summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/AutoUpgrade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r--llvm/lib/IR/AutoUpgrade.cpp53
1 files changed, 52 insertions, 1 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index bbb8462652c..b4f327bab5c 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -17,6 +17,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
@@ -106,6 +107,20 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
}
+ case 'd': {
+ if (Name.startswith("dbg.declare") && F->arg_size() == 2) {
+ F->setName(Name + ".old");
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_declare);
+ return true;
+ }
+ if (Name.startswith("dbg.value") && F->arg_size() == 3) {
+ F->setName(Name + ".old");
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value);
+ return true;
+ }
+ break;
+ }
+
case 'o':
// We only need to change the name to match the mangling including the
// address space.
@@ -239,6 +254,22 @@ bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
return false;
}
+static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {
+ if (!DbgNode || Elt >= DbgNode->getNumOperands())
+ return nullptr;
+ return dyn_cast_or_null<MDNode>(DbgNode->getOperand(Elt));
+}
+
+static DIExpression getExpression(Value *VarOperand, Function *F) {
+ // Old-style DIVariables have an optional expression as the 8th element.
+ DIExpression Expr(getNodeField(cast<MDNode>(VarOperand), 8));
+ if (!Expr) {
+ DIBuilder DIB(*F->getParent());
+ Expr = DIB.createExpression();
+ }
+ return Expr;
+}
+
// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
// upgraded intrinsic. All argument and return casting must be provided in
// order to seamlessly integrate with existing context.
@@ -402,12 +433,32 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
}
std::string Name = CI->getName().str();
- CI->setName(Name + ".old");
+ if (!Name.empty())
+ CI->setName(Name + ".old");
switch (NewFn->getIntrinsicID()) {
default:
llvm_unreachable("Unknown function for CallInst upgrade.");
+ // Upgrade debug intrinsics to use an additional DIExpression argument.
+ case Intrinsic::dbg_declare: {
+ auto NewCI =
+ Builder.CreateCall3(NewFn, CI->getArgOperand(0), CI->getArgOperand(1),
+ getExpression(CI->getArgOperand(1), F), Name);
+ NewCI->setDebugLoc(CI->getDebugLoc());
+ CI->replaceAllUsesWith(NewCI);
+ CI->eraseFromParent();
+ return;
+ }
+ case Intrinsic::dbg_value: {
+ auto NewCI = Builder.CreateCall4(
+ NewFn, CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
+ getExpression(CI->getArgOperand(2), F), Name);
+ NewCI->setDebugLoc(CI->getDebugLoc());
+ CI->replaceAllUsesWith(NewCI);
+ CI->eraseFromParent();
+ return;
+ }
case Intrinsic::ctlz:
case Intrinsic::cttz:
assert(CI->getNumArgOperands() == 1 &&
OpenPOWER on IntegriCloud