VPlanPredicator.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. //===-- VPlanPredicator.cpp -------------------------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. ///
  10. /// \file
  11. /// This file implements the VPlanPredicator class which contains the public
  12. /// interfaces to predicate and linearize the VPlan region.
  13. ///
  14. //===----------------------------------------------------------------------===//
  15. #include "VPlanPredicator.h"
  16. #include "VPlan.h"
  17. #include "llvm/ADT/DepthFirstIterator.h"
  18. #include "llvm/ADT/GraphTraits.h"
  19. #include "llvm/ADT/PostOrderIterator.h"
  20. #include "llvm/Support/Debug.h"
  21. #include "llvm/Support/raw_ostream.h"
  22. #define DEBUG_TYPE "VPlanPredicator"
  23. using namespace llvm;
  24. // Generate VPInstructions at the beginning of CurrBB that calculate the
  25. // predicate being propagated from PredBB to CurrBB depending on the edge type
  26. // between them. For example if:
  27. // i. PredBB is controlled by predicate %BP, and
  28. // ii. The edge PredBB->CurrBB is the false edge, controlled by the condition
  29. // bit value %CBV then this function will generate the following two
  30. // VPInstructions at the start of CurrBB:
  31. // %IntermediateVal = not %CBV
  32. // %FinalVal = and %BP %IntermediateVal
  33. // It returns %FinalVal.
  34. VPValue *VPlanPredicator::getOrCreateNotPredicate(VPBasicBlock *PredBB,
  35. VPBasicBlock *CurrBB) {
  36. VPValue *CBV = PredBB->getCondBit();
  37. // Set the intermediate value - this is either 'CBV', or 'not CBV'
  38. // depending on the edge type.
  39. EdgeType ET = getEdgeTypeBetween(PredBB, CurrBB);
  40. VPValue *IntermediateVal = nullptr;
  41. switch (ET) {
  42. case EdgeType::TRUE_EDGE:
  43. // CurrBB is the true successor of PredBB - nothing to do here.
  44. IntermediateVal = CBV;
  45. break;
  46. case EdgeType::FALSE_EDGE:
  47. // CurrBB is the False successor of PredBB - compute not of CBV.
  48. IntermediateVal = Builder.createNot(CBV);
  49. break;
  50. }
  51. // Now AND intermediate value with PredBB's block predicate if it has one.
  52. VPValue *BP = PredBB->getPredicate();
  53. if (BP)
  54. return Builder.createAnd(BP, IntermediateVal);
  55. else
  56. return IntermediateVal;
  57. }
  58. // Generate a tree of ORs for all IncomingPredicates in WorkList.
  59. // Note: This function destroys the original Worklist.
  60. //
  61. // P1 P2 P3 P4 P5
  62. // \ / \ / /
  63. // OR1 OR2 /
  64. // \ | /
  65. // \ +/-+
  66. // \ / |
  67. // OR3 |
  68. // \ |
  69. // OR4 <- Returns this
  70. // |
  71. //
  72. // The algorithm uses a worklist of predicates as its main data structure.
  73. // We pop a pair of values from the front (e.g. P1 and P2), generate an OR
  74. // (in this example OR1), and push it back. In this example the worklist
  75. // contains {P3, P4, P5, OR1}.
  76. // The process iterates until we have only one element in the Worklist (OR4).
  77. // The last element is the root predicate which is returned.
  78. VPValue *VPlanPredicator::genPredicateTree(std::list<VPValue *> &Worklist) {
  79. if (Worklist.empty())
  80. return nullptr;
  81. // The worklist initially contains all the leaf nodes. Initialize the tree
  82. // using them.
  83. while (Worklist.size() >= 2) {
  84. // Pop a pair of values from the front.
  85. VPValue *LHS = Worklist.front();
  86. Worklist.pop_front();
  87. VPValue *RHS = Worklist.front();
  88. Worklist.pop_front();
  89. // Create an OR of these values.
  90. VPValue *Or = Builder.createOr(LHS, RHS);
  91. // Push OR to the back of the worklist.
  92. Worklist.push_back(Or);
  93. }
  94. assert(Worklist.size() == 1 && "Expected 1 item in worklist");
  95. // The root is the last node in the worklist.
  96. VPValue *Root = Worklist.front();
  97. // This root needs to replace the existing block predicate. This is done in
  98. // the caller function.
  99. return Root;
  100. }
  101. // Return whether the edge FromBlock -> ToBlock is a TRUE_EDGE or FALSE_EDGE
  102. VPlanPredicator::EdgeType
  103. VPlanPredicator::getEdgeTypeBetween(VPBlockBase *FromBlock,
  104. VPBlockBase *ToBlock) {
  105. unsigned Count = 0;
  106. for (VPBlockBase *SuccBlock : FromBlock->getSuccessors()) {
  107. if (SuccBlock == ToBlock) {
  108. assert(Count < 2 && "Switch not supported currently");
  109. return (Count == 0) ? EdgeType::TRUE_EDGE : EdgeType::FALSE_EDGE;
  110. }
  111. Count++;
  112. }
  113. llvm_unreachable("Broken getEdgeTypeBetween");
  114. }
  115. // Generate all predicates needed for CurrBlock by going through its immediate
  116. // predecessor blocks.
  117. void VPlanPredicator::createOrPropagatePredicates(VPBlockBase *CurrBlock,
  118. VPRegionBlock *Region) {
  119. // Blocks that dominate region exit inherit the predicate from the region.
  120. // Return after setting the predicate.
  121. if (VPDomTree.dominates(CurrBlock, Region->getExit())) {
  122. VPValue *RegionBP = Region->getPredicate();
  123. CurrBlock->setPredicate(RegionBP);
  124. return;
  125. }
  126. // Collect all incoming predicates in a worklist.
  127. std::list<VPValue *> IncomingPredicates;
  128. // Set the builder's insertion point to the top of the current BB
  129. VPBasicBlock *CurrBB = cast<VPBasicBlock>(CurrBlock->getEntryBasicBlock());
  130. Builder.setInsertPoint(CurrBB, CurrBB->begin());
  131. // For each predecessor, generate the VPInstructions required for
  132. // computing 'BP AND (not) CBV" at the top of CurrBB.
  133. // Collect the outcome of this calculation for all predecessors
  134. // into IncomingPredicates.
  135. for (VPBlockBase *PredBlock : CurrBlock->getPredecessors()) {
  136. // Skip back-edges
  137. if (VPBlockUtils::isBackEdge(PredBlock, CurrBlock, VPLI))
  138. continue;
  139. VPValue *IncomingPredicate = nullptr;
  140. unsigned NumPredSuccsNoBE =
  141. VPBlockUtils::countSuccessorsNoBE(PredBlock, VPLI);
  142. // If there is an unconditional branch to the currBB, then we don't create
  143. // edge predicates. We use the predecessor's block predicate instead.
  144. if (NumPredSuccsNoBE == 1)
  145. IncomingPredicate = PredBlock->getPredicate();
  146. else if (NumPredSuccsNoBE == 2) {
  147. // Emit recipes into CurrBlock if required
  148. assert(isa<VPBasicBlock>(PredBlock) && "Only BBs have multiple exits");
  149. IncomingPredicate =
  150. getOrCreateNotPredicate(cast<VPBasicBlock>(PredBlock), CurrBB);
  151. } else
  152. llvm_unreachable("FIXME: switch statement ?");
  153. if (IncomingPredicate)
  154. IncomingPredicates.push_back(IncomingPredicate);
  155. }
  156. // Logically OR all incoming predicates by building the Predicate Tree.
  157. VPValue *Predicate = genPredicateTree(IncomingPredicates);
  158. // Now update the block's predicate with the new one.
  159. CurrBlock->setPredicate(Predicate);
  160. }
  161. // Generate all predicates needed for Region.
  162. void VPlanPredicator::predicateRegionRec(VPRegionBlock *Region) {
  163. VPBasicBlock *EntryBlock = cast<VPBasicBlock>(Region->getEntry());
  164. ReversePostOrderTraversal<VPBlockBase *> RPOT(EntryBlock);
  165. // Generate edge predicates and append them to the block predicate. RPO is
  166. // necessary since the predecessor blocks' block predicate needs to be set
  167. // before the current block's block predicate can be computed.
  168. for (VPBlockBase *Block : make_range(RPOT.begin(), RPOT.end())) {
  169. // TODO: Handle nested regions once we start generating the same.
  170. assert(!isa<VPRegionBlock>(Block) && "Nested region not expected");
  171. createOrPropagatePredicates(Block, Region);
  172. }
  173. }
  174. // Linearize the CFG within Region.
  175. // TODO: Predication and linearization need RPOT for every region.
  176. // This traversal is expensive. Since predication is not adding new
  177. // blocks, we should be able to compute RPOT once in predication and
  178. // reuse it here. This becomes even more important once we have nested
  179. // regions.
  180. void VPlanPredicator::linearizeRegionRec(VPRegionBlock *Region) {
  181. ReversePostOrderTraversal<VPBlockBase *> RPOT(Region->getEntry());
  182. VPBlockBase *PrevBlock = nullptr;
  183. for (VPBlockBase *CurrBlock : make_range(RPOT.begin(), RPOT.end())) {
  184. // TODO: Handle nested regions once we start generating the same.
  185. assert(!isa<VPRegionBlock>(CurrBlock) && "Nested region not expected");
  186. // Linearize control flow by adding an unconditional edge between PrevBlock
  187. // and CurrBlock skipping loop headers and latches to keep intact loop
  188. // header predecessors and loop latch successors.
  189. if (PrevBlock && !VPLI->isLoopHeader(CurrBlock) &&
  190. !VPBlockUtils::blockIsLoopLatch(PrevBlock, VPLI)) {
  191. LLVM_DEBUG(dbgs() << "Linearizing: " << PrevBlock->getName() << "->"
  192. << CurrBlock->getName() << "\n");
  193. PrevBlock->clearSuccessors();
  194. CurrBlock->clearPredecessors();
  195. VPBlockUtils::connectBlocks(PrevBlock, CurrBlock);
  196. }
  197. PrevBlock = CurrBlock;
  198. }
  199. }
  200. // Entry point. The driver function for the predicator.
  201. void VPlanPredicator::predicate(void) {
  202. // Predicate the blocks within Region.
  203. predicateRegionRec(cast<VPRegionBlock>(Plan.getEntry()));
  204. // Linearlize the blocks with Region.
  205. linearizeRegionRec(cast<VPRegionBlock>(Plan.getEntry()));
  206. }
  207. VPlanPredicator::VPlanPredicator(VPlan &Plan)
  208. : Plan(Plan), VPLI(&(Plan.getVPLoopInfo())) {
  209. // FIXME: Predicator is currently computing the dominator information for the
  210. // top region. Once we start storing dominator information in a VPRegionBlock,
  211. // we can avoid this recalculation.
  212. VPDomTree.recalculate(*(cast<VPRegionBlock>(Plan.getEntry())));
  213. }