|
@@ -103,8 +103,8 @@ using namespace llvm;
|
|
|
namespace {
|
|
|
StringRef kNoopName = "dx.noop";
|
|
|
StringRef kPreservePrefix = "dx.preserve.";
|
|
|
-StringRef kNothingName = "dx.nothing";
|
|
|
-StringRef kPreserveName = "dx.preserve.value";
|
|
|
+StringRef kNothingName = "dx.nothing.a";
|
|
|
+StringRef kPreserveName = "dx.preserve.value.a";
|
|
|
}
|
|
|
|
|
|
static Function *GetOrCreateNoopF(Module &M) {
|
|
@@ -115,6 +115,12 @@ static Function *GetOrCreateNoopF(Module &M) {
|
|
|
return NoopF;
|
|
|
}
|
|
|
|
|
|
+static Constant *GetConstGep(Constant *Ptr, unsigned Idx0, unsigned Idx1) {
|
|
|
+ Type *i32Ty = Type::getInt32Ty(Ptr->getContext());
|
|
|
+ Constant *Indices[] = { ConstantInt::get(i32Ty, Idx0), ConstantInt::get(i32Ty, Idx1) };
|
|
|
+ return ConstantExpr::getGetElementPtr(nullptr, Ptr, Indices);
|
|
|
+}
|
|
|
+
|
|
|
static bool ShouldPreserve(Value *V) {
|
|
|
if (isa<Constant>(V)) return true;
|
|
|
if (isa<Argument>(V)) return true;
|
|
@@ -190,6 +196,14 @@ static void FindAllStores(Value *Ptr, std::vector<Store_Info> *Stores, std::vect
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static User *GetUniqueUser(Value *V) {
|
|
|
+ if (V->user_begin() != V->user_end()) {
|
|
|
+ if (std::next(V->user_begin()) == V->user_end())
|
|
|
+ return *V->user_begin();
|
|
|
+ }
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
static Value *GetOrCreatePreserveCond(Function *F) {
|
|
|
assert(!F->isDeclaration());
|
|
|
|
|
@@ -197,19 +211,24 @@ static Value *GetOrCreatePreserveCond(Function *F) {
|
|
|
GlobalVariable *GV = M->getGlobalVariable(kPreserveName, true);
|
|
|
if (!GV) {
|
|
|
Type *i32Ty = Type::getInt32Ty(M->getContext());
|
|
|
+ Type *i32ArrayTy = ArrayType::get(i32Ty, 1);
|
|
|
+
|
|
|
+ unsigned int Values[1] = { 0 };
|
|
|
+ Constant *InitialValue = llvm::ConstantDataArray::get(M->getContext(), Values);
|
|
|
+
|
|
|
GV = new GlobalVariable(*M,
|
|
|
- i32Ty, true,
|
|
|
+ i32ArrayTy, true,
|
|
|
llvm::GlobalValue::InternalLinkage,
|
|
|
- llvm::ConstantInt::get(i32Ty, 0), kPreserveName);
|
|
|
+ InitialValue, kPreserveName);
|
|
|
}
|
|
|
|
|
|
for (User *U : GV->users()) {
|
|
|
- LoadInst *LI = cast<LoadInst>(U);
|
|
|
- if (LI->getParent()->getParent() == F) {
|
|
|
- assert(LI->user_begin() != LI->user_end() &&
|
|
|
- std::next(LI->user_begin()) == LI->user_end());
|
|
|
-
|
|
|
- return *LI->user_begin();
|
|
|
+ GEPOperator *Gep = Gep = cast<GEPOperator>(U);
|
|
|
+ for (User *GepU : Gep->users()) {
|
|
|
+ LoadInst *LI = cast<LoadInst>(GepU);
|
|
|
+ if (LI->getParent()->getParent() == F) {
|
|
|
+ return GetUniqueUser(LI);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -220,7 +239,8 @@ static Value *GetOrCreatePreserveCond(Function *F) {
|
|
|
|
|
|
IRBuilder<> B(InsertPt);
|
|
|
|
|
|
- LoadInst *Load = B.CreateLoad(GV);
|
|
|
+ Constant *Gep = GetConstGep(GV, 0, 0);
|
|
|
+ LoadInst *Load = B.CreateLoad(Gep);
|
|
|
return B.CreateTrunc(Load, B.getInt1Ty());
|
|
|
}
|
|
|
|
|
@@ -461,18 +481,24 @@ public:
|
|
|
}
|
|
|
|
|
|
Instruction *GetFinalNoopInst(Module &M, Instruction *InsertBefore) {
|
|
|
+ Type *i32Ty = Type::getInt32Ty(M.getContext());
|
|
|
if (!NothingGV) {
|
|
|
NothingGV = M.getGlobalVariable(kNothingName);
|
|
|
if (!NothingGV) {
|
|
|
- Type *i32Ty = Type::getInt32Ty(M.getContext());
|
|
|
+ Type *i32ArrayTy = ArrayType::get(i32Ty, 1);
|
|
|
+
|
|
|
+ unsigned int Values[1] = { 0 };
|
|
|
+ Constant *InitialValue = llvm::ConstantDataArray::get(M.getContext(), Values);
|
|
|
+
|
|
|
NothingGV = new GlobalVariable(M,
|
|
|
- i32Ty, true,
|
|
|
+ i32ArrayTy, true,
|
|
|
llvm::GlobalValue::InternalLinkage,
|
|
|
- llvm::ConstantInt::get(i32Ty, 0), kNothingName);
|
|
|
+ InitialValue, kNothingName);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return new llvm::LoadInst(NothingGV, nullptr, InsertBefore);
|
|
|
+ Constant *Gep = GetConstGep(NothingGV, 0, 0);
|
|
|
+ return new llvm::LoadInst(Gep, nullptr, InsertBefore);
|
|
|
}
|
|
|
|
|
|
bool LowerPreserves(Module &M);
|
|
@@ -491,20 +517,23 @@ bool DxilFinalizePreserves::LowerPreserves(Module &M) {
|
|
|
GlobalVariable *GV = M.getGlobalVariable(kPreserveName, true);
|
|
|
if (GV) {
|
|
|
for (User *U : GV->users()) {
|
|
|
- LoadInst *LI = cast<LoadInst>(U);
|
|
|
- assert(LI->user_begin() != LI->user_end() &&
|
|
|
- std::next(LI->user_begin()) == LI->user_end());
|
|
|
- Instruction *I = cast<Instruction>(*LI->user_begin());
|
|
|
-
|
|
|
- for (User *UU : I->users()) {
|
|
|
-
|
|
|
- SelectInst *P = cast<SelectInst>(UU);
|
|
|
- Value *PrevV = P->getTrueValue();
|
|
|
- Value *CurV = P->getFalseValue();
|
|
|
-
|
|
|
- if (isa<UndefValue>(PrevV) || isa<Constant>(PrevV)) {
|
|
|
- P->setOperand(1, CurV);
|
|
|
- Changed = true;
|
|
|
+ GEPOperator *Gep = cast<GEPOperator>(U);
|
|
|
+ for (User *GepU : Gep->users()) {
|
|
|
+ LoadInst *LI = cast<LoadInst>(GepU);
|
|
|
+ assert(LI->user_begin() != LI->user_end() &&
|
|
|
+ std::next(LI->user_begin()) == LI->user_end());
|
|
|
+ Instruction *I = cast<Instruction>(*LI->user_begin());
|
|
|
+
|
|
|
+ for (User *UU : I->users()) {
|
|
|
+
|
|
|
+ SelectInst *P = cast<SelectInst>(UU);
|
|
|
+ Value *PrevV = P->getTrueValue();
|
|
|
+ Value *CurV = P->getFalseValue();
|
|
|
+
|
|
|
+ if (isa<UndefValue>(PrevV) || isa<Constant>(PrevV)) {
|
|
|
+ P->setOperand(1, CurV);
|
|
|
+ Changed = true;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|