Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 5c6b7fe

Browse files
authored
Merge pull request #106 from dotdash/jt_assume
Backport fixes for JumpThreading/assume bug
2 parents 4d4f5d0 + 3dd7de0 commit 5c6b7fe

File tree

18 files changed

+1431
-100
lines changed

18 files changed

+1431
-100
lines changed

include/llvm/Analysis/LazyValueInfo.h

+7
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ class LazyValueInfo {
113113
/// in LVI, so we need to pass it here as an argument.
114114
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
115115

116+
/// Disables use of the DominatorTree within LVI.
117+
void disableDT();
118+
119+
/// Enables use of the DominatorTree within LVI. Does nothing if the class
120+
/// instance was initialized without a DT pointer.
121+
void enableDT();
122+
116123
// For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
117124
void releaseMemory();
118125

include/llvm/IR/Dominators.h

+87
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,93 @@ class DominatorTreeWrapperPass : public FunctionPass {
290290
void print(raw_ostream &OS, const Module *M = nullptr) const override;
291291
};
292292

293+
//===-------------------------------------
294+
/// \brief Class to defer updates to a DominatorTree.
295+
///
296+
/// Definition: Applying updates to every edge insertion and deletion is
297+
/// expensive and not necessary. When one needs the DominatorTree for analysis
298+
/// they can request a flush() to perform a larger batch update. This has the
299+
/// advantage of the DominatorTree inspecting the set of updates to find
300+
/// duplicates or unnecessary subtree updates.
301+
///
302+
/// The scope of DeferredDominance operates at a Function level.
303+
///
304+
/// It is not necessary for the user to scrub the updates for duplicates or
305+
/// updates that point to the same block (Delete, BB_A, BB_A). Performance
306+
/// can be gained if the caller attempts to batch updates before submitting
307+
/// to applyUpdates(ArrayRef) in cases where duplicate edge requests will
308+
/// occur.
309+
///
310+
/// It is required for the state of the LLVM IR to be applied *before*
311+
/// submitting updates. The update routines must analyze the current state
312+
/// between a pair of (From, To) basic blocks to determine if the update
313+
/// needs to be queued.
314+
/// Example (good):
315+
/// TerminatorInstructionBB->removeFromParent();
316+
/// DDT->deleteEdge(BB, Successor);
317+
/// Example (bad):
318+
/// DDT->deleteEdge(BB, Successor);
319+
/// TerminatorInstructionBB->removeFromParent();
320+
class DeferredDominance {
321+
public:
322+
DeferredDominance(DominatorTree &DT_) : DT(DT_) {}
323+
324+
/// \brief Queues multiple updates and discards duplicates.
325+
void applyUpdates(ArrayRef<DominatorTree::UpdateType> Updates);
326+
327+
/// \brief Helper method for a single edge insertion. It's almost always
328+
/// better to batch updates and call applyUpdates to quickly remove duplicate
329+
/// edges. This is best used when there is only a single insertion needed to
330+
/// update Dominators.
331+
void insertEdge(BasicBlock *From, BasicBlock *To);
332+
333+
/// \brief Helper method for a single edge deletion. It's almost always better
334+
/// to batch updates and call applyUpdates to quickly remove duplicate edges.
335+
/// This is best used when there is only a single deletion needed to update
336+
/// Dominators.
337+
void deleteEdge(BasicBlock *From, BasicBlock *To);
338+
339+
/// \brief Delays the deletion of a basic block until a flush() event.
340+
void deleteBB(BasicBlock *DelBB);
341+
342+
/// \brief Returns true if DelBB is awaiting deletion at a flush() event.
343+
bool pendingDeletedBB(BasicBlock *DelBB);
344+
345+
/// \brief Returns true if pending DT updates are queued for a flush() event.
346+
bool pending();
347+
348+
/// \brief Flushes all pending updates and block deletions. Returns a
349+
/// correct DominatorTree reference to be used by the caller for analysis.
350+
DominatorTree &flush();
351+
352+
/// \brief Drops all internal state and forces a (slow) recalculation of the
353+
/// DominatorTree based on the current state of the LLVM IR in F. This should
354+
/// only be used in corner cases such as the Entry block of F being deleted.
355+
void recalculate(Function &F);
356+
357+
/// \brief Debug method to help view the state of pending updates.
358+
LLVM_DUMP_METHOD void dump() const;
359+
360+
private:
361+
DominatorTree &DT;
362+
SmallVector<DominatorTree::UpdateType, 16> PendUpdates;
363+
SmallPtrSet<BasicBlock *, 8> DeletedBBs;
364+
365+
/// Apply an update (Kind, From, To) to the internal queued updates. The
366+
/// update is only added when determined to be necessary. Checks for
367+
/// self-domination, unnecessary updates, duplicate requests, and balanced
368+
/// pairs of requests are all performed. Returns true if the update is
369+
/// queued and false if it is discarded.
370+
bool applyUpdate(DominatorTree::UpdateKind Kind, BasicBlock *From,
371+
BasicBlock *To);
372+
373+
/// Performs all pending basic block deletions. We have to defer the deletion
374+
/// of these blocks until after the DominatorTree updates are applied. The
375+
/// internal workings of the DominatorTree code expect every update's From
376+
/// and To blocks to exist and to be a member of the same Function.
377+
bool flushDelBB();
378+
};
379+
293380
} // end namespace llvm
294381

295382
#endif // LLVM_IR_DOMINATORS_H

include/llvm/Transforms/Scalar/JumpThreading.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class BinaryOperator;
3434
class BranchInst;
3535
class CmpInst;
3636
class Constant;
37+
class DeferredDominance;
3738
class Function;
3839
class Instruction;
3940
class IntrinsicInst;
@@ -77,6 +78,7 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
7778
TargetLibraryInfo *TLI;
7879
LazyValueInfo *LVI;
7980
AliasAnalysis *AA;
81+
DeferredDominance *DDT;
8082
std::unique_ptr<BlockFrequencyInfo> BFI;
8183
std::unique_ptr<BranchProbabilityInfo> BPI;
8284
bool HasProfileData = false;
@@ -107,8 +109,8 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
107109

108110
// Glue for old PM.
109111
bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_,
110-
AliasAnalysis *AA_, bool HasProfileData_,
111-
std::unique_ptr<BlockFrequencyInfo> BFI_,
112+
AliasAnalysis *AA_, DeferredDominance *DDT_,
113+
bool HasProfileData_, std::unique_ptr<BlockFrequencyInfo> BFI_,
112114
std::unique_ptr<BranchProbabilityInfo> BPI_);
113115

114116
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);

include/llvm/Transforms/Utils/BasicBlockUtils.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace llvm {
2727

2828
class BlockFrequencyInfo;
2929
class BranchProbabilityInfo;
30+
class DeferredDominance;
3031
class DominatorTree;
3132
class Function;
3233
class Instruction;
@@ -38,7 +39,7 @@ class TargetLibraryInfo;
3839
class Value;
3940

4041
/// Delete the specified block, which must have no predecessors.
41-
void DeleteDeadBlock(BasicBlock *BB);
42+
void DeleteDeadBlock(BasicBlock *BB, DeferredDominance *DDT = nullptr);
4243

4344
/// We know that BB has one predecessor. If there are any single-entry PHI nodes
4445
/// in it, fold them away. This handles the case when all entries to the PHI

include/llvm/Transforms/Utils/Local.h

+13-7
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ struct SimplifyCFGOptions {
117117
/// conditions and indirectbr addresses this might make dead if
118118
/// DeleteDeadConditions is true.
119119
bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
120-
const TargetLibraryInfo *TLI = nullptr);
120+
const TargetLibraryInfo *TLI = nullptr,
121+
DeferredDominance *DDT = nullptr);
121122

122123
//===----------------------------------------------------------------------===//
123124
// Local dead code elimination.
@@ -171,18 +172,21 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB,
171172
///
172173
/// .. and delete the predecessor corresponding to the '1', this will attempt to
173174
/// recursively fold the 'and' to 0.
174-
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred);
175+
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
176+
DeferredDominance *DDT = nullptr);
175177

176178
/// BB is a block with one predecessor and its predecessor is known to have one
177179
/// successor (BB!). Eliminate the edge between them, moving the instructions in
178180
/// the predecessor into BB. This deletes the predecessor block.
179-
void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, DominatorTree *DT = nullptr);
181+
void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, DominatorTree *DT = nullptr,
182+
DeferredDominance *DDT = nullptr);
180183

181184
/// BB is known to contain an unconditional branch, and contains no instructions
182185
/// other than PHI nodes, potential debug intrinsics and the branch. If
183186
/// possible, eliminate BB by rewriting all the predecessors to branch to the
184187
/// successor block and return true. If we can't transform, return false.
185-
bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB);
188+
bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
189+
DeferredDominance *DDT = nullptr);
186190

187191
/// Check for and eliminate duplicate PHI nodes in this block. This doesn't try
188192
/// to be clever about PHI nodes which differ only in the order of the incoming
@@ -382,7 +386,8 @@ unsigned removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB);
382386
/// Insert an unreachable instruction before the specified
383387
/// instruction, making it and the rest of the code in the block dead.
384388
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap,
385-
bool PreserveLCSSA = false);
389+
bool PreserveLCSSA = false,
390+
DeferredDominance *DDT = nullptr);
386391

387392
/// Convert the CallInst to InvokeInst with the specified unwind edge basic
388393
/// block. This also splits the basic block where CI is located, because
@@ -397,12 +402,13 @@ BasicBlock *changeToInvokeAndSplitBasicBlock(CallInst *CI,
397402
///
398403
/// \param BB Block whose terminator will be replaced. Its terminator must
399404
/// have an unwind successor.
400-
void removeUnwindEdge(BasicBlock *BB);
405+
void removeUnwindEdge(BasicBlock *BB, DeferredDominance *DDT = nullptr);
401406

402407
/// Remove all blocks that can not be reached from the function's entry.
403408
///
404409
/// Returns true if any basic block was removed.
405-
bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr);
410+
bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr,
411+
DeferredDominance *DDT = nullptr);
406412

407413
/// Combine the metadata of two instructions so that K can replace J
408414
///

lib/Analysis/LazyValueInfo.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ namespace {
401401
AssumptionCache *AC; ///< A pointer to the cache of @llvm.assume calls.
402402
const DataLayout &DL; ///< A mandatory DataLayout
403403
DominatorTree *DT; ///< An optional DT pointer.
404+
DominatorTree *DisabledDT; ///< Stores DT if it's disabled.
404405

405406
ValueLatticeElement getBlockValue(Value *Val, BasicBlock *BB);
406407
bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T,
@@ -463,13 +464,30 @@ namespace {
463464
TheCache.eraseBlock(BB);
464465
}
465466

467+
/// Disables use of the DominatorTree within LVI.
468+
void disableDT() {
469+
if (DT) {
470+
assert(!DisabledDT && "Both DT and DisabledDT are not nullptr!");
471+
std::swap(DT, DisabledDT);
472+
}
473+
}
474+
475+
/// Enables use of the DominatorTree within LVI. Does nothing if the class
476+
/// instance was initialized without a DT pointer.
477+
void enableDT() {
478+
if (DisabledDT) {
479+
assert(!DT && "Both DT and DisabledDT are not nullptr!");
480+
std::swap(DT, DisabledDT);
481+
}
482+
}
483+
466484
/// This is the update interface to inform the cache that an edge from
467485
/// PredBB to OldSucc has been threaded to be from PredBB to NewSucc.
468486
void threadEdge(BasicBlock *PredBB,BasicBlock *OldSucc,BasicBlock *NewSucc);
469487

470488
LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL,
471489
DominatorTree *DT = nullptr)
472-
: AC(AC), DL(DL), DT(DT) {}
490+
: AC(AC), DL(DL), DT(DT), DisabledDT(nullptr) {}
473491
};
474492
} // end anonymous namespace
475493

@@ -1791,6 +1809,16 @@ void LazyValueInfo::printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS)
17911809
}
17921810
}
17931811

1812+
void LazyValueInfo::disableDT() {
1813+
if (PImpl)
1814+
getImpl(PImpl, AC, DL, DT).disableDT();
1815+
}
1816+
1817+
void LazyValueInfo::enableDT() {
1818+
if (PImpl)
1819+
getImpl(PImpl, AC, DL, DT).enableDT();
1820+
}
1821+
17941822
// Print the LVI for the function arguments at the start of each basic block.
17951823
void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
17961824
const BasicBlock *BB, formatted_raw_ostream &OS) {

0 commit comments

Comments
 (0)