[llvm] r335083 - [IR] Introduce helpers to skip debug instructions (NFC)
Vedant Kumar via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 19 16:42:17 PDT 2018
Author: vedantk
Date: Tue Jun 19 16:42:17 2018
New Revision: 335083
URL: http://llvm.org/viewvc/llvm-project?rev=335083&view=rev
Log:
[IR] Introduce helpers to skip debug instructions (NFC)
This patch introduces two helpers to make it easier to ignore debug
intrinsics:
- Instruction::getNextNonDebugInstruction()
This is just like Instruction::getNextNode(), except that it skips debug
info.
- skipDebugInfo(BasicBlock::iterator)
A free function which advances a BasicBlock iterator past any debug
info. This is a no-op when the iterator already points to a non-debug
instruction.
Part of: llvm.org/PR37728
Related to: https://reviews.llvm.org/D47874
Differential Revision: https://reviews.llvm.org/D48305
Modified:
llvm/trunk/include/llvm/IR/BasicBlock.h
llvm/trunk/include/llvm/IR/Instruction.h
llvm/trunk/lib/IR/BasicBlock.cpp
llvm/trunk/lib/IR/Instruction.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/trunk/unittests/IR/InstructionsTest.cpp
Modified: llvm/trunk/include/llvm/IR/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=335083&r1=335082&r2=335083&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/IR/BasicBlock.h Tue Jun 19 16:42:17 2018
@@ -433,6 +433,10 @@ private:
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
+/// Advance \p It while it points to a debug instruction and return the result.
+/// This assumes that \p It is not at the end of a block.
+BasicBlock::iterator skipDebugInfo(BasicBlock::iterator It);
+
} // end namespace llvm
#endif // LLVM_IR_BASICBLOCK_H
Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=335083&r1=335082&r2=335083&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Tue Jun 19 16:42:17 2018
@@ -556,6 +556,14 @@ public:
}
}
+ /// Return a pointer to the next non-debug instruction in the same basic
+ /// block as 'this', or nullptr if no such instruction exists.
+ const Instruction *getNextNonDebugInstruction() const;
+ Instruction *getNextNonDebugInstruction() {
+ return const_cast<Instruction *>(
+ static_cast<const Instruction *>(this)->getNextNonDebugInstruction());
+ }
+
/// Create a copy of 'this' instruction that is identical in all ways except
/// the following:
/// * The instruction has no parent
Modified: llvm/trunk/lib/IR/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=335083&r1=335082&r2=335083&view=diff
==============================================================================
--- llvm/trunk/lib/IR/BasicBlock.cpp (original)
+++ llvm/trunk/lib/IR/BasicBlock.cpp Tue Jun 19 16:42:17 2018
@@ -479,3 +479,9 @@ Optional<uint64_t> BasicBlock::getIrrLoo
}
return Optional<uint64_t>();
}
+
+BasicBlock::iterator llvm::skipDebugInfo(BasicBlock::iterator It) {
+ while (isa<DbgInfoIntrinsic>(It))
+ ++It;
+ return It;
+}
Modified: llvm/trunk/lib/IR/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instruction.cpp?rev=335083&r1=335082&r2=335083&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instruction.cpp (original)
+++ llvm/trunk/lib/IR/Instruction.cpp Tue Jun 19 16:42:17 2018
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
@@ -594,6 +595,13 @@ bool Instruction::isSafeToRemove() const
!isa<TerminatorInst>(this);
}
+const Instruction *Instruction::getNextNonDebugInstruction() const {
+ for (const Instruction *I = getNextNode(); I; I = I->getNextNode())
+ if (!isa<DbgInfoIntrinsic>(I))
+ return I;
+ return nullptr;
+}
+
bool Instruction::isAssociative() const {
unsigned Opcode = getOpcode();
if (isAssociative(Opcode))
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=335083&r1=335082&r2=335083&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Tue Jun 19 16:42:17 2018
@@ -3614,13 +3614,8 @@ Instruction *InstCombiner::visitCallInst
// happen when variable allocas are DCE'd.
if (IntrinsicInst *SS = dyn_cast<IntrinsicInst>(II->getArgOperand(0))) {
if (SS->getIntrinsicID() == Intrinsic::stacksave) {
- // Skip over debug info instructions.
- // FIXME: This should be an utility in Instruction.h
- auto It = SS->getIterator();
- It++;
- while (isa<DbgInfoIntrinsic>(*It))
- It++;
- if (&*It == II) {
+ // Skip over debug info.
+ if (SS->getNextNonDebugInstruction() == II) {
return eraseInstFromFunction(CI);
}
}
@@ -3804,10 +3799,7 @@ Instruction *InstCombiner::visitCallInst
// Fence instruction simplification
Instruction *InstCombiner::visitFenceInst(FenceInst &FI) {
// Remove identical consecutive fences.
- Instruction *Next = FI.getNextNode();
- while (Next != nullptr && isa<DbgInfoIntrinsic>(Next))
- Next = Next->getNextNode();
-
+ Instruction *Next = FI.getNextNonDebugInstruction();
if (auto *NFI = dyn_cast<FenceInst>(Next))
if (FI.isIdenticalTo(NFI))
return eraseInstFromFunction(FI);
Modified: llvm/trunk/unittests/IR/InstructionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/InstructionsTest.cpp?rev=335083&r1=335082&r2=335083&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/InstructionsTest.cpp (original)
+++ llvm/trunk/unittests/IR/InstructionsTest.cpp Tue Jun 19 16:42:17 2018
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Instructions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -21,6 +22,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Operator.h"
+#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"
#include <memory>
@@ -28,6 +30,14 @@
namespace llvm {
namespace {
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+ if (!Mod)
+ Err.print("InstructionsTests", errs());
+ return Mod;
+}
+
TEST(InstructionsTest, ReturnInst) {
LLVMContext C;
@@ -829,5 +839,44 @@ TEST(InstructionsTest, ShuffleMaskQuerie
EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(ConstantVector::get({C1, C3})));
}
+TEST(InstructionsTest, SkipDebug) {
+ LLVMContext C;
+ std::unique_ptr<Module> M = parseIR(C,
+ R"(
+ declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+ define void @f() {
+ entry:
+ call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !13
+ ret void
+ }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!3, !4}
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "t2.c", directory: "foo")
+ !2 = !{}
+ !3 = !{i32 2, !"Dwarf Version", i32 4}
+ !4 = !{i32 2, !"Debug Info Version", i32 3}
+ !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
+ !9 = !DISubroutineType(types: !10)
+ !10 = !{null}
+ !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
+ !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !13 = !DILocation(line: 2, column: 7, scope: !8)
+ )");
+ ASSERT_TRUE(M);
+ Function *F = cast<Function>(M->getNamedValue("f"));
+ BasicBlock &BB = F->front();
+
+ // The first non-debug instruction is the terminator.
+ auto *Term = BB.getTerminator();
+ EXPECT_EQ(Term, BB.begin()->getNextNonDebugInstruction());
+ EXPECT_EQ(Term->getIterator(), skipDebugInfo(BB.begin()));
+
+ // After the terminator, there are no non-debug instructions.
+ EXPECT_EQ(nullptr, Term->getNextNonDebugInstruction());
+}
+
} // end anonymous namespace
} // end namespace llvm
More information about the llvm-commits
mailing list