IRBuilder: Add RAII objects to reset insertion points or fast math flags.

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
This commit is contained in:
Benjamin Kramer 2013-09-30 15:39:48 +00:00
parent 5a17a462cd
commit adb412daa4
4 changed files with 86 additions and 22 deletions

View File

@ -25,6 +25,7 @@
#include "llvm/IR/Operator.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/ConstantFolder.h"
#include "llvm/Support/ValueHandle.h"
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; }
//===--------------------------------------------------------------------===//
// 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.
//===--------------------------------------------------------------------===//

View File

@ -65,26 +65,6 @@ static const unsigned MinVecRegSize = 128;
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 {
@ -1177,7 +1157,7 @@ Value *BoUpSLP::vectorizeTree(ArrayRef<Value *> VL) {
}
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");

View 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: ![[LOC2]] = metadata !{i32 8, i32 0,
;CHECK: ![[LOC2]] = metadata !{i32 7, i32 0,
define i32 @depth(double* nocapture %A, i32 %m) #0 {
entry:

View 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());
}
}