Browse Source

New approach to avoid skipallocas (#3219)

Many places that previously relied on skipallocas to find the right
place for a non-alloca instruction are replaced with at least the
attempt to find a valid location depending on conditions. This is a
piecemeal case by case determination. The exception is the SROA pass
which made heavy and necessary use of the skipallocas call. Instead, at
the end of the pass, allocas are shuffled to the top of the entry block.
PIX passes are ignored here because they are not involved in the compile
time complaints and I'm unfamiliar with the circumstances when they are
invoked.
Greg Roth 4 years ago
parent
commit
bba9c4506a

+ 1 - 1
lib/HLSL/DxilCondenseResources.cpp

@@ -2077,7 +2077,7 @@ void DxilLowerCreateHandleForLib::TranslateDxilResourceUses(
   for (iplist<Function>::iterator F : pM->getFunctionList()) {
   for (iplist<Function>::iterator F : pM->getFunctionList()) {
     if (!F->isDeclaration()) {
     if (!F->isDeclaration()) {
       if (!isResArray) {
       if (!isResArray) {
-        IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F));
+        IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(F));
         if (m_HasDbgInfo) {
         if (m_HasDbgInfo) {
           // TODO: set debug info.
           // TODO: set debug info.
           // Builder.SetCurrentDebugLocation(DL);
           // Builder.SetCurrentDebugLocation(DL);

+ 1 - 7
lib/HLSL/DxilGenerationPass.cpp

@@ -55,19 +55,13 @@ void SimplifyGlobalSymbol(GlobalVariable *GV) {
         Function *F = LI->getParent()->getParent();
         Function *F = LI->getParent()->getParent();
         auto it = handleMapOnFunction.find(F);
         auto it = handleMapOnFunction.find(F);
         if (it == handleMapOnFunction.end()) {
         if (it == handleMapOnFunction.end()) {
+          LI->moveBefore(dxilutil::FindAllocaInsertionPt(F));
           handleMapOnFunction[F] = LI;
           handleMapOnFunction[F] = LI;
         } else {
         } else {
           LI->replaceAllUsesWith(it->second);
           LI->replaceAllUsesWith(it->second);
         }
         }
       }
       }
     }
     }
-    for (auto it : handleMapOnFunction) {
-      Function *F = it.first;
-      Instruction *I = it.second;
-      IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F));
-      Value *headLI = Builder.CreateLoad(GV);
-      I->replaceAllUsesWith(headLI);
-    }
   }
   }
 }
 }
 
 

+ 1 - 1
lib/HLSL/DxilLinker.cpp

