IRBuilder: Add RAII objects to reset insertion points or fast math flags.
authorBenjamin Kramer <benny.kra@googlemail.com>
Mon, 30 Sep 2013 15:39:48 +0000 (15:39 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Mon, 30 Sep 2013 15:39:48 +0000 (15:39 +0000)
Inspired by the object from the SLPVectorizer. This found a minor bug in the
debug loc restoration in the vectorizer where the location of a following
instruction was attached instead of the location from the original instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191673 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/IRBuilder.h
lib/Transforms/Vectorize/SLPVectorizer.cpp
test/Transforms/SLPVectorizer/X86/debug_info.ll
unittests/IR/IRBuilderTest.cpp

index 458f87a88f4b0086abaa61b77b92c4b48cd66cae..0adfbc40d554dea96bb5cc23550570821b93a6ff 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/IR/Operator.h"
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/ConstantFolder.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/ConstantFolder.h"
+#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
   class MDNode;
 
 namespace llvm {
   class MDNode;
@@ -187,6 +188,53 @@ public:
   /// \brief Set the fast-math flags to be used with generated fp-math operators
   void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
 
   /// \brief Set the fast-math flags to be used with generated fp-math operators
   void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
 
+  //===--------------------------------------------------------------------===//
+  // RAII helpers.
+  //===--------------------------------------------------------------------===//
+
+  // \brief RAII object that stores the current insertion point and restores it
+  // when the object is destroyed. This includes the debug location.
+  class InsertPointGuard {
+    IRBuilderBase &Builder;
+    AssertingVH<BasicBlock> Block;
+    AssertingVH<Instruction> Point;
+    DebugLoc DbgLoc;
+
+    InsertPointGuard(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
+    InsertPointGuard &operator=(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
+
+  public:
+    InsertPointGuard(IRBuilderBase &B)
+        : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()),
+          DbgLoc(B.getCurrentDebugLocation()) {}
+
+    ~InsertPointGuard() {
+      Builder.restoreIP(InsertPoint(Block, BasicBlock::iterator(Point)));
+      Builder.SetCurrentDebugLocation(DbgLoc);
+    }
+  };
+
+  // \brief RAII object that stores the current fast math settings and restores
+  // them when the object is destroyed.
+  class FastMathFlagGuard {
+    IRBuilderBase &Builder;
+    FastMathFlags FMF;
+    MDNode *FPMathTag;
+
+    FastMathFlagGuard(const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
+    FastMathFlagGuard &operator=(
+        const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
+
+  public:
+    FastMathFlagGuard(IRBuilderBase &B)
+        : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {}
+
+    ~FastMathFlagGuard() {
+      Builder.FMF = FMF;
+      Builder.DefaultFPMathTag = FPMathTag;
+    }
+  };
+
   //===--------------------------------------------------------------------===//
   // Miscellaneous creation methods.
   //===--------------------------------------------------------------------===//
   //===--------------------------------------------------------------------===//
   // Miscellaneous creation methods.
   //===--------------------------------------------------------------------===//
index 2b0bdfafc4149e27c2a1ca396940b25d1e58cfb4..c8c8ba51b7e1aaeee0a7604dc9b8640075b63f08 100644 (file)
@@ -65,26 +65,6 @@ static const unsigned MinVecRegSize = 128;
 
 static const unsigned RecursionMaxDepth = 12;
 
 
 static const unsigned RecursionMaxDepth = 12;
 
-/// RAII pattern to save the insertion point of the IR builder.
-class BuilderLocGuard {
-public:
-  BuilderLocGuard(IRBuilder<> &B) : Builder(B), Loc(B.GetInsertPoint()),
-  DbgLoc(B.getCurrentDebugLocation()) {}
-  ~BuilderLocGuard() {
-    Builder.SetCurrentDebugLocation(DbgLoc);
-    if (Loc)
-      Builder.SetInsertPoint(Loc);
-  }
-
-private:
-  // Prevent copying.
-  BuilderLocGuard(const BuilderLocGuard &);
-  BuilderLocGuard &operator=(const BuilderLocGuard &);
-  IRBuilder<> &Builder;
-  AssertingVH<Instruction> Loc;
-  DebugLoc DbgLoc;
-};
-
 /// A helper class for numbering instructions in multiple blocks.
 /// Numbers start at zero for each basic block.
 struct BlockNumbering {
 /// A helper class for numbering instructions in multiple blocks.
 /// Numbers start at zero for each basic block.
 struct BlockNumbering {
@@ -1177,7 +1157,7 @@ Value *BoUpSLP::vectorizeTree(ArrayRef<Value *> VL) {
 }
 
 Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
 }
 
 Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
-  BuilderLocGuard Guard(Builder);
+  IRBuilder<>::InsertPointGuard Guard(Builder);
 
   if (E->VectorizedValue) {
     DEBUG(dbgs() << "SLP: Diamond merged for " << *E->Scalars[0] << ".\n");
 
   if (E->VectorizedValue) {
     DEBUG(dbgs() << "SLP: Diamond merged for " << *E->Scalars[0] << ".\n");
index b3a6f6dc3c54c9343d33b3d59acacea9dad67462..97704d08c49378b70677ec5e8e45304fc566688a 100644 (file)
@@ -19,7 +19,7 @@ target triple = "x86_64-apple-macosx10.7.0"
 ;CHECK: store <2 x double> {{.*}}, !dbg ![[LOC2:[0-9]+]]
 ;CHECK: ret
 ;CHECK: ![[LOC]] = metadata !{i32 4, i32 0,
 ;CHECK: store <2 x double> {{.*}}, !dbg ![[LOC2:[0-9]+]]
 ;CHECK: ret
 ;CHECK: ![[LOC]] = metadata !{i32 4, i32 0,
-;CHECK: ![[LOC2]] = metadata !{i32 8, i32 0,
+;CHECK: ![[LOC2]] = metadata !{i32 7, i32 0,
 
 define i32 @depth(double* nocapture %A, i32 %m) #0 {
 entry:
 
 define i32 @depth(double* nocapture %A, i32 %m) #0 {
 entry:
index fecc4a4fe6b4121500fc5b361c392e9431e6a010..d79ff62b19d869175d65905473e4cbf9fdb8381a 100644 (file)
@@ -182,4 +182,40 @@ TEST_F(IRBuilderTest, FastMathFlags) {
 
 }
 
 
 }
 
+TEST_F(IRBuilderTest, RAIIHelpersTest) {
+  IRBuilder<> Builder(BB);
+  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
+  MDBuilder MDB(M->getContext());
+
+  MDNode *FPMathA = MDB.createFPMath(0.01);
+  MDNode *FPMathB = MDB.createFPMath(0.1);
+
+  Builder.SetDefaultFPMathTag(FPMathA);
+
+  {
+    IRBuilder<>::FastMathFlagGuard Guard(Builder);
+    FastMathFlags FMF;
+    FMF.setAllowReciprocal();
+    Builder.SetFastMathFlags(FMF);
+    Builder.SetDefaultFPMathTag(FPMathB);
+    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
+    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
+  }
+
+  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
+  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());
+
+  Value *F = Builder.CreateLoad(GV);
+
+  {
+    IRBuilder<>::InsertPointGuard Guard(Builder);
+    Builder.SetInsertPoint(cast<Instruction>(F));
+    EXPECT_EQ(F, Builder.GetInsertPoint());
+  }
+
+  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
+  EXPECT_EQ(BB, Builder.GetInsertBlock());
+}
+
+
 }
 }