//===-- VPlanHCFGBuilder.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file implements the construction of a VPlan-based Hierarchical CFG /// (H-CFG) for an incoming IR. This construction comprises the following /// components and steps: // /// 1. PlainCFGBuilder class: builds a plain VPBasicBlock-based CFG that /// faithfully represents the CFG in the incoming IR. A VPRegionBlock (Top /// Region) is created to enclose and serve as parent of all the VPBasicBlocks /// in the plain CFG. /// NOTE: At this point, there is a direct correspondence between all the /// VPBasicBlocks created for the initial plain CFG and the incoming /// BasicBlocks. However, this might change in the future. /// //===----------------------------------------------------------------------===// #include "VPlanHCFGBuilder.h" #include "LoopVectorizationPlanner.h" #include "llvm/Analysis/LoopIterator.h" #define DEBUG_TYPE … usingnamespacellvm; namespace { // Class that is used to build the plain CFG for the incoming IR. class PlainCFGBuilder { … }; } // anonymous namespace // Set predecessors of \p VPBB in the same order as they are in \p BB. \p VPBB // must have no predecessors. void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) { … } static bool isHeaderBB(BasicBlock *BB, Loop *L) { … } void PlainCFGBuilder::setRegionPredsFromBB(VPRegionBlock *Region, BasicBlock *BB) { … } // Add operands to VPInstructions representing phi nodes from the input IR. void PlainCFGBuilder::fixPhiNodes() { … } static bool isHeaderVPBB(VPBasicBlock *VPBB) { … } /// Return true of \p L loop is contained within \p OuterLoop. static bool doesContainLoop(const Loop *L, const Loop *OuterLoop) { … } // Create a new empty VPBasicBlock for an incoming BasicBlock in the region // corresponding to the containing loop or retrieve an existing one if it was // already created. If no region exists yet for the loop containing \p BB, a new // one is created. VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) { … } #ifndef NDEBUG // Return true if \p Val is considered an external definition. An external // definition is either: // 1. A Value that is not an Instruction. This will be refined in the future. // 2. An Instruction that is outside of the CFG snippet represented in VPlan, // i.e., is not part of: a) the loop nest, b) outermost loop PH and, c) // outermost loop exits. bool PlainCFGBuilder::isExternalDef(Value *Val) { // All the Values that are not Instructions are considered external // definitions for now. Instruction *Inst = dyn_cast<Instruction>(Val); if (!Inst) return true; BasicBlock *InstParent = Inst->getParent(); assert(InstParent && "Expected instruction parent."); // Check whether Instruction definition is in loop PH. BasicBlock *PH = TheLoop->getLoopPreheader(); assert(PH && "Expected loop pre-header."); if (InstParent == PH) // Instruction definition is in outermost loop PH. return false; // Check whether Instruction definition is in the loop exit. BasicBlock *Exit = TheLoop->getUniqueExitBlock(); assert(Exit && "Expected loop with single exit."); if (InstParent == Exit) { // Instruction definition is in outermost loop exit. return false; } // Check whether Instruction definition is in loop body. return !TheLoop->contains(Inst); } #endif // Create a new VPValue or retrieve an existing one for the Instruction's // operand \p IRVal. This function must only be used to create/retrieve VPValues // for *Instruction's operands* and not to create regular VPInstruction's. For // the latter, please, look at 'createVPInstructionsForVPBB'. VPValue *PlainCFGBuilder::getOrCreateVPOperand(Value *IRVal) { … } // Create new VPInstructions in a VPBasicBlock, given its BasicBlock // counterpart. This function must be invoked in RPO so that the operands of a // VPInstruction in \p BB have been visited before (except for Phi nodes). void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB, BasicBlock *BB) { … } // Main interface to build the plain CFG. void PlainCFGBuilder::buildPlainCFG() { … } void VPlanHCFGBuilder::buildPlainCFG() { … } // Public interface to build a H-CFG. void VPlanHCFGBuilder::buildHierarchicalCFG() { … }