@@ -792,7 +792,7 @@ DxilLinkJob::Link(std::pair<DxilFunctionLinkInfo *, DxilLib *> &entryLinkPair,
   CloneFunctions(vmap);
   CloneFunctions(vmap);
 
 
   // Call global constrctor.
   // Call global constrctor.
-  IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(DM.GetEntryFunction()));
+  IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(DM.GetEntryFunction()));
   for (auto &it : m_functionDefs) {
   for (auto &it : m_functionDefs) {
     DxilFunctionLinkInfo *linkInfo = it.first;
     DxilFunctionLinkInfo *linkInfo = it.first;
     DxilLib *pLib = it.second;
     DxilLib *pLib = it.second;

+ 1 - 1
lib/HLSL/DxilPreparePasses.cpp

@@ -715,7 +715,7 @@ private:
           Function *F = CI->getParent()->getParent();
           Function *F = CI->getParent()->getParent();
           ICmpInst *Cmp = DxBreakCmpMap.lookup(F);
           ICmpInst *Cmp = DxBreakCmpMap.lookup(F);
           if (!Cmp) {
           if (!Cmp) {
-            Instruction *IP = dxilutil::FirstNonAllocaInsertionPt(F);
+            Instruction *IP = dxilutil::FindAllocaInsertionPt(F);
             LoadInst *LI = new LoadInst(Gep, nullptr, false, IP);
             LoadInst *LI = new LoadInst(Gep, nullptr, false, IP);
             Cmp = new ICmpInst(IP, ICmpInst::ICMP_EQ, LI, llvm::ConstantInt::get(i32Ty,0));
             Cmp = new ICmpInst(IP, ICmpInst::ICMP_EQ, LI, llvm::ConstantInt::get(i32Ty,0));
             DxBreakCmpMap[F] = Cmp;
             DxBreakCmpMap[F] = Cmp;

+ 1 - 1
lib/HLSL/HLMatrixLowerPass.cpp

@@ -476,7 +476,7 @@ void HLMatrixLowerPass::replaceAllUsesByLoweredValue(Instruction* MatInst, Value
       Instruction *PrevInst = dyn_cast<Instruction>(VecVal);
       Instruction *PrevInst = dyn_cast<Instruction>(VecVal);
       if (PrevInst == nullptr) PrevInst = MatInst;
       if (PrevInst == nullptr) PrevInst = MatInst;
 
 
-      IRBuilder<> Builder(dxilutil::SkipAllocas(PrevInst->getNextNode()));
+      IRBuilder<> Builder(PrevInst->getNextNode());
       VecToMatStub = Builder.CreateCall(TranslationStub, { VecVal });
       VecToMatStub = Builder.CreateCall(TranslationStub, { VecVal });
     }
     }
 
 

+ 34 - 24
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -1748,7 +1748,7 @@ bool SROAGlobalAndAllocas(HLModule &HLM, bool bHasDbgInfo) {
       // separate elements.
       // separate elements.
       if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) {
       if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) {
         std::vector<Value *> Elts;
         std::vector<Value *> Elts;
-        IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(AI));
+        IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(AI));
         bool hasPrecise = HLModule::HasPreciseAttributeWithMetadata(AI);
         bool hasPrecise = HLModule::HasPreciseAttributeWithMetadata(AI);
 
 
         Type *BrokenUpTy = nullptr;
         Type *BrokenUpTy = nullptr;
@@ -3711,6 +3711,23 @@ public:
     // SROA globals and allocas.
     // SROA globals and allocas.
     SROAGlobalAndAllocas(*m_pHLModule, m_HasDbgInfo);
     SROAGlobalAndAllocas(*m_pHLModule, m_HasDbgInfo);
 
 
+    // Move up allocas that might have been pushed down by instruction inserts
+    for (Function &F : M) {
+      if (F.isDeclaration())
+        continue;
+      Instruction *insertPt = nullptr;
+      // SROA only potentially "incorrectly" inserts non-allocas into the entry block.
+      for (llvm::Instruction &I : F.getEntryBlock()) {
+        if (!insertPt) {
+          // Find the first non-alloca to move the allocas above
+          if (!isa<AllocaInst>(I) && !isa<DbgInfoIntrinsic>(I))
+            insertPt = &I;
+        } else if (isa<AllocaInst>(I)) {
+          // Move any alloca to before the first non-alloca
+          I.moveBefore(insertPt);
+        }
+      }
+    }
     return true;
     return true;
   }
   }
 
 
@@ -4598,10 +4615,9 @@ void SROA_Parameter_HLSL::flattenArgument(
     const bool bAllowReplace = false;
     const bool bAllowReplace = false;
     SROA_Helper::LowerMemcpy(V, &annotation, dxilTypeSys, DL, nullptr /*DT */, bAllowReplace);
     SROA_Helper::LowerMemcpy(V, &annotation, dxilTypeSys, DL, nullptr /*DT */, bAllowReplace);
 
 
-    // Now is safe to create the IRBuilders.
+    // Now is safe to create the IRBuilder.
     // If we create it before LowerMemcpy, the insertion pointer instruction may get deleted
     // If we create it before LowerMemcpy, the insertion pointer instruction may get deleted
-    IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(EntryBlock));
-    IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(EntryBlock));
+    IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(EntryBlock));
 
 
     std::vector<Value *> Elts;
     std::vector<Value *> Elts;
 
 
