2
0
Эх сурвалжийг харах

Enabled loop exit structurizer by default. (#3334)

* Fixed a bug in loop exit structurizer where exit values don't dominate users. Replaced the undef with 0 for numeric types. Enabled it by default.
* No longer using a separate list
Adam Yang 4 жил өмнө
parent
commit
4c66d72760

+ 18 - 8
lib/Transforms/Scalar/DxilRemoveUnstructuredLoopExits.cpp

@@ -276,6 +276,16 @@ static bool IsNoop(Instruction *inst) {
   return false;
 }
 
+static Value* GetDefaultValue(Type *type) {
+  if (type->isIntegerTy()) {
+    return ConstantInt::get(type, 0);
+  }
+  else if (type->isFloatingPointTy()) {
+    return ConstantFP::get(type, 0);
+  }
+  return UndefValue::get(type);
+}
+
 static BasicBlock *GetExitBlockForExitingBlock(Loop *L, BasicBlock *exiting_block) {
   BranchInst *br = dyn_cast<BranchInst>(exiting_block->getTerminator());
   assert(L->contains(exiting_block));
@@ -300,18 +310,18 @@ static void SkipBlockWithBranch(BasicBlock *bb, Value *cond, Loop *L, LoopInfo *
   for (Instruction &inst : *body) {
     PHINode *phi = nullptr;
 
-    for (User *user : inst.users()) {
-      Instruction *user_inst = dyn_cast<Instruction>(user);
-      if (!user_inst)
+    // For each user that's outside of 'body', replace its use of 'inst' with a phi created
+    // in 'end'
+    for (auto it = inst.user_begin(); it != inst.user_end();) {
+      Instruction *user_inst = cast<Instruction>(*(it++));
+      if (user_inst == phi)
         continue;
-
       if (user_inst->getParent() != body) {
         if (!phi) {
           phi = PHINode::Create(inst.getType(), 2, "", &*end->begin());
-          phi->addIncoming(UndefValue::get(inst.getType()), bb);
+          phi->addIncoming(GetDefaultValue(inst.getType()), bb);
           phi->addIncoming(&inst, body);
         }
-
         user_inst->replaceUsesOfWith(&inst, phi);
       }
     } // For each user of inst of body
@@ -369,7 +379,7 @@ static bool RemoveUnstructuredLoopExitsIteration(BasicBlock *exiting_block, Loop
           exit_cond_has_phi = true;
         }
         else {
-          false_value = UndefValue::get(value->getType());
+          false_value = GetDefaultValue(value->getType());
         }
         exit_values.push_back({ value, false_value, phi });
       }
@@ -462,7 +472,7 @@ static bool RemoveUnstructuredLoopExitsIteration(BasicBlock *exiting_block, Loop
       PHINode *phi = dyn_cast<PHINode>(&inst);
       if (!phi)
         break;
-      phi->addIncoming(UndefValue::get(phi->getType()), new_exiting_block);
+      phi->addIncoming(GetDefaultValue(phi->getType()), new_exiting_block);
     }
 
 

+ 1 - 1
tools/clang/lib/CodeGen/BackendUtil.cpp

@@ -337,7 +337,7 @@ void EmitAssemblyHelper::CreatePasses() {
                         CodeGenOpts.HLSLOptimizationToggles.find("gvn")->second;
 
   PMBuilder.StructurizeLoopExitsForUnroll =
-                        CodeGenOpts.HLSLOptimizationToggles.count("structurize-loop-exits-for-unroll") &&
+                        !CodeGenOpts.HLSLOptimizationToggles.count("structurize-loop-exits-for-unroll") ||
                         CodeGenOpts.HLSLOptimizationToggles.find("structurize-loop-exits-for-unroll")->second;
 
   PMBuilder.HLSLEnableLifetimeMarkers = CodeGenOpts.HLSLEnableLifetimeMarkers;

+ 3 - 3
tools/clang/test/HLSLFileCheck/hlsl/control_flow/loops/struct_exit_disable.hlsl

@@ -1,6 +1,6 @@
-// RUN: %dxc -E main -Zi -O3 -T ps_6_0 %s | FileCheck %s
-// RUN: %dxc -E main -Zi -Od -T ps_6_0 %s -DFORCE_UNROLL | FileCheck %s
-// RUN: %dxc -E main -Zi -T ps_6_0 %s -DFORCE_UNROLL | FileCheck %s
+// RUN: %dxc -opt-disable structurize-loop-exits-for-unroll -E main -Zi -O3 -T ps_6_0 %s | FileCheck %s
+// RUN: %dxc -opt-disable structurize-loop-exits-for-unroll -E main -Zi -Od -T ps_6_0 %s -DFORCE_UNROLL | FileCheck %s
+// RUN: %dxc -opt-disable structurize-loop-exits-for-unroll -E main -Zi -T ps_6_0 %s -DFORCE_UNROLL | FileCheck %s
 
 // CHECK: %{{.+}} = call float @dx.op.unary.f32(i32 13
 // CHECK: %{{.+}} = call float @dx.op.unary.f32(i32 13