diff --git a/include/dxc/HLSL/DxilUtil.h b/include/dxc/HLSL/DxilUtil.h index c3794a898..9ae3319a5 100644 --- a/include/dxc/HLSL/DxilUtil.h +++ b/include/dxc/HLSL/DxilUtil.h @@ -22,6 +22,7 @@ class LLVMContext; class DiagnosticInfo; class Value; class Instruction; +class BasicBlock; class StringRef; } @@ -37,6 +38,15 @@ namespace dxilutil { llvm::Type *GetArrayEltTy(llvm::Type *Ty); bool HasDynamicIndexing(llvm::Value *V); + // Find alloca insertion point, given instruction + llvm::Instruction *FindAllocaInsertionPt(llvm::Instruction* I); + llvm::Instruction *FindAllocaInsertionPt(llvm::Function* F); + llvm::Instruction *SkipAllocas(llvm::Instruction *I); + // Get first non-alloca insertion point, to avoid inserting non-allocas before alloca + llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Instruction* I); + llvm::Instruction *FirstNonAllocaInsertionPt(llvm::BasicBlock* BB); + llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Function* F); + bool IsStaticGlobal(llvm::GlobalVariable *GV); bool IsSharedMemoryGlobal(llvm::GlobalVariable *GV); bool RemoveUnusedFunctions(llvm::Module &M, llvm::Function *EntryFunc, diff --git a/lib/HLSL/DxilAddPixelHitInstrumentation.cpp b/lib/HLSL/DxilAddPixelHitInstrumentation.cpp index 6bedca558..7a91dcbd1 100644 --- a/lib/HLSL/DxilAddPixelHitInstrumentation.cpp +++ b/lib/HLSL/DxilAddPixelHitInstrumentation.cpp @@ -15,6 +15,7 @@ #include "dxc/HLSL/DxilInstructions.h" #include "dxc/HLSL/DxilModule.h" #include "dxc/HLSL/DxilPIXPasses.h" +#include "dxc/HLSL/DxilUtil.h" #include "llvm/IR/PassManager.h" #include "llvm/Transforms/Utils/Local.h" @@ -93,7 +94,7 @@ bool DxilAddPixelHitInstrumentation::runOnModule(Module &M) CallInst *HandleForUAV; { - IRBuilder<> Builder(DM.GetEntryFunction()->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction())); unsigned int UAVResourceHandle = static_cast(DM.GetUAVs().size()); diff --git a/lib/HLSL/DxilCondenseResources.cpp b/lib/HLSL/DxilCondenseResources.cpp index cb39744ba..40282bff6 100644 --- a/lib/HLSL/DxilCondenseResources.cpp +++ b/lib/HLSL/DxilCondenseResources.cpp @@ -804,7 +804,7 @@ void DxilLowerCreateHandleForLib::TranslateDxilResourceUses( for (iplist::iterator F : pM->getFunctionList()) { if (!F->isDeclaration()) { if (!isResArray) { - IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F)); if (m_HasDbgInfo) { // TODO: set debug info. // Builder.SetCurrentDebugLocation(DL); diff --git a/lib/HLSL/DxilDebugInstrumentation.cpp b/lib/HLSL/DxilDebugInstrumentation.cpp index 8d818ee76..d3a60022c 100644 --- a/lib/HLSL/DxilDebugInstrumentation.cpp +++ b/lib/HLSL/DxilDebugInstrumentation.cpp @@ -13,6 +13,7 @@ #include "dxc/HLSL/DxilModule.h" #include "dxc/HLSL/DxilOperations.h" #include "dxc/HLSL/DxilPIXPasses.h" +#include "dxc/HLSL/DxilUtil.h" #include "llvm/IR/Module.h" #include "llvm/IR/Constants.h" @@ -728,7 +729,7 @@ bool DxilDebugInstrumentation::runOnModule(Module &M) { // value at (UAVSize) - (Small Amount) * 2 (which is actually a conservative definition of overflow). // - Instruction* firstInsertionPt = DM.GetEntryFunction()->getEntryBlock().getFirstInsertionPt(); + Instruction* firstInsertionPt = dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction()); IRBuilder<> Builder(firstInsertionPt); BuilderContext BC{ M, DM, Ctx, HlslOP, Builder }; diff --git a/lib/HLSL/DxilEliminateOutputDynamicIndexing.cpp b/lib/HLSL/DxilEliminateOutputDynamicIndexing.cpp index eeb3aacdb..7a1cd5c4b 100644 --- a/lib/HLSL/DxilEliminateOutputDynamicIndexing.cpp +++ b/lib/HLSL/DxilEliminateOutputDynamicIndexing.cpp @@ -13,6 +13,7 @@ #include "dxc/HLSL/DxilOperations.h" #include "dxc/HLSL/DxilSignatureElement.h" #include "dxc/HLSL/DxilModule.h" +#include "dxc/HLSL/DxilUtil.h" #include "dxc/Support/Global.h" #include "dxc/HLSL/DxilInstructions.h" @@ -123,10 +124,10 @@ bool DxilEliminateOutputDynamicIndexing::EliminateDynamicOutput( if (dynamicSigSet.empty()) return false; - IRBuilder<> Builder(Entry->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Entry)); - Value *opcodeV = Builder.getInt32(static_cast(opcode)); - Value *zero = Builder.getInt32(0); + Value *opcodeV = AllocaBuilder.getInt32(static_cast(opcode)); + Value *zero = AllocaBuilder.getInt32(0); for (auto sig : dynamicSigSet) { Value *sigID = sig.first; @@ -139,7 +140,7 @@ bool DxilEliminateOutputDynamicIndexing::EliminateDynamicOutput( std::vector tmpSigElts(col); for (unsigned c = 0; c < col; c++) { - Value *newCol = Builder.CreateAlloca(AT); + Value *newCol = AllocaBuilder.CreateAlloca(AT); tmpSigElts[c] = newCol; } diff --git a/lib/HLSL/DxilGenerationPass.cpp b/lib/HLSL/DxilGenerationPass.cpp index bdfeb2402..cbc1530b3 100644 --- a/lib/HLSL/DxilGenerationPass.cpp +++ b/lib/HLSL/DxilGenerationPass.cpp @@ -100,7 +100,7 @@ void SimplifyGlobalSymbol(GlobalVariable *GV) { for (auto it : handleMapOnFunction) { Function *F = it.first; Instruction *I = it.second; - IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F)); Value *headLI = Builder.CreateLoad(GV); I->replaceAllUsesWith(headLI); } @@ -613,11 +613,10 @@ void DxilGenerationPass::RemoveLocalDxilResourceAllocas(Function *F) { Insts.clear(); } } - void DxilGenerationPass::TranslateParamDxilResourceHandles(Function *F, std::unordered_map &handleMap) { Type *handleTy = m_pHLModule->GetOP()->GetHandleType(); - IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F)); for (Argument &arg : F->args()) { Type *Ty = arg.getType(); @@ -770,9 +769,7 @@ void DxilGenerationPass::GenerateDxilCBufferHandles( // Must HLCreateHandle. CallInst *CI = cast(*(U++)); // Put createHandle to entry block. - auto InsertPt = - CI->getParent()->getParent()->getEntryBlock().getFirstInsertionPt(); - IRBuilder<> Builder(InsertPt); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(CI)); Value *V = Builder.CreateLoad(GV); CallInst *handle = Builder.CreateCall(createHandle, {opArg, V}, handleName); if (m_HasDbgInfo) { @@ -796,11 +793,7 @@ void DxilGenerationPass::GenerateDxilCBufferHandles( Value *CBIndex = CI->getArgOperand(HLOperandIndex::kCreateHandleIndexOpIdx); if (isa(CBIndex)) { // Put createHandle to entry block for const index. - auto InsertPt = CI->getParent() - ->getParent() - ->getEntryBlock() - .getFirstInsertionPt(); - Builder.SetInsertPoint(InsertPt); + Builder.SetInsertPoint(dxilutil::FirstNonAllocaInsertionPt(CI)); } // Add GEP for cbv array use. Value *GEP = Builder.CreateGEP(GV, {zeroIdx, CBIndex}); diff --git a/lib/HLSL/DxilLinker.cpp b/lib/HLSL/DxilLinker.cpp index 6c4f1459f..a9a35d3de 100644 --- a/lib/HLSL/DxilLinker.cpp +++ b/lib/HLSL/DxilLinker.cpp @@ -754,8 +754,7 @@ DxilLinkJob::Link(std::pair &entryLinkPair, CloneFunctions(vmap); // Call global constrctor. - IRBuilder<> Builder( - DM.GetEntryFunction()->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction())); for (auto &it : m_functionDefs) { DxilFunctionLinkInfo *linkInfo = it.first; DxilLib *pLib = it.second; diff --git a/lib/HLSL/DxilPreserveAllOutputs.cpp b/lib/HLSL/DxilPreserveAllOutputs.cpp index 0599a7930..29512e7ad 100644 --- a/lib/HLSL/DxilPreserveAllOutputs.cpp +++ b/lib/HLSL/DxilPreserveAllOutputs.cpp @@ -86,15 +86,15 @@ public: { } - void CreateAlloca(IRBuilder<> &builder) { - LLVMContext &context = builder.getContext(); + void CreateAlloca(IRBuilder<> &allocaBuilder) { + LLVMContext &context = allocaBuilder.getContext(); Type *elementType = m_OutputElement.GetCompType().GetLLVMType(context); Type *allocaType = nullptr; if (IsSingleElement()) allocaType = elementType; else allocaType = ArrayType::get(elementType, NumElements()); - m_Alloca = builder.CreateAlloca(allocaType, nullptr, m_OutputElement.GetName()); + m_Alloca = allocaBuilder.CreateAlloca(allocaType, nullptr, m_OutputElement.GetName()); } void StoreTemp(IRBuilder<> &builder, Value *row, Value *col, Value *value) const { @@ -249,11 +249,11 @@ DxilPreserveAllOutputs::OutputMap DxilPreserveAllOutputs::generateOutputMap(cons return map; } -void DxilPreserveAllOutputs::createTempAllocas(OutputMap &outputMap, IRBuilder<> &builder) +void DxilPreserveAllOutputs::createTempAllocas(OutputMap &outputMap, IRBuilder<> &allocaBuilder) { for (auto &iter: outputMap) { OutputElement &output = iter.second; - output.CreateAlloca(builder); + output.CreateAlloca(allocaBuilder); } } diff --git a/lib/HLSL/DxilUtil.cpp b/lib/HLSL/DxilUtil.cpp index dacdbc40c..b4796e3e4 100644 --- a/lib/HLSL/DxilUtil.cpp +++ b/lib/HLSL/DxilUtil.cpp @@ -265,5 +265,33 @@ Value *SelectOnOperation(llvm::Instruction *Inst, unsigned operandIdx) { } return nullptr; } + +llvm::Instruction *SkipAllocas(llvm::Instruction *I) { + // Step past any allocas: + while (I && isa(I)) + I = I->getNextNode(); + return I; +} +llvm::Instruction *FindAllocaInsertionPt(llvm::Instruction* I) { + Function *F = I->getParent()->getParent(); + if (F) + return F->getEntryBlock().getFirstInsertionPt(); + else // BB with no parent function + return I->getParent()->getFirstInsertionPt(); +} +llvm::Instruction *FindAllocaInsertionPt(llvm::Function* F) { + return F->getEntryBlock().getFirstInsertionPt(); +} +llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Instruction* I) { + return SkipAllocas(FindAllocaInsertionPt(I)); +} +llvm::Instruction *FirstNonAllocaInsertionPt(llvm::BasicBlock* BB) { + return SkipAllocas( + BB->getFirstInsertionPt()); +} +llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Function* F) { + return SkipAllocas( + F->getEntryBlock().getFirstInsertionPt()); +} } } diff --git a/lib/HLSL/HLMatrixLowerPass.cpp b/lib/HLSL/HLMatrixLowerPass.cpp index c5f73c4d2..1ef49671e 100644 --- a/lib/HLSL/HLMatrixLowerPass.cpp +++ b/lib/HLSL/HLMatrixLowerPass.cpp @@ -789,18 +789,16 @@ Instruction *HLMatrixLowerPass::TrivialMatBinOpToVec(CallInst *CI) { // Create BitCast if ptr, otherwise, create alloca of new type, write to bitcast of alloca, and return load from alloca // If bOrigAllocaTy is true: create alloca of old type instead, write to alloca, and return load from bitcast of alloca static Instruction *BitCastValueOrPtr(Value* V, Instruction *Insert, Type *Ty, bool bOrigAllocaTy = false, const Twine &Name = "") { + IRBuilder<> Builder(Insert); if (Ty->isPointerTy()) { // If pointer, we can bitcast directly - IRBuilder<> Builder(Insert); return cast(Builder.CreateBitCast(V, Ty, Name)); - } - else { + } else { // If value, we have to alloca, store to bitcast ptr, and load - IRBuilder<> EntryBuilder(Insert->getParent()->getParent()->getEntryBlock().begin()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Insert)); Type *allocaTy = bOrigAllocaTy ? V->getType() : Ty; Type *otherTy = bOrigAllocaTy ? Ty : V->getType(); - Instruction *allocaInst = EntryBuilder.CreateAlloca(allocaTy); - IRBuilder<> Builder(Insert); + Instruction *allocaInst = AllocaBuilder.CreateAlloca(allocaTy); Instruction *bitCast = cast(Builder.CreateBitCast(allocaInst, otherTy->getPointerTo())); Builder.CreateStore(V, bOrigAllocaTy ? allocaInst : bitCast); return Builder.CreateLoad(bOrigAllocaTy ? bitCast : allocaInst, Name); @@ -855,14 +853,14 @@ void HLMatrixLowerPass::lowerToVec(Instruction *matInst) { Type *Ty = AI->getAllocatedType(); Type *matTy = Ty; - IRBuilder<> Builder(AI); + IRBuilder<> AllocaBuilder(AI); if (Ty->isArrayTy()) { Type *vecTy = HLMatrixLower::LowerMatrixArrayPointer(AI->getType()); vecTy = vecTy->getPointerElementType(); - vecVal = Builder.CreateAlloca(vecTy, nullptr, AI->getName()); + vecVal = AllocaBuilder.CreateAlloca(vecTy, nullptr, AI->getName()); } else { Type *vecTy = HLMatrixLower::LowerMatrixType(matTy); - vecVal = Builder.CreateAlloca(vecTy, nullptr, AI->getName()); + vecVal = AllocaBuilder.CreateAlloca(vecTy, nullptr, AI->getName()); } // Update debug info. DbgDeclareInst *DDI = llvm::FindAllocaDbgDeclare(AI); diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index 724f60ba4..8865683c9 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -6727,18 +6727,16 @@ void TranslateSubscriptOperation(Function *F, HLOperationLowerHelper &helper, H // Create BitCast if ptr, otherwise, create alloca of new type, write to bitcast of alloca, and return load from alloca // If bOrigAllocaTy is true: create alloca of old type instead, write to alloca, and return load from bitcast of alloca static Instruction *BitCastValueOrPtr(Value* V, Instruction *Insert, Type *Ty, bool bOrigAllocaTy = false, const Twine &Name = "") { + IRBuilder<> Builder(Insert); if (Ty->isPointerTy()) { // If pointer, we can bitcast directly - IRBuilder<> Builder(Insert); return cast(Builder.CreateBitCast(V, Ty, Name)); - } - else { + } else { // If value, we have to alloca, store to bitcast ptr, and load - IRBuilder<> EntryBuilder(Insert->getParent()->getParent()->getEntryBlock().begin()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Insert)); Type *allocaTy = bOrigAllocaTy ? V->getType() : Ty; Type *otherTy = bOrigAllocaTy ? Ty : V->getType(); - Instruction *allocaInst = EntryBuilder.CreateAlloca(allocaTy); - IRBuilder<> Builder(Insert); + Instruction *allocaInst = AllocaBuilder.CreateAlloca(allocaTy); Instruction *bitCast = cast(Builder.CreateBitCast(allocaInst, otherTy->getPointerTo())); Builder.CreateStore(V, bOrigAllocaTy ? allocaInst : bitCast); return Builder.CreateLoad(bOrigAllocaTy ? bitCast : allocaInst, Name); diff --git a/lib/HLSL/HLSignatureLower.cpp b/lib/HLSL/HLSignatureLower.cpp index 71afc24dc..f3673ed9f 100644 --- a/lib/HLSL/HLSignatureLower.cpp +++ b/lib/HLSL/HLSignatureLower.cpp @@ -19,6 +19,7 @@ #include "dxc/HLSL/HLModule.h" #include "dxc/HLSL/HLMatrixLowerHelper.h" #include "dxc/HlslIntrinsicOp.h" +#include "dxc/HLSL/DxilUtil.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/DebugInfo.h" @@ -530,6 +531,7 @@ Value *replaceLdWithLdInput(Function *loadInput, LoadInst *ldInst, unsigned cols, MutableArrayRef args, bool bCast) { IRBuilder<> Builder(ldInst); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(ldInst)); Type *Ty = ldInst->getType(); Type *EltTy = Ty->getScalarType(); // Change i1 to i32 for load input. @@ -570,7 +572,7 @@ Value *replaceLdWithLdInput(Function *loadInput, LoadInst *ldInst, // Vector indexing. // Load to array. ArrayType *AT = ArrayType::get(ldInst->getType(), cols); - Value *arrayVec = Builder.CreateAlloca(AT); + Value *arrayVec = AllocaBuilder.CreateAlloca(AT); Value *zeroIdx = Builder.getInt32(0); for (unsigned col = 0; col < cols; col++) { diff --git a/lib/Transforms/Scalar/Reg2MemHLSL.cpp b/lib/Transforms/Scalar/Reg2MemHLSL.cpp index 5c9954818..43ce2e318 100644 --- a/lib/Transforms/Scalar/Reg2MemHLSL.cpp +++ b/lib/Transforms/Scalar/Reg2MemHLSL.cpp @@ -59,15 +59,15 @@ namespace { return nullptr; } - IRBuilder<> Builder(P); + IRBuilder<> AllocaBuilder(P); if (!AllocaPoint) { Function *F = P->getParent()->getParent(); AllocaPoint = F->getEntryBlock().begin(); } - Builder.SetInsertPoint(AllocaPoint); + AllocaBuilder.SetInsertPoint(AllocaPoint); // Create a stack slot to hold the value. - AllocaInst *Slot = Builder.CreateAlloca(P->getType(), nullptr, P->getName() + ".reg2mem"); + AllocaInst *Slot = AllocaBuilder.CreateAlloca(P->getType(), nullptr, P->getName() + ".reg2mem"); // Insert a load in place of the PHI and replace all uses. BasicBlock::iterator InsertPt = P; @@ -123,23 +123,23 @@ namespace { return nullptr; } - IRBuilder<> Builder(&I); + IRBuilder<> AllocaBuilder(&I); if (!AllocaPoint) { Function *F = I.getParent()->getParent(); AllocaPoint = F->getEntryBlock().begin(); } - Builder.SetInsertPoint(AllocaPoint); + AllocaBuilder.SetInsertPoint(AllocaPoint); if (AllocaInst *AI = dyn_cast(&I)) { // Create a stack slot to hold the value. - AllocaInst *Slot = Builder.CreateAlloca(AI->getAllocatedType(), nullptr, I.getName() + ".reg2mem"); + AllocaInst *Slot = AllocaBuilder.CreateAlloca(AI->getAllocatedType(), nullptr, I.getName() + ".reg2mem"); I.replaceAllUsesWith(Slot); I.eraseFromParent(); return Slot; } // Create a stack slot to hold the value. - AllocaInst *Slot = Builder.CreateAlloca(I.getType(), nullptr, I.getName() + ".reg2mem");; + AllocaInst *Slot = AllocaBuilder.CreateAlloca(I.getType(), nullptr, I.getName() + ".reg2mem");; // Change all of the users of the instruction to read from the stack slot. while (!I.use_empty()) { diff --git a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp index c633db5fe..2f2fec783 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp @@ -1605,7 +1605,7 @@ bool SROA_HLSL::performScalarRepl(Function &F, DxilTypeSystem &typeSys) { // separate elements. if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) { std::vector Elts; - IRBuilder<> Builder(AI); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(AI)); bool hasPrecise = HLModule::HasPreciseAttributeWithMetadata(AI); bool SROAed = SROA_Helper::DoScalarReplacement( @@ -3068,7 +3068,7 @@ void SROA_Helper::RewriteBitCast(BitCastInst *BCI) { void SROA_Helper::RewriteCallArg(CallInst *CI, unsigned ArgIdx, bool bIn, bool bOut) { Function *F = CI->getParent()->getParent(); - IRBuilder<> AllocaBuilder(F->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(F)); const DataLayout &DL = F->getParent()->getDataLayout(); Value *userTyV = CI->getArgOperand(ArgIdx); @@ -3269,7 +3269,9 @@ bool SROA_Helper::DoScalarReplacement(Value *V, std::vector &Elts, // Skip matrix types. if (HLMatrixLower::IsMatrixType(Ty)) return false; - + + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Builder.GetInsertPoint())); + if (StructType *ST = dyn_cast(Ty)) { // Skip HLSL object types. if (HLModule::IsHLSLObjectType(ST)) { @@ -3283,7 +3285,7 @@ bool SROA_Helper::DoScalarReplacement(Value *V, std::vector &Elts, if (SA && SA->IsEmptyStruct()) return true; for (int i = 0, e = numTypes; i != e; ++i) { - AllocaInst *NA = Builder.CreateAlloca(ST->getContainedType(i), nullptr, V->getName() + "." + Twine(i)); + AllocaInst *NA = AllocaBuilder.CreateAlloca(ST->getContainedType(i), nullptr, V->getName() + "." + Twine(i)); bool markPrecise = hasPrecise; if (SA) { DxilFieldAnnotation &FA = SA->GetFieldAnnotation(i); @@ -3324,7 +3326,7 @@ bool SROA_Helper::DoScalarReplacement(Value *V, std::vector &Elts, if (SA && SA->IsEmptyStruct()) return true; for (int i = 0, e = numTypes; i != e; ++i) { - AllocaInst *NA = Builder.CreateAlloca( + AllocaInst *NA = AllocaBuilder.CreateAlloca( CreateNestArrayTy(ElST->getContainedType(i), nestArrayTys), nullptr, V->getName() + "." + Twine(i)); bool markPrecise = hasPrecise; @@ -3344,7 +3346,7 @@ bool SROA_Helper::DoScalarReplacement(Value *V, std::vector &Elts, nestArrayTys.size() > 1) return false; for (int i = 0, e = AT->getNumElements(); i != e; ++i) { - AllocaInst *NA = Builder.CreateAlloca(ElTy, nullptr, + AllocaInst *NA = AllocaBuilder.CreateAlloca(ElTy, nullptr, V->getName() + "." + Twine(i)); Elts.push_back(NA); } @@ -3362,7 +3364,7 @@ bool SROA_Helper::DoScalarReplacement(Value *V, std::vector &Elts, ArrayType *scalarArrayTy = CreateNestArrayTy(ElVT->getElementType(), nestArrayTys); for (int i = 0, e = ElVT->getNumElements(); i != e; ++i) { - AllocaInst *NA = Builder.CreateAlloca(scalarArrayTy, nullptr, + AllocaInst *NA = AllocaBuilder.CreateAlloca(scalarArrayTy, nullptr, V->getName() + "." + Twine(i)); if (hasPrecise) HLModule::MarkPreciseAttributeWithMetadata(NA); @@ -4784,7 +4786,8 @@ void SROA_Parameter_HLSL::replaceCastParameter( if (isa(OldParam) && OldTy->isPointerTy()) { // OldParam will be removed with Old function. // Create alloca to replace it. - Value *AllocParam = Builder.CreateAlloca(OldTy->getPointerElementType()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(&F)); + Value *AllocParam = AllocaBuilder.CreateAlloca(OldTy->getPointerElementType()); OldParam->replaceAllUsesWith(AllocParam); OldParam = AllocParam; } @@ -4880,6 +4883,8 @@ Value *SROA_Parameter_HLSL::castResourceArgIfRequired( IRBuilder<> &Builder) { Type *HandleTy = m_pHLModule->GetOP()->GetHandleType(); Module &M = *m_pHLModule->GetModule(); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Builder.GetInsertPoint())); + // Lower resource type to handle ty. if (HLModule::IsHLSLObjectType(Ty) && !HLModule::IsStreamOutputPtrType(V->getType())) { @@ -4891,7 +4896,7 @@ Value *SROA_Parameter_HLSL::castResourceArgIfRequired( /*opcode*/ 0, HandleTy, { LdRes }, M); } else { - V = Builder.CreateAlloca(HandleTy); + V = AllocaBuilder.CreateAlloca(HandleTy); } castParamMap[V] = std::make_pair(Res, inputQual); } @@ -4905,7 +4910,7 @@ Value *SROA_Parameter_HLSL::castResourceArgIfRequired( if (HLModule::IsHLSLObjectType(AT)) { Value *Res = V; Type *Ty = ArrayType::get(HandleTy, arraySize); - V = Builder.CreateAlloca(Ty); + V = AllocaBuilder.CreateAlloca(Ty); castParamMap[V] = std::make_pair(Res, inputQual); } } @@ -4917,9 +4922,11 @@ Value *SROA_Parameter_HLSL::castArgumentIfRequired( DxilParamInputQual inputQual, DxilFieldAnnotation &annotation, std::deque &WorkList, IRBuilder<> &Builder) { Module &M = *m_pHLModule->GetModule(); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Builder.GetInsertPoint())); + // Remove pointer for vector/scalar which is not out. if (V->getType()->isPointerTy() && !Ty->isAggregateType() && !bOut) { - Value *Ptr = Builder.CreateAlloca(Ty); + Value *Ptr = AllocaBuilder.CreateAlloca(Ty); V->replaceAllUsesWith(Ptr); // Create load here to make correct type. // The Ptr will be store with correct value in replaceCastParameter. @@ -5005,6 +5012,7 @@ void SROA_Parameter_HLSL::flattenArgument( std::vector &FlatParamList, std::vector &FlatAnnotationList, IRBuilder<> &Builder, DbgDeclareInst *DDI) { + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(Builder.GetInsertPoint())); std::deque WorkList; WorkList.push_back(Arg); @@ -5140,7 +5148,7 @@ void SROA_Parameter_HLSL::flattenArgument( unsigned targetIndex; Semantic::DecomposeNameAndIndex(semanticStr, &targetStr, &targetIndex); // Replace target parameter with local target. - AllocaInst *localTarget = Builder.CreateAlloca(Ty); + AllocaInst *localTarget = AllocaBuilder.CreateAlloca(Ty); V->replaceAllUsesWith(localTarget); unsigned arraySize = 1; std::vector arraySizeList; @@ -5157,7 +5165,7 @@ void SROA_Parameter_HLSL::flattenArgument( // Create flattened target. DxilFieldAnnotation EltAnnotation = annotation; for (unsigned i=0;igetType()->getPointerElementType()->getStructElementType(0); - Value *outputVal = Builder.CreateAlloca(outputType); + Value *outputVal = AllocaBuilder.CreateAlloca(outputType); // For each stream.Append(data) // transform into // d = load data @@ -5372,7 +5380,8 @@ void SROA_Parameter_HLSL::preprocessArgUsedInCall(Function *F) { DxilFunctionAnnotation *pFuncAnnot = typeSys.GetFunctionAnnotation(F); DXASSERT(pFuncAnnot, "else invalid function"); - IRBuilder<> AllocaBuilder(F->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(F)); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F)); SmallVector retList; for (BasicBlock &bb : F->getBasicBlockList()) { @@ -5407,7 +5416,7 @@ void SROA_Parameter_HLSL::preprocessArgUsedInCall(Function *F) { if (inputQual == DxilParamInputQual::In || inputQual == DxilParamInputQual::Inout) { // copy arg to tmp. - CallInst *argToTmp = AllocaBuilder.CreateMemCpy(TmpArg, &arg, size, 0); + CallInst *argToTmp = Builder.CreateMemCpy(TmpArg, &arg, size, 0); // Split the memcpy. MemcpySplitter::SplitMemCpy(cast(argToTmp), DL, nullptr, typeSys); @@ -5525,7 +5534,7 @@ static void LegalizeDxilInputOutputs(Function *F, // DxilGenerationPass. isColMajor = paramAnnotation.GetMatrixAnnotation().Orientation == MatrixOrientation::ColumnMajor; - IRBuilder<> Builder(EntryBlk.getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F)); HLCastOpcode opcode = isColMajor ? HLCastOpcode::ColMatrixToVecCast : HLCastOpcode::RowMatrixToVecCast; @@ -5591,9 +5600,10 @@ static void LegalizeDxilInputOutputs(Function *F, } if (bNeedTemp) { - IRBuilder<> Builder(EntryBlk.getFirstInsertionPt()); + IRBuilder<> AllocaBuilder(EntryBlk.getFirstInsertionPt()); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(&EntryBlk)); - AllocaInst *temp = Builder.CreateAlloca(Ty); + AllocaInst *temp = AllocaBuilder.CreateAlloca(Ty); // Replace all uses with temp. arg.replaceAllUsesWith(temp); @@ -5684,9 +5694,9 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) { // Insert point may be removed. So recreate builder every time. IRBuilder<> Builder(Ctx); if (!F->isDeclaration()) { - Builder.SetInsertPoint(F->getEntryBlock().getFirstInsertionPt()); + Builder.SetInsertPoint(dxilutil::FirstNonAllocaInsertionPt(F)); } else { - Builder.SetInsertPoint(TmpBlockForFuncDecl->getFirstInsertionPt()); + Builder.SetInsertPoint(dxilutil::FirstNonAllocaInsertionPt(TmpBlockForFuncDecl.get())); } unsigned prevFlatParamCount = FlatParamList.size(); @@ -5710,12 +5720,15 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) { // Split and change to out parameter. if (!retType->isVoidTy()) { IRBuilder<> Builder(Ctx); + IRBuilder<> AllocaBuilder(Ctx); if (!F->isDeclaration()) { - Builder.SetInsertPoint(F->getEntryBlock().getFirstInsertionPt()); + Builder.SetInsertPoint(dxilutil::FirstNonAllocaInsertionPt(F)); + AllocaBuilder.SetInsertPoint(dxilutil::FindAllocaInsertionPt(F)); } else { - Builder.SetInsertPoint(TmpBlockForFuncDecl->getFirstInsertionPt()); + Builder.SetInsertPoint(dxilutil::FirstNonAllocaInsertionPt(TmpBlockForFuncDecl.get())); + AllocaBuilder.SetInsertPoint(TmpBlockForFuncDecl->getFirstInsertionPt()); } - Value *retValAddr = Builder.CreateAlloca(retType); + Value *retValAddr = AllocaBuilder.CreateAlloca(retType); DxilParameterAnnotation &retAnnotation = funcAnnotation->GetRetTypeAnnotation(); Module &M = *m_pHLModule->GetModule(); @@ -5925,7 +5938,8 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) { LLVMContext &Context = F->getContext(); // Parameter cast come from begining of entry block. - IRBuilder<> Builder(flatF->getEntryBlock().getFirstInsertionPt()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(flatF)); + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(flatF)); while (argIter != flatF->arg_end()) { Argument *Arg = argIter++; @@ -5950,7 +5964,7 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) { StoreInst *SI = cast(*flatArg->user_begin()); allocaArg = SI->getPointerOperand(); } else { - allocaArg = Builder.CreateAlloca(flatArg->getType()); + allocaArg = AllocaBuilder.CreateAlloca(flatArg->getType()); StoreInst *initArg = Builder.CreateStore(flatArg, allocaArg); Value *ldArg = Builder.CreateLoad(allocaArg); flatArg->replaceAllUsesWith(ldArg); @@ -6062,8 +6076,10 @@ bool LowerStaticGlobalIntoAlloca::lowerStaticGlobalIntoAlloca(GlobalVariable *GV return false; Function *F = const_cast(PS.AccessingFunction); - IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt()); - AllocaInst *AI = Builder.CreateAlloca(GV->getType()->getElementType()); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(F)); + AllocaInst *AI = AllocaBuilder.CreateAlloca(GV->getType()->getElementType()); + + IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F)); // Store initializer is exist. if (GV->hasInitializer() && !isa(GV->getInitializer())) { @@ -6110,9 +6126,9 @@ protected: }; AllocaInst *LowerTypePass::lowerAlloca(AllocaInst *A) { - IRBuilder<> Builder(A); + IRBuilder<> AllocaBuilder(A); Type *NewTy = lowerType(A->getAllocatedType()); - return Builder.CreateAlloca(NewTy); + return AllocaBuilder.CreateAlloca(NewTy); } GlobalVariable *LowerTypePass::lowerInternalGlobal(GlobalVariable *GV) { diff --git a/tools/clang/lib/CodeGen/CGHLSLMS.cpp b/tools/clang/lib/CodeGen/CGHLSLMS.cpp index 990d6efa4..2d1089189 100644 --- a/tools/clang/lib/CodeGen/CGHLSLMS.cpp +++ b/tools/clang/lib/CodeGen/CGHLSLMS.cpp @@ -6502,15 +6502,14 @@ void CGMSHLSLRuntime::EmitHLSLOutParamConversionInit( Value *tmpArgAddr = nullptr; BasicBlock *InsertBlock = CGF.Builder.GetInsertBlock(); Function *F = InsertBlock->getParent(); - BasicBlock *EntryBlock = &F->getEntryBlock(); if (ParamTy->isBooleanType()) { // Create i32 for bool. ParamTy = CGM.getContext().IntTy; } // Make sure the alloca is in entry block to stop inline create stacksave. - IRBuilder<> Builder(EntryBlock->getFirstInsertionPt()); - tmpArgAddr = Builder.CreateAlloca(CGF.ConvertType(ParamTy)); + IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(F)); + tmpArgAddr = AllocaBuilder.CreateAlloca(CGF.ConvertType(ParamTy)); // add it to local decl map