@@ -4679,7 +4695,7 @@ void SROA_Parameter_HLSL::flattenArgument(
         unsigned  targetIndex;
         unsigned  targetIndex;
         Semantic::DecomposeNameAndIndex(semanticStr, &targetStr, &targetIndex);
         Semantic::DecomposeNameAndIndex(semanticStr, &targetStr, &targetIndex);
         // Replace target parameter with local target.
         // Replace target parameter with local target.
-        AllocaInst *localTarget = AllocaBuilder.CreateAlloca(Ty);
+        AllocaInst *localTarget = Builder.CreateAlloca(Ty);
         V->replaceAllUsesWith(localTarget);
         V->replaceAllUsesWith(localTarget);
         unsigned arraySize = 1;
         unsigned arraySize = 1;
         std::vector<unsigned> arraySizeList;
         std::vector<unsigned> arraySizeList;
@@ -4696,7 +4712,7 @@ void SROA_Parameter_HLSL::flattenArgument(
         // Create flattened target.
         // Create flattened target.
         DxilFieldAnnotation EltAnnotation = annotation;
         DxilFieldAnnotation EltAnnotation = annotation;
         for (unsigned i=0;i<arraySize;i++) {
         for (unsigned i=0;i<arraySize;i++) {
-          Value *Elt = AllocaBuilder.CreateAlloca(Ty);
+          Value *Elt = Builder.CreateAlloca(Ty);
           EltAnnotation.SetSemanticString(targetStr.str()+std::to_string(targetIndex+i));
           EltAnnotation.SetSemanticString(targetStr.str()+std::to_string(targetIndex+i));
 
 
           // Add semantic type.
           // Add semantic type.
@@ -4798,7 +4814,7 @@ void SROA_Parameter_HLSL::flattenArgument(
         // For stream output objects.
         // For stream output objects.
         // Create a value as output value.
         // Create a value as output value.
         Type *outputType = V->getType()->getPointerElementType()->getStructElementType(0);
         Type *outputType = V->getType()->getPointerElementType()->getStructElementType(0);
-        Value *outputVal = AllocaBuilder.CreateAlloca(outputType);
+        Value *outputVal = Builder.CreateAlloca(outputType);
 
 
         // For each stream.Append(data)
         // For each stream.Append(data)
         // transform into
         // transform into
@@ -4924,8 +4940,7 @@ void SROA_Parameter_HLSL::preprocessArgUsedInCall(Function *F) {
   DxilFunctionAnnotation *pFuncAnnot = typeSys.GetFunctionAnnotation(F);
   DxilFunctionAnnotation *pFuncAnnot = typeSys.GetFunctionAnnotation(F);
   DXASSERT(pFuncAnnot, "else invalid function");
   DXASSERT(pFuncAnnot, "else invalid function");
 
 
-  IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(F));
-  IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F));
+  IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(F));
 
 
   SmallVector<ReturnInst*, 2> retList;
   SmallVector<ReturnInst*, 2> retList;
   for (BasicBlock &bb : F->getBasicBlockList()) {
   for (BasicBlock &bb : F->getBasicBlockList()) {
@@ -4949,7 +4964,7 @@ void SROA_Parameter_HLSL::preprocessArgUsedInCall(Function *F) {
 
 
     if (bUsedInCall) {
     if (bUsedInCall) {
       // Create tmp.
       // Create tmp.
-      Value *TmpArg = AllocaBuilder.CreateAlloca(Ty);
+      Value *TmpArg = Builder.CreateAlloca(Ty);
       // Replace arg with tmp.
       // Replace arg with tmp.
       arg.replaceAllUsesWith(TmpArg);
       arg.replaceAllUsesWith(TmpArg);
 
 
@@ -5118,7 +5133,7 @@ static void LegalizeDxilInputOutputs(Function *F,
         // DxilGenerationPass.
         // DxilGenerationPass.
         isColMajor = paramAnnotation.GetMatrixAnnotation().Orientation ==
         isColMajor = paramAnnotation.GetMatrixAnnotation().Orientation ==
                      MatrixOrientation::ColumnMajor;
                      MatrixOrientation::ColumnMajor;
-        IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F));
+        IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(F));
 
 
         HLCastOpcode opcode = isColMajor ? HLCastOpcode::ColMatrixToVecCast
         HLCastOpcode opcode = isColMajor ? HLCastOpcode::ColMatrixToVecCast
                                          : HLCastOpcode::RowMatrixToVecCast;
                                          : HLCastOpcode::RowMatrixToVecCast;
@@ -5179,10 +5194,9 @@ static void LegalizeDxilInputOutputs(Function *F,
     }
     }
 
 
     if (bStoreInputToTemp || bLoadOutputFromTemp) {
     if (bStoreInputToTemp || bLoadOutputFromTemp) {
-      IRBuilder<> AllocaBuilder(EntryBlk.getFirstInsertionPt());
-      IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(&EntryBlk));
+      IRBuilder<> Builder(EntryBlk.getFirstInsertionPt());
 
 
-      AllocaInst *temp = AllocaBuilder.CreateAlloca(Ty);
+      AllocaInst *temp = Builder.CreateAlloca(Ty);
       // Replace all uses with temp.
       // Replace all uses with temp.
       arg.replaceAllUsesWith(temp);
       arg.replaceAllUsesWith(temp);
 
 
@@ -5296,9 +5310,8 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) {
   std::vector<DxilParameterAnnotation> FlatRetAnnotationList;
   std::vector<DxilParameterAnnotation> FlatRetAnnotationList;
   // Split and change to out parameter.
   // Split and change to out parameter.
   if (!retType->isVoidTy()) {
   if (!retType->isVoidTy()) {
-    IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(EntryBlock));
-    IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(EntryBlock));
-    Value *retValAddr = AllocaBuilder.CreateAlloca(retType);
+    IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(EntryBlock));
+    Value *retValAddr = Builder.CreateAlloca(retType);
     DxilParameterAnnotation &retAnnotation =
     DxilParameterAnnotation &retAnnotation =
         funcAnnotation->GetRetTypeAnnotation();
         funcAnnotation->GetRetTypeAnnotation();
     Module &M = *m_pHLModule->GetModule();
     Module &M = *m_pHLModule->GetModule();
@@ -5510,8 +5523,7 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) {
     LLVMContext &Context = F->getContext();
     LLVMContext &Context = F->getContext();
 
 
     // Parameter cast come from begining of entry block.
     // Parameter cast come from begining of entry block.
-    IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(flatF));
-    IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(flatF));
+    IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(flatF));
 
 
     while (argIter != flatF->arg_end()) {
     while (argIter != flatF->arg_end()) {
       Argument *Arg = argIter++;
       Argument *Arg = argIter++;
@@ -5536,7 +5548,7 @@ void SROA_Parameter_HLSL::createFlattenedFunction(Function *F) {
             StoreInst *SI = cast<StoreInst>(*flatArg->user_begin());
             StoreInst *SI = cast<StoreInst>(*flatArg->user_begin());
             allocaArg = SI->getPointerOperand();
             allocaArg = SI->getPointerOperand();
           } else {
           } else {
-            allocaArg = AllocaBuilder.CreateAlloca(flatArg->getType());
+            allocaArg = Builder.CreateAlloca(flatArg->getType());
             StoreInst *initArg = Builder.CreateStore(flatArg, allocaArg);
             StoreInst *initArg = Builder.CreateStore(flatArg, allocaArg);
             Value *ldArg = Builder.CreateLoad(allocaArg);
             Value *ldArg = Builder.CreateLoad(allocaArg);
             flatArg->replaceAllUsesWith(ldArg);
             flatArg->replaceAllUsesWith(ldArg);
@@ -5765,10 +5777,8 @@ bool LowerStaticGlobalIntoAlloca::lowerStaticGlobalIntoAlloca(GlobalVariable *GV
     return false;
     return false;
 
 
   Function *F = const_cast<Function*>(PS.AccessingFunction);
   Function *F = const_cast<Function*>(PS.AccessingFunction);
-  IRBuilder<> AllocaBuilder(dxilutil::FindAllocaInsertionPt(F));
-  AllocaInst *AI = AllocaBuilder.CreateAlloca(GV->getType()->getElementType());
-
-  IRBuilder<> Builder(dxilutil::FirstNonAllocaInsertionPt(F));
+  IRBuilder<> Builder(dxilutil::FindAllocaInsertionPt(F));
+  AllocaInst *AI = Builder.CreateAlloca(GV->getType()->getElementType());
 
 
   // Store initializer is exist.
   // Store initializer is exist.
   if (GV->hasInitializer() && !isa<UndefValue>(GV->getInitializer())) {
   if (GV->hasInitializer() && !isa<UndefValue>(GV->getInitializer())) {