|
@@ -81,6 +81,7 @@
|
|
|
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
|
|
|
|
|
#include "dxc/DXIL/DxilUtil.h"
|
|
|
+#include "dxc/DXIL/DxilOperations.h"
|
|
|
#include "dxc/HLSL/HLModule.h"
|
|
|
#include "llvm/Analysis/DxilValueCache.h"
|
|
|
|
|
@@ -130,6 +131,7 @@ public:
|
|
|
}
|
|
|
const char *getPassName() const override { return "Dxil Loop Unroll"; }
|
|
|
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
|
|
|
+ bool IsLoopSafeToClone(Loop *L);
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
|
AU.addRequired<LoopInfoWrapperPass>();
|
|
|
AU.addRequired<AssumptionCacheTracker>();
|
|
@@ -636,6 +638,33 @@ static void RecursivelyRemoveLoopFromQueue(LPPassManager &LPM, Loop *L) {
|
|
|
LPM.deleteLoopFromQueue(L);
|
|
|
}
|
|
|
|
|
|
+// Mostly copied from Loop::isSafeToClone, but making exception
|
|
|
+// for dx.op.barrier.
|
|
|
+//
|
|
|
+bool DxilLoopUnroll::IsLoopSafeToClone(Loop *L) {
|
|
|
+ // Return false if any loop blocks contain indirectbrs, or there are any calls
|
|
|
+ // to noduplicate functions.
|
|
|
+ for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) {
|
|
|
+ if (isa<IndirectBrInst>((*I)->getTerminator()))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator()))
|
|
|
+ if (II->cannotDuplicate())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ for (BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); BI != BE; ++BI) {
|
|
|
+ if (const CallInst *CI = dyn_cast<CallInst>(BI)) {
|
|
|
+ if (CI->cannotDuplicate() &&
|
|
|
+ !hlsl::OP::IsDxilOpFuncCallInst(CI, hlsl::OP::OpCode::Barrier))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|
|
|
|
|
DebugLoc LoopLoc = L->getStartLoc(); // Debug location for the start of the loop.
|
|
@@ -663,7 +692,7 @@ bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|
|
ExplicitUnrollCount = (unsigned)ExplicitUnrollCountSigned;
|
|
|
}
|
|
|
|
|
|
- if (!L->isSafeToClone())
|
|
|
+ if (!IsLoopSafeToClone(L))
|
|
|
return false;
|
|
|
|
|
|
unsigned TripCount = 0;
|