[PATCH] IRBuilder: Allow retrieval of the inserted instructions
Hal Finkel
hfinkel at anl.gov
Wed Feb 4 18:14:28 PST 2015
----- Original Message -----
> From: "Adam Nemet" <anemet at apple.com>
> To: anemet at apple.com, hfinkel at anl.gov, nrotem at apple.com, aschwaighofer at apple.com, chandlerc at gmail.com
> Cc: llvm-commits at cs.uiuc.edu
> Sent: Wednesday, February 4, 2015 5:58:45 PM
> Subject: [PATCH] IRBuilder: Allow retrieval of the inserted instructions
>
> Hi hfinkel, nadav, aschwaighofer, chandlerc,
>
> This is an RFC.
>
> When the Loop Vectorizer builds the instruction sequence for checks
> it tries
> to determine the first instruction that was emitted in the current
> block.
> This is then used to split the block.
Silly question: Why don't we split the block first?
-Hal
>
> It uses a custom solution for this implemented in the static function
> getFirstInst. The pattern is something like:
>
> Value *V = IRBuilder.CreateBlah(...);
> FirstInst = getFirstInst(FirstInst, V, Loc)
> Value *V2 = IRBuilder.CreateBlah(...);
> FirstInst = getFirstInst(FirstInst, V2, Loc);
>
> (Since CreateBlah may return a constant we may not generate the first
> instruction for V.)
>
> For the LoopAccessAnalysis work I need this to be made global so I
> was
> thinking how to make it more generic. My idea was to change the
> approach and
> rather than repeatedly checking whether we had emitted the first
> instruction,
> remember the predecessor of the insertion point in the IRBuilder.
> Subsequently, when the first emitted instruction is queried I return
> the
> successor of the saved predecessor instruction.
>
> Conceptually:
>
> IRBuilder<>::Marker Mark(IRBuilder.getInsertPoint());
>
> marks the next instruction that will be inserted at the current
> insertion
> point. After inserting instructions into IRBuilder, you can retrieve
> the
> first instruction inserted with Mark.get() (perhaps Mark.first()
> would be a
> better name).
>
> The patch also contains the changes to make use of this in LV and
> then asserts
> that the new result is at least as good as the one from getFirstInst.
> The
> assert does not fail on things I tried so far.
>
> I went back and forth on this but I think it's better to associate
> the marker
> with an insertion point rather than the IRBuilder instance itself. I
> had two
> reasons to go this way:
>
> 1. The insertion point can be adjusted manually in the IRBuilder.
> This makes
> it more obvious that the marker is associated with the original
> insertion
> point after a change.
>
> 2. The behavior is more intuitive with nested IRBuilders.
>
> For example in the LV code that I am changing we should really move
> the marker
> earlier to also cover the SCEV expansion of the array bounds. Those
> instructions are however inserted via an implicit IRBuilder inside
> SCEV
> expansion. The good thing is that the marker as written sees these
> because of
> the shared insertion point.
>
> The patch is still missing unit tests but wanted to float the idea
> before I
> get too carried away. Is this a reasonable idea? Are there other
> issues I am
> missing?
>
> http://reviews.llvm.org/D7421
>
> Files:
> include/llvm/IR/IRBuilder.h
> lib/Transforms/Vectorize/LoopVectorize.cpp
>
> Index: include/llvm/IR/IRBuilder.h
> ===================================================================
> --- include/llvm/IR/IRBuilder.h
> +++ include/llvm/IR/IRBuilder.h
> @@ -188,6 +188,24 @@
> /// \brief Set the fast-math flags to be used with generated
> fp-math operators
> void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
>
> + class Marker {
> + BasicBlock::iterator Prev;
> + BasicBlock *BB;
> + public:
> + Marker(BasicBlock::iterator InsertionPoint) : BB(nullptr) {
> + if (InsertionPoint == InsertionPoint->getParent()->begin())
> + BB = InsertionPoint->getParent();
> + else
> + Prev = std::prev(InsertionPoint);
> + }
> + BasicBlock::iterator get() const {
> + if (BB)
> + return BB->begin();
> + else
> + return std::next(Prev);
> + }
> + };
> +
> //===--------------------------------------------------------------------===//
> // RAII helpers.
> //===--------------------------------------------------------------------===//
> Index: lib/Transforms/Vectorize/LoopVectorize.cpp
> ===================================================================
> --- lib/Transforms/Vectorize/LoopVectorize.cpp
> +++ lib/Transforms/Vectorize/LoopVectorize.cpp
> @@ -2050,6 +2050,8 @@
> }
>
> IRBuilder<> ChkBuilder(Loc);
> + IRBuilder<>::Marker BeforeInsertionMarker(Loc);
> +
> // Our instructions might fold to a constant.
> Value *MemoryRuntimeCheck = nullptr;
> for (unsigned i = 0; i < NumPointers; ++i) {
> @@ -2102,6 +2104,14 @@
> ConstantInt::getTrue(Ctx));
> ChkBuilder.Insert(Check, "memcheck.conflict");
> FirstInst = getFirstInst(FirstInst, Check, Loc);
> +
> + Instruction *AnotherFirst = BeforeInsertionMarker.get();
> + assert(std::find_if(BasicBlock::iterator(AnotherFirst),
> + Loc->getParent()->end(),
> + [&](Instruction &I) {
> + return &I == FirstInst;
> + }) != Loc->getParent()->end());
> +
> return std::make_pair(FirstInst, Check);
> }
>
> EMAIL PREFERENCES
> http://reviews.llvm.org/settings/panel/emailpreferences/
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-commits
mailing list