RE: [PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
Oops, totally forgot this got approved ☺ Thanks for the reminder! From: Eric Christopher [mailto:echri...@gmail.com] Sent: Friday, September 1, 2017 12:40 PM To: reviews+d36707+public+aa8b48c258736...@reviews.llvm.org; Keane, Erich <erich.ke...@intel.com>; llvm-...@redking.me.uk; craig.top...@gmail.com Cc: cfe-commits@lists.llvm.org Subject: Re: [PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation Don't wait on me here. On Thu, Aug 31, 2017, 10:53 PM Craig Topper via Phabricator <revi...@reviews.llvm.org<mailto:revi...@reviews.llvm.org>> wrote: craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D36707 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
Don't wait on me here. On Thu, Aug 31, 2017, 10:53 PM Craig Topper via Phabricator < revi...@reviews.llvm.org> wrote: > craig.topper accepted this revision. > craig.topper added a comment. > This revision is now accepted and ready to land. > > LGTM > > > https://reviews.llvm.org/D36707 > > > > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D36707 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane updated this revision to Diff 113424. erichkeane marked 4 inline comments as done. https://reviews.llvm.org/D36707 Files: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3857,6 +3857,10 @@ void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); llvm::Value *GetValueForARMHint(unsigned BuiltinID); + llvm::Value *EmitX86CpuIs(const CallExpr *E); + llvm::Value *EmitX86CpuIs(StringRef CPUStr); + llvm::Value *EmitX86CpuSupports(const CallExpr *E); + llvm::Value *EmitX86CpuSupports(ArrayRef FeatureStrs); }; /// Helper class with most of the code for saving a value for a Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7288,9 +7288,13 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -static Value *EmitX86CpuIs(CodeGenFunction , const CallExpr *E) { +Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); + return EmitX86CpuIs(CPUStr); +} + +Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { // This enum contains the vendor, type, and subtype enums from the // runtime library concatenated together. The _START labels mark @@ -7332,7 +7336,9 @@ StringSwitch(CPUStr) .Case("amd", AMD) .Case("amdfam10h", AMDFAM10H) + .Case("amdfam10", AMDFAM10H) .Case("amdfam15h", AMDFAM15H) + .Case("amdfam15", AMDFAM15H) .Case("atom", INTEL_BONNELL) .Case("barcelona", AMDFAM10H_BARCELONA) .Case("bdver1", AMDFAM15H_BDVER1) @@ -7360,7 +7366,7 @@ .Case("westmere", INTEL_COREI7_WESTMERE) .Case("znver1", AMDFAM17H_ZNVER1); - llvm::Type *Int32Ty = CGF.Builder.getInt32Ty(); + llvm::Type *Int32Ty = Builder.getInt32Ty(); // Matching the struct layout from the compiler-rt/libgcc structure that is // filled in: @@ -7372,7 +7378,7 @@ llvm::ArrayType::get(Int32Ty, 1)); // Grab the global __cpu_model. - llvm::Constant *CpuModel = CGF.CGM.CreateRuntimeVariable(STy, "__cpu_model"); + llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); // Calculate the index needed to access the correct field based on the // range. Also adjust the expected value. @@ -7394,16 +7400,133 @@ ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, Index) }; - llvm::Value *CpuValue = CGF.Builder.CreateGEP(STy, CpuModel, Idxs); - CpuValue = CGF.Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); + llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); + CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); // Check the value of the field against the requested value. - return CGF.Builder.CreateICmpEQ(CpuValue, + return Builder.CreateICmpEQ(CpuValue, llvm::ConstantInt::get(Int32Ty, Value)); } +Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast(FeatureExpr)->getString(); + return EmitX86CpuSupports(FeatureStr); +} + +Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef FeatureStrs) { + // TODO: When/if this becomes more than x86 specific then use a TargetInfo + // based mapping. + // Processor features and mapping to processor feature value. + enum X86Features { +CMOV = 0, +MMX, +POPCNT, +SSE, +SSE2, +SSE3, +SSSE3, +SSE4_1, +SSE4_2, +AVX, +AVX2, +SSE4_A, +FMA4, +XOP, +FMA, +AVX512F, +BMI, +BMI2, +AES, +PCLMUL, +AVX512VL, +AVX512BW, +AVX512DQ, +AVX512CD, +AVX512ER, +AVX512PF, +AVX512VBMI, +AVX512IFMA, +AVX5124VNNIW, +AVX5124FMAPS, +AVX512VPOPCNTDQ, +MAX + }; + + uint32_t FeaturesMask = 0; + + for (const StringRef : FeatureStrs) { +X86Features Feature = +StringSwitch(FeatureStr) +.Case("cmov", X86Features::CMOV) +.Case("mmx", X86Features::MMX) +.Case("popcnt", X86Features::POPCNT) +.Case("sse", X86Features::SSE) +.Case("sse2", X86Features::SSE2) +.Case("sse3", X86Features::SSE3) +.Case("ssse3", X86Features::SSSE3) +.Case("sse4.1", X86Features::SSE4_1) +.Case("sse4.2", X86Features::SSE4_2) +.Case("avx", X86Features::AVX) +.Case("avx2", X86Features::AVX2) +.Case("sse4a", X86Features::SSE4_A) +.Case("fma4", X86Features::FMA4) +.Case("xop", X86Features::XOP) +.Case("fma", X86Features::FMA) +.Case("avx512f",
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
craig.topper added inline comments. Comment at: lib/CodeGen/CGBuiltin.cpp:7414 + StringRef FeatureStr = cast(FeatureExpr)->getString(); + return EmitX86CpuSupports({FeatureStr}); +} You shouldn't need curly braces here. ArrayRef has a conversion constructor that should take care of this. Comment at: lib/CodeGen/CGBuiltin.cpp:7456 + + unsigned FeaturesMask = 0; + Declare as uint32_t? Comment at: lib/CodeGen/CGBuiltin.cpp:7494 +assert(Feature != X86Features::MAX && "Invalid feature!"); +FeaturesMask |= (1ULL << Feature); + } No need for 64-bit OR here. FeaturesMask is only 32-bits. Comment at: lib/CodeGen/CGBuiltin.cpp:7525 const CallExpr *E) { + if (BuiltinID == X86::BI__builtin_cpu_is) +return EmitX86CpuIs(E); I think you have the builtin handline at the top and in the switch. Bad rebase? https://reviews.llvm.org/D36707 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane updated this revision to Diff 113297. erichkeane added a comment. Woops, messed up my rebase! https://reviews.llvm.org/D36707 Files: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3857,6 +3857,10 @@ void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); llvm::Value *GetValueForARMHint(unsigned BuiltinID); + llvm::Value *EmitX86CpuIs(const CallExpr *E); + llvm::Value *EmitX86CpuIs(StringRef CPUStr); + llvm::Value *EmitX86CpuSupports(const CallExpr *E); + llvm::Value *EmitX86CpuSupports(ArrayRef FeatureStrs); }; /// Helper class with most of the code for saving a value for a Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7288,9 +7288,13 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -static Value *EmitX86CpuIs(CodeGenFunction , const CallExpr *E) { +Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); + return EmitX86CpuIs(CPUStr); +} + +Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { // This enum contains the vendor, type, and subtype enums from the // runtime library concatenated together. The _START labels mark @@ -7332,7 +7336,9 @@ StringSwitch(CPUStr) .Case("amd", AMD) .Case("amdfam10h", AMDFAM10H) + .Case("amdfam10", AMDFAM10H) .Case("amdfam15h", AMDFAM15H) + .Case("amdfam15", AMDFAM15H) .Case("atom", INTEL_BONNELL) .Case("barcelona", AMDFAM10H_BARCELONA) .Case("bdver1", AMDFAM15H_BDVER1) @@ -7360,7 +7366,7 @@ .Case("westmere", INTEL_COREI7_WESTMERE) .Case("znver1", AMDFAM17H_ZNVER1); - llvm::Type *Int32Ty = CGF.Builder.getInt32Ty(); + llvm::Type *Int32Ty = Builder.getInt32Ty(); // Matching the struct layout from the compiler-rt/libgcc structure that is // filled in: @@ -7372,7 +7378,7 @@ llvm::ArrayType::get(Int32Ty, 1)); // Grab the global __cpu_model. - llvm::Constant *CpuModel = CGF.CGM.CreateRuntimeVariable(STy, "__cpu_model"); + llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); // Calculate the index needed to access the correct field based on the // range. Also adjust the expected value. @@ -7394,16 +7400,133 @@ ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, Index) }; - llvm::Value *CpuValue = CGF.Builder.CreateGEP(STy, CpuModel, Idxs); - CpuValue = CGF.Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); + llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); + CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); // Check the value of the field against the requested value. - return CGF.Builder.CreateICmpEQ(CpuValue, + return Builder.CreateICmpEQ(CpuValue, llvm::ConstantInt::get(Int32Ty, Value)); } +Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast(FeatureExpr)->getString(); + return EmitX86CpuSupports({FeatureStr}); +} + +Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef FeatureStrs) { + // TODO: When/if this becomes more than x86 specific then use a TargetInfo + // based mapping. + // Processor features and mapping to processor feature value. + enum X86Features { +CMOV = 0, +MMX, +POPCNT, +SSE, +SSE2, +SSE3, +SSSE3, +SSE4_1, +SSE4_2, +AVX, +AVX2, +SSE4_A, +FMA4, +XOP, +FMA, +AVX512F, +BMI, +BMI2, +AES, +PCLMUL, +AVX512VL, +AVX512BW, +AVX512DQ, +AVX512CD, +AVX512ER, +AVX512PF, +AVX512VBMI, +AVX512IFMA, +AVX5124VNNIW, +AVX5124FMAPS, +AVX512VPOPCNTDQ, +MAX + }; + + unsigned FeaturesMask = 0; + + for (const StringRef : FeatureStrs) { +X86Features Feature = +StringSwitch(FeatureStr) +.Case("cmov", X86Features::CMOV) +.Case("mmx", X86Features::MMX) +.Case("popcnt", X86Features::POPCNT) +.Case("sse", X86Features::SSE) +.Case("sse2", X86Features::SSE2) +.Case("sse3", X86Features::SSE3) +.Case("ssse3", X86Features::SSSE3) +.Case("sse4.1", X86Features::SSE4_1) +.Case("sse4.2", X86Features::SSE4_2) +.Case("avx", X86Features::AVX) +.Case("avx2", X86Features::AVX2) +.Case("sse4a", X86Features::SSE4_A) +.Case("fma4", X86Features::FMA4) +.Case("xop", X86Features::XOP) +.Case("fma", X86Features::FMA) +
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane updated this revision to Diff 113291. erichkeane added a comment. This revision is now accepted and ready to land. I figured out that combining the CpuSupports items via an array is a REALLY useful function for dispatch. I've got most of gcc's target implemented, so I believe that this is sufficient for that purpose. Thanks in advance for the reviews :) https://reviews.llvm.org/D36707 Files: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3857,6 +3857,10 @@ void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); llvm::Value *GetValueForARMHint(unsigned BuiltinID); + llvm::Value *EmitX86CpuIs(const CallExpr *E); + llvm::Value *EmitX86CpuIs(StringRef CPUStr); + llvm::Value *EmitX86CpuSupports(const CallExpr *E); + llvm::Value *EmitX86CpuSupports(ArrayRef FeatureStrs); }; /// Helper class with most of the code for saving a value for a Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7288,9 +7288,13 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -static Value *EmitX86CpuIs(CodeGenFunction , const CallExpr *E) { +Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); + return EmitX86CpuIs(CPUStr); +} + +Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { // This enum contains the vendor, type, and subtype enums from the // runtime library concatenated together. The _START labels mark @@ -7332,7 +7336,9 @@ StringSwitch(CPUStr) .Case("amd", AMD) .Case("amdfam10h", AMDFAM10H) + .Case("amdfam10", AMDFAM10H) .Case("amdfam15h", AMDFAM15H) + .Case("amdfam15", AMDFAM15H) .Case("atom", INTEL_BONNELL) .Case("barcelona", AMDFAM10H_BARCELONA) .Case("bdver1", AMDFAM15H_BDVER1) @@ -7360,7 +7366,7 @@ .Case("westmere", INTEL_COREI7_WESTMERE) .Case("znver1", AMDFAM17H_ZNVER1); - llvm::Type *Int32Ty = CGF.Builder.getInt32Ty(); + llvm::Type *Int32Ty = Builder.getInt32Ty(); // Matching the struct layout from the compiler-rt/libgcc structure that is // filled in: @@ -7372,7 +7378,7 @@ llvm::ArrayType::get(Int32Ty, 1)); // Grab the global __cpu_model. - llvm::Constant *CpuModel = CGF.CGM.CreateRuntimeVariable(STy, "__cpu_model"); + llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); // Calculate the index needed to access the correct field based on the // range. Also adjust the expected value. @@ -7394,16 +7400,133 @@ ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, Index) }; - llvm::Value *CpuValue = CGF.Builder.CreateGEP(STy, CpuModel, Idxs); - CpuValue = CGF.Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); + llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); + CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); // Check the value of the field against the requested value. - return CGF.Builder.CreateICmpEQ(CpuValue, + return Builder.CreateICmpEQ(CpuValue, llvm::ConstantInt::get(Int32Ty, Value)); } +Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast(FeatureExpr)->getString(); + return EmitX86CpuSupports({FeatureStr}); +} + +Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef FeatureStrs) { + // TODO: When/if this becomes more than x86 specific then use a TargetInfo + // based mapping. + // Processor features and mapping to processor feature value. + enum X86Features { +CMOV = 0, +MMX, +POPCNT, +SSE, +SSE2, +SSE3, +SSSE3, +SSE4_1, +SSE4_2, +AVX, +AVX2, +SSE4_A, +FMA4, +XOP, +FMA, +AVX512F, +BMI, +BMI2, +AES, +PCLMUL, +AVX512VL, +AVX512BW, +AVX512DQ, +AVX512CD, +AVX512ER, +AVX512PF, +AVX512VBMI, +AVX512IFMA, +AVX5124VNNIW, +AVX5124FMAPS, +AVX512VPOPCNTDQ, +MAX + }; + + unsigned FeaturesMask = 0; + + for (const StringRef : FeatureStrs) { +X86Features Feature = +StringSwitch(FeatureStr) +.Case("cmov", X86Features::CMOV) +.Case("mmx", X86Features::MMX) +.Case("popcnt", X86Features::POPCNT) +.Case("sse", X86Features::SSE) +.Case("sse2", X86Features::SSE2) +.Case("sse3", X86Features::SSE3) +.Case("ssse3", X86Features::SSSE3) +.Case("sse4.1", X86Features::SSE4_1) +.Case("sse4.2", X86Features::SSE4_2) +
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane planned changes to this revision. erichkeane added a comment. I actually updated it a bit since then, so I'll hold off on committing until my replacement version is perfect, I'd prefer to stop churning. Thanks for the review though Craig! https://reviews.llvm.org/D36707 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D36707 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane added a comment. Of course, overnight I realized I am probably better off having the 'CpuSupports' validate MULTIPLE features at a time! I'll update this patch with an improvement when I get one that I think is really useful. Sorry for the thrash. https://reviews.llvm.org/D36707 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane updated this revision to Diff 111061. erichkeane added a comment. Thinking about it further, the emit functions should be private in this case. https://reviews.llvm.org/D36707 Files: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3852,6 +3852,10 @@ void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); llvm::Value *GetValueForARMHint(unsigned BuiltinID); + llvm::Value *EmitX86CpuIs(const CallExpr *E); + llvm::Value *EmitX86CpuIs(StringRef CPUStr); + llvm::Value *EmitX86CpuSupports(const CallExpr *E); + llvm::Value *EmitX86CpuSupports(StringRef FeatureStr); }; /// Helper class with most of the code for saving a value for a Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7287,9 +7287,13 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -static Value *EmitX86CpuIs(CodeGenFunction , const CallExpr *E) { +Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); + return EmitX86CpuIs(CPUStr); +} + +Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { // This enum contains the vendor, type, and subtype enums from the // runtime library concatenated together. The _START labels mark @@ -7359,7 +7363,7 @@ .Case("westmere", INTEL_COREI7_WESTMERE) .Case("znver1", AMDFAM17H_ZNVER1); - llvm::Type *Int32Ty = CGF.Builder.getInt32Ty(); + llvm::Type *Int32Ty = Builder.getInt32Ty(); // Matching the struct layout from the compiler-rt/libgcc structure that is // filled in: @@ -7371,7 +7375,7 @@ llvm::ArrayType::get(Int32Ty, 1)); // Grab the global __cpu_model. - llvm::Constant *CpuModel = CGF.CGM.CreateRuntimeVariable(STy, "__cpu_model"); + llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); // Calculate the index needed to access the correct field based on the // range. Also adjust the expected value. @@ -7393,18 +7397,127 @@ ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, Index) }; - llvm::Value *CpuValue = CGF.Builder.CreateGEP(STy, CpuModel, Idxs); - CpuValue = CGF.Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); + llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); + CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); // Check the value of the field against the requested value. - return CGF.Builder.CreateICmpEQ(CpuValue, + return Builder.CreateICmpEQ(CpuValue, llvm::ConstantInt::get(Int32Ty, Value)); } +Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast(FeatureExpr)->getString(); + return EmitX86CpuSupports(FeatureStr); +} + +Value *CodeGenFunction::EmitX86CpuSupports(StringRef FeatureStr) { + // TODO: When/if this becomes more than x86 specific then use a TargetInfo + // based mapping. + // Processor features and mapping to processor feature value. + enum X86Features { +CMOV = 0, +MMX, +POPCNT, +SSE, +SSE2, +SSE3, +SSSE3, +SSE4_1, +SSE4_2, +AVX, +AVX2, +SSE4_A, +FMA4, +XOP, +FMA, +AVX512F, +BMI, +BMI2, +AES, +PCLMUL, +AVX512VL, +AVX512BW, +AVX512DQ, +AVX512CD, +AVX512ER, +AVX512PF, +AVX512VBMI, +AVX512IFMA, +AVX5124VNNIW, +AVX5124FMAPS, +AVX512VPOPCNTDQ, +MAX + }; + + X86Features Feature = + StringSwitch(FeatureStr) + .Case("cmov", X86Features::CMOV) + .Case("mmx", X86Features::MMX) + .Case("popcnt", X86Features::POPCNT) + .Case("sse", X86Features::SSE) + .Case("sse2", X86Features::SSE2) + .Case("sse3", X86Features::SSE3) + .Case("ssse3", X86Features::SSSE3) + .Case("sse4.1", X86Features::SSE4_1) + .Case("sse4.2", X86Features::SSE4_2) + .Case("avx", X86Features::AVX) + .Case("avx2", X86Features::AVX2) + .Case("sse4a", X86Features::SSE4_A) + .Case("fma4", X86Features::FMA4) + .Case("xop", X86Features::XOP) + .Case("fma", X86Features::FMA) + .Case("avx512f", X86Features::AVX512F) + .Case("bmi", X86Features::BMI) + .Case("bmi2", X86Features::BMI2) + .Case("aes", X86Features::AES) + .Case("pclmul", X86Features::PCLMUL) + .Case("avx512vl", X86Features::AVX512VL) + .Case("avx512bw", X86Features::AVX512BW) + .Case("avx512dq", X86Features::AVX512DQ) + .Case("avx512cd",
[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation
erichkeane created this revision. A small set of refactors that'll make it easier for me to implement 'target' support. First, extract the CPUSupports functionality into its own function. THis has the advantage of not wasting time in this builtin to deal with arguments. Second, pulls both CPUSupports and CPUIs implementation into a member-function, so that it can be called from the resolver generation that I'm working on. Third, creates an overload that takes simply the feature/cpu name (rather than extracting it from a callexpr), since that info isn't available later. Note that despite how the 'diff' looks, the EmitX86CPUSupports function simply takes the implementation out of the 'switch'. https://reviews.llvm.org/D36707 Files: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3841,6 +3841,12 @@ void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); + + llvm::Value *EmitX86CpuIs(const CallExpr *E); + llvm::Value *EmitX86CpuIs(StringRef CPUStr); + llvm::Value *EmitX86CpuSupports(const CallExpr *E); + llvm::Value *EmitX86CpuSupports(StringRef FeatureStr); + private: QualType getVarArgType(const Expr *Arg); Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -7287,9 +7287,13 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } -static Value *EmitX86CpuIs(CodeGenFunction , const CallExpr *E) { +Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); + return EmitX86CpuIs(CPUStr); +} + +Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { // This enum contains the vendor, type, and subtype enums from the // runtime library concatenated together. The _START labels mark @@ -7359,7 +7363,7 @@ .Case("westmere", INTEL_COREI7_WESTMERE) .Case("znver1", AMDFAM17H_ZNVER1); - llvm::Type *Int32Ty = CGF.Builder.getInt32Ty(); + llvm::Type *Int32Ty = Builder.getInt32Ty(); // Matching the struct layout from the compiler-rt/libgcc structure that is // filled in: @@ -7371,7 +7375,7 @@ llvm::ArrayType::get(Int32Ty, 1)); // Grab the global __cpu_model. - llvm::Constant *CpuModel = CGF.CGM.CreateRuntimeVariable(STy, "__cpu_model"); + llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); // Calculate the index needed to access the correct field based on the // range. Also adjust the expected value. @@ -7393,18 +7397,127 @@ ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, Index) }; - llvm::Value *CpuValue = CGF.Builder.CreateGEP(STy, CpuModel, Idxs); - CpuValue = CGF.Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); + llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); + CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); // Check the value of the field against the requested value. - return CGF.Builder.CreateICmpEQ(CpuValue, + return Builder.CreateICmpEQ(CpuValue, llvm::ConstantInt::get(Int32Ty, Value)); } +Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); + StringRef FeatureStr = cast(FeatureExpr)->getString(); + return EmitX86CpuSupports(FeatureStr); +} + +Value *CodeGenFunction::EmitX86CpuSupports(StringRef FeatureStr) { + // TODO: When/if this becomes more than x86 specific then use a TargetInfo + // based mapping. + // Processor features and mapping to processor feature value. + enum X86Features { +CMOV = 0, +MMX, +POPCNT, +SSE, +SSE2, +SSE3, +SSSE3, +SSE4_1, +SSE4_2, +AVX, +AVX2, +SSE4_A, +FMA4, +XOP, +FMA, +AVX512F, +BMI, +BMI2, +AES, +PCLMUL, +AVX512VL, +AVX512BW, +AVX512DQ, +AVX512CD, +AVX512ER, +AVX512PF, +AVX512VBMI, +AVX512IFMA, +AVX5124VNNIW, +AVX5124FMAPS, +AVX512VPOPCNTDQ, +MAX + }; + + X86Features Feature = + StringSwitch(FeatureStr) + .Case("cmov", X86Features::CMOV) + .Case("mmx", X86Features::MMX) + .Case("popcnt", X86Features::POPCNT) + .Case("sse", X86Features::SSE) + .Case("sse2", X86Features::SSE2) + .Case("sse3", X86Features::SSE3) + .Case("ssse3", X86Features::SSSE3) + .Case("sse4.1", X86Features::SSE4_1) + .Case("sse4.2", X86Features::SSE4_2) + .Case("avx", X86Features::AVX) + .Case("avx2", X86Features::AVX2) + .Case("sse4a", X86Features::SSE4_A) + .Case("fma4", X86Features::FMA4) +