From c4b9c174a3075f48de6d12d04c8ba9c0e308f2d1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 2 Oct 2018 14:08:09 -0700 Subject: [PATCH] gallium/swr: Change global static non-PODs to local statics The std::map template as well as std::function and std::string types are not literals, meaning that the variables intrinsicMap and intrinsicMap2 are initialised at load-time. Since this file is compiled with -mavx, the compiler is free to then use AVX instructions in the initialisation, without any CPUID check. By making them local static, they get initialised on first use, which should happen after CPUID checks. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108135 --- .../jitter/functionpasses/lower_x86.cpp | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/swr/rasterizer/jitter/functionpasses/lower_x86.cpp b/src/gallium/drivers/swr/rasterizer/jitter/functionpasses/lower_x86.cpp index 7605823c04..49e676570d 100644 --- a/src/gallium/drivers/swr/rasterizer/jitter/functionpasses/lower_x86.cpp +++ b/src/gallium/drivers/swr/rasterizer/jitter/functionpasses/lower_x86.cpp @@ -70,7 +70,9 @@ namespace SwrJit // Map of intrinsics that haven't been moved to the new mechanism yet. If used, these get the // previous behavior of mapping directly to avx/avx2 intrinsics. - static std::map intrinsicMap = { + static std::map &intrinsicMap() + { + static std::map map = { {"meta.intrinsic.BEXTR_32", Intrinsic::x86_bmi_bextr_32}, {"meta.intrinsic.VPSHUFB", Intrinsic::x86_avx2_pshuf_b}, {"meta.intrinsic.VCVTPS2PH", Intrinsic::x86_vcvtps2ph_256}, @@ -80,7 +82,9 @@ namespace SwrJit {"meta.intrinsic.VPHADDD", Intrinsic::x86_avx2_phadd_d}, {"meta.intrinsic.PDEP32", Intrinsic::x86_bmi_pdep_32}, {"meta.intrinsic.RDTSC", Intrinsic::x86_rdtsc}, - }; + }; + return map; + } // Forward decls Instruction* NO_EMU(LowerX86* pThis, TargetArch arch, TargetWidth width, CallInst* pCallInst); @@ -103,7 +107,10 @@ namespace SwrJit static Intrinsic::ID DOUBLE = (Intrinsic::ID)-1; - static std::map intrinsicMap2[] = { + using IntrinsicMap2 = std::map[3]; + static IntrinsicMap2 &intrinsicMap2() + { + static IntrinsicMap2 map = { // 256 wide 512 wide { // AVX @@ -185,6 +192,8 @@ namespace SwrJit {"meta.intrinsic.VHSUBPS", {{Intrinsic::not_intrinsic, Intrinsic::not_intrinsic}, VHSUB_EMU}}, }}; + return map; + } struct LowerX86 : public FunctionPass { @@ -305,7 +314,7 @@ namespace SwrJit Instruction* ProcessIntrinsicAdvanced(CallInst* pCallInst) { Function* pFunc = pCallInst->getCalledFunction(); - auto& intrinsic = intrinsicMap2[mTarget][pFunc->getName()]; + auto& intrinsic = intrinsicMap2()[mTarget][pFunc->getName()]; TargetWidth vecWidth; Type* pElemTy; GetRequestedWidthAndType(pCallInst, pFunc->getName(), &vecWidth, &pElemTy); @@ -366,16 +375,16 @@ namespace SwrJit Function* pFunc = pCallInst->getCalledFunction(); // Forward to the advanced support if found - if (intrinsicMap2[mTarget].find(pFunc->getName()) != intrinsicMap2[mTarget].end()) + if (intrinsicMap2()[mTarget].find(pFunc->getName()) != intrinsicMap2()[mTarget].end()) { return ProcessIntrinsicAdvanced(pCallInst); } - SWR_ASSERT(intrinsicMap.find(pFunc->getName()) != intrinsicMap.end(), + SWR_ASSERT(intrinsicMap().find(pFunc->getName()) != intrinsicMap().end(), "Unimplemented intrinsic %s.", pFunc->getName()); - Intrinsic::ID x86Intrinsic = intrinsicMap[pFunc->getName()]; + Intrinsic::ID x86Intrinsic = intrinsicMap()[pFunc->getName()]; Function* pX86IntrinFunc = Intrinsic::getDeclaration(B->JM()->mpCurrentModule, x86Intrinsic); -- 2.19.0