summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp27
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp59
2 files changed, 64 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index eaccaa1c4ac..94edf8ccab8 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -485,15 +485,19 @@ void llvm::RecursivelyDeleteTriviallyDeadInstructions(
I.eraseFromParent();
}
}
+void llvm::setDbgVariableUndef(DbgVariableIntrinsic *DVI) {
+ Value *DbgValue = DVI->getVariableLocation(false);
+ Value *Undef = UndefValue::get(DbgValue ? DbgValue->getType()
+ : Type::getInt1Ty(DVI->getContext()));
+ DVI->setOperand(
+ 0, MetadataAsValue::get(DVI->getContext(), ValueAsMetadata::get(Undef)));
+}
bool llvm::replaceDbgUsesWithUndef(Instruction *I) {
SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
findDbgUsers(DbgUsers, I);
- for (auto *DII : DbgUsers) {
- Value *Undef = UndefValue::get(I->getType());
- DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
- ValueAsMetadata::get(Undef)));
- }
+ for (auto *DII : DbgUsers)
+ setDbgVariableUndef(DII);
return !DbgUsers.empty();
}
@@ -1040,6 +1044,19 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
assert(PN->use_empty() && "There shouldn't be any uses here!");
PN->eraseFromParent();
}
+ // If Succ has multiple predecessors, each debug intrinsic in BB may or may
+ // not be valid when we reach Succ, so the debug variable should be set
+ // undef since its value is unknown.
+ Instruction *DbgInsertPoint = Succ->getFirstNonPHI();
+ while (DbgInfoIntrinsic *DI = dyn_cast<DbgInfoIntrinsic>(&BB->front())) {
+ if (auto DVI = cast<DbgVariableIntrinsic>(DI)) {
+ if (!isa<DbgDeclareInst>(DVI))
+ setDbgVariableUndef(DVI);
+ DVI->moveBefore(DbgInsertPoint);
+ } else {
+ break;
+ }
+ }
}
// If the unconditional branch we replaced contains llvm.loop metadata, we
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 79d4857c2c8..0e74a26987c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h"
@@ -38,6 +39,7 @@
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
@@ -1250,14 +1252,38 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
Instruction *I1 = &*BB1_Itr++, *I2 = &*BB2_Itr++;
// Skip debug info if it is not identical.
- DbgInfoIntrinsic *DBI1 = dyn_cast<DbgInfoIntrinsic>(I1);
- DbgInfoIntrinsic *DBI2 = dyn_cast<DbgInfoIntrinsic>(I2);
- if (!DBI1 || !DBI2 || !DBI1->isIdenticalToWhenDefined(DBI2)) {
- while (isa<DbgInfoIntrinsic>(I1))
- I1 = &*BB1_Itr++;
- while (isa<DbgInfoIntrinsic>(I2))
- I2 = &*BB2_Itr++;
- }
+
+ // If the terminator instruction is hoisted, and any variable locations have
+ // non-identical debug intrinsics, then those variable locations must be set
+ // as undef.
+ // FIXME: If each block contains identical debug variable intrinsics in a
+ // different order, they will be considered non-identical and be dropped.
+ MapVector<DebugVariable, DbgVariableIntrinsic *> UndefDVIs;
+
+ auto SkipDbgInfo = [&UndefDVIs](Instruction *&I,
+ BasicBlock::iterator &BB_Itr) {
+ while (isa<DbgInfoIntrinsic>(I)) {
+ if (DbgVariableIntrinsic *DVI = dyn_cast<DbgVariableIntrinsic>(I))
+ UndefDVIs.insert(
+ {DebugVariable(DVI->getVariable(), DVI->getExpression(),
+ DVI->getDebugLoc()->getInlinedAt()),
+ DVI});
+ I = &*BB_Itr++;
+ }
+ };
+
+ auto SkipNonIdenticalDbgInfo =
+ [&BB1_Itr, &BB2_Itr, &SkipDbgInfo](Instruction *&I1, Instruction *&I2) {
+ DbgInfoIntrinsic *DBI1 = dyn_cast<DbgInfoIntrinsic>(I1);
+ DbgInfoIntrinsic *DBI2 = dyn_cast<DbgInfoIntrinsic>(I2);
+ if (!DBI1 || !DBI2 || !DBI1->isIdenticalToWhenDefined(DBI2)) {
+ SkipDbgInfo(I1, BB1_Itr);
+ SkipDbgInfo(I2, BB2_Itr);
+ }
+ };
+
+ SkipNonIdenticalDbgInfo(I1, I2);
+
// FIXME: Can we define a safety predicate for CallBr?
if (isa<PHINode>(I1) || !I1->isIdenticalToWhenDefined(I2) ||
(isa<InvokeInst>(I1) && !isSafeToHoistInvoke(BB1, BB2, I1, I2)) ||
@@ -1330,15 +1356,7 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
I1 = &*BB1_Itr++;
I2 = &*BB2_Itr++;
- // Skip debug info if it is not identical.
- DbgInfoIntrinsic *DBI1 = dyn_cast<DbgInfoIntrinsic>(I1);
- DbgInfoIntrinsic *DBI2 = dyn_cast<DbgInfoIntrinsic>(I2);
- if (!DBI1 || !DBI2 || !DBI1->isIdenticalToWhenDefined(DBI2)) {
- while (isa<DbgInfoIntrinsic>(I1))
- I1 = &*BB1_Itr++;
- while (isa<DbgInfoIntrinsic>(I2))
- I2 = &*BB2_Itr++;
- }
+ SkipNonIdenticalDbgInfo(I1, I2);
} while (I1->isIdenticalToWhenDefined(I2));
return true;
@@ -1374,6 +1392,13 @@ HoistTerminator:
}
// Okay, it is safe to hoist the terminator.
+ for (auto DIVariableInst : UndefDVIs) {
+ DbgVariableIntrinsic *DVI = DIVariableInst.second;
+ DVI->moveBefore(BI);
+ if (Value *V = DVI->getVariableLocation())
+ setDbgVariableUndef(DVI);
+ }
+
Instruction *NT = I1->clone();
BIParent->getInstList().insert(BI->getIterator(), NT);
if (!NT->getType()->isVoidTy()) {
OpenPOWER on IntegriCloud