10b57cec5SDimitry Andric //===- PostOrderCFGView.cpp - Post order view of CFG blocks ---------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements post order view of the blocks in a CFG. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "clang/Analysis/Analyses/PostOrderCFGView.h" 140b57cec5SDimitry Andric #include "clang/Analysis/AnalysisDeclContext.h" 150b57cec5SDimitry Andric #include "clang/Analysis/CFG.h" 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric using namespace clang; 180b57cec5SDimitry Andric anchor()190b57cec5SDimitry Andricvoid PostOrderCFGView::anchor() {} 200b57cec5SDimitry Andric PostOrderCFGView(const CFG * cfg)210b57cec5SDimitry AndricPostOrderCFGView::PostOrderCFGView(const CFG *cfg) { 220b57cec5SDimitry Andric Blocks.reserve(cfg->getNumBlockIDs()); 230b57cec5SDimitry Andric CFGBlockSet BSet(cfg); 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric for (po_iterator I = po_iterator::begin(cfg, BSet), 260b57cec5SDimitry Andric E = po_iterator::end(cfg, BSet); I != E; ++I) { 270b57cec5SDimitry Andric BlockOrder[*I] = Blocks.size() + 1; 280b57cec5SDimitry Andric Blocks.push_back(*I); 290b57cec5SDimitry Andric } 300b57cec5SDimitry Andric } 310b57cec5SDimitry Andric 32*5ffd83dbSDimitry Andric std::unique_ptr<PostOrderCFGView> create(AnalysisDeclContext & ctx)33*5ffd83dbSDimitry AndricPostOrderCFGView::create(AnalysisDeclContext &ctx) { 340b57cec5SDimitry Andric const CFG *cfg = ctx.getCFG(); 350b57cec5SDimitry Andric if (!cfg) 360b57cec5SDimitry Andric return nullptr; 37*5ffd83dbSDimitry Andric return std::make_unique<PostOrderCFGView>(cfg); 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric getTag()400b57cec5SDimitry Andricconst void *PostOrderCFGView::getTag() { static int x; return &x; } 410b57cec5SDimitry Andric operator ()(const CFGBlock * b1,const CFGBlock * b2) const420b57cec5SDimitry Andricbool PostOrderCFGView::BlockOrderCompare::operator()(const CFGBlock *b1, 430b57cec5SDimitry Andric const CFGBlock *b2) const { 440b57cec5SDimitry Andric PostOrderCFGView::BlockOrderTy::const_iterator b1It = POV.BlockOrder.find(b1); 450b57cec5SDimitry Andric PostOrderCFGView::BlockOrderTy::const_iterator b2It = POV.BlockOrder.find(b2); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric unsigned b1V = (b1It == POV.BlockOrder.end()) ? 0 : b1It->second; 480b57cec5SDimitry Andric unsigned b2V = (b2It == POV.BlockOrder.end()) ? 0 : b2It->second; 490b57cec5SDimitry Andric return b1V > b2V; 500b57cec5SDimitry Andric } 51