summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRForTarget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Expression/IRForTarget.cpp')
-rw-r--r--lldb/source/Expression/IRForTarget.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp
index 31f3343d82e..e201117338b 100644
--- a/lldb/source/Expression/IRForTarget.cpp
+++ b/lldb/source/Expression/IRForTarget.cpp
@@ -162,6 +162,85 @@ PrintValue(llvm::Value *V, bool truncate = false)
return s;
}
+static bool isGuardVariableRef(llvm::Value *V)
+{
+ ConstantExpr *C = dyn_cast<ConstantExpr>(V);
+
+ if (!C || C->getOpcode() != Instruction::BitCast)
+ return false;
+
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(C->getOperand(0));
+
+ if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
+ return false;
+
+ return true;
+}
+
+static void TurnGuardLoadIntoZero(Instruction* guard_load, Module &M)
+{
+ Constant* zero(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0, true));
+
+ Value::use_iterator ui;
+
+ for (ui = guard_load->use_begin();
+ ui != guard_load->use_end();
+ ++ui)
+ ui->replaceUsesOfWith(guard_load, zero);
+
+ guard_load->eraseFromParent();
+}
+
+static void ExciseGuardStore(Instruction* guard_store)
+{
+ guard_store->eraseFromParent();
+}
+
+bool
+IRForTarget::removeGuards(Module &M, BasicBlock &BB)
+{
+ ///////////////////////////////////////////////////////
+ // Eliminate any reference to guard variables found.
+ //
+
+ llvm::BasicBlock::iterator ii;
+
+ typedef llvm::SmallVector <Instruction*, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
+
+ InstrList guard_loads;
+ InstrList guard_stores;
+
+ for (ii = BB.begin();
+ ii != BB.end();
+ ++ii)
+ {
+ Instruction &inst = *ii;
+
+ if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (isGuardVariableRef(load->getPointerOperand()))
+ guard_loads.push_back(&inst);
+
+ if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+ if (isGuardVariableRef(store->getPointerOperand()))
+ guard_stores.push_back(&inst);
+ }
+
+ InstrIterator iter;
+
+ for (iter = guard_loads.begin();
+ iter != guard_loads.end();
+ ++iter)
+ TurnGuardLoadIntoZero(*iter, M);
+
+ for (iter = guard_stores.begin();
+ iter != guard_stores.end();
+ ++iter)
+ ExciseGuardStore(*iter);
+
+ return true;
+}
+
// UnfoldConstant operates on a constant [C] which has just been replaced with a value
// [new_value]. We assume that new_value has been properly placed early in the function,
// most likely somewhere in front of the first instruction in the entry basic block
@@ -363,6 +442,9 @@ IRForTarget::runOnModule(Module &M)
{
if (!runOnBasicBlock(M, *bbi))
return false;
+
+ if (!removeGuards(M, *bbi))
+ return false;
}
if (!replaceVariables(M, function))
OpenPOWER on IntegriCloud