Static Value-Flow Analysis
Loading...
Searching...
No Matches
LLVMLoopAnalysis.cpp
Go to the documentation of this file.
1//===- LLVMLoopAnalysis.cpp -- LoopAnalysis of SVF ------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2022> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23
24/*
25 * LLVMLoopAnalysis.cpp
26 *
27 * Created on: 14, 06, 2022
28 * Author: Jiawei Wang, Xiao Cheng
29 */
30
31#include "MemoryModel/SVFLoop.h"
33#include "Util/GeneralType.h"
34#include "Util/Options.h"
35#include "SVF-LLVM/LLVMUtil.h"
36#include "llvm/Analysis/LoopInfo.h"
37
38#include "llvm/Transforms/Utils/Mem2Reg.h"
39#include "llvm/Passes/PassBuilder.h"
40
41#include "SVF-LLVM/LLVMModule.h"
42
43using namespace SVF;
44using namespace SVFUtil;
45
52{
53 std::vector<const Loop *> loop_stack;
55 {
56 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
57 {
58 const Function* func = &*F;
60 if (func->isDeclaration()) continue;
61 // do not analyze external call
62 if (SVFUtil::isExtCall(svffun)) continue;
63 llvm::DominatorTree& DT = LLVMModuleSet::getLLVMModuleSet()->getDomTree(func);
64 llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop> loopInfo;
65 std::vector<const Loop*> llvmLoops;
66 loopInfo.analyze(DT);
67 for (const auto &loop: loopInfo)
68 {
69 loop_stack.push_back(loop);
70 }
71 // pre-order traversal on loop-subloop tree
72 while (!loop_stack.empty())
73 {
74 const Loop *loop = loop_stack.back();
75 loop_stack.pop_back();
76 llvmLoops.push_back(loop);
77 for (const auto &subloop: loop->getSubLoops())
78 {
79 loop_stack.push_back(subloop);
80 }
81 }
83 }
84 }
85}
86
92{
93 std::vector<const Loop *> llvmLoops;
94 buildLLVMLoops(icfg);
95}
96
102void LLVMLoopAnalysis::buildSVFLoops(ICFG *icfg, std::vector<const Loop *> &llvmLoops)
103{
104 for (const auto &llvmLoop: llvmLoops)
105 {
106 DBOUT(DPAGBuild, outs() << "loop name: " << llvmLoop->getName().data() << "\n");
107 // count all node id in loop
110 for (const auto &BB: llvmLoop->getBlocks())
111 {
112 for (const auto &ins: *BB)
113 {
115 continue;
118 }
119 }
121 for (const auto &node: nodes)
122 {
123 icfg->addNodeToSVFLoop(node, svf_loop);
124 }
125 // mark loop header's first inst
126 BasicBlock* header_blk = llvmLoop->getHeader();
127 Instruction* in_ins = &(*header_blk->begin());
128
130 {
131 in_ins = in_ins->getNextNode();
132 }
134 for (const auto &edge: in_node->getInEdges())
135 {
136 if (loop_ids.find(edge->getSrcNode()) == loop_ids.end())
137 {
138 // entry edge
139 svf_loop->addEntryICFGEdge(edge);
140 DBOUT(DPAGBuild, outs() << " entry edge: " << edge->toString() << "\n");
141 }
142 else
143 {
144 // back edge
145 svf_loop->addBackICFGEdge(edge);
146 DBOUT(DPAGBuild, outs() << " back edge: " << edge->toString() << "\n");
147 }
148 }
149 // handle in edge
150 llvm::Instruction &br_ins = header_blk->back();
152 for (const auto &edge: br_node->getOutEdges())
153 {
154 if (loop_ids.find(edge->getDstNode()) != loop_ids.end())
155 {
156 svf_loop->addInICFGEdge(edge);
157 DBOUT(DPAGBuild, outs() << " in edge: " << edge->toString() << "\n");
158 }
159 else
160 {
161 continue;
162 }
163 }
164 // mark loop end's first inst
165 llvm::SmallVector<BasicBlock*, 8> ExitBlocks;
166 llvmLoop->getExitBlocks(ExitBlocks);
167 for (const auto& exit_blk: ExitBlocks)
168 {
169 assert(!exit_blk->empty() && "exit block is empty?");
170 llvm::Instruction* out_ins = &(*exit_blk->begin());
171
173 {
174 out_ins = out_ins->getNextNode();
175 }
176
178 for (const auto &edge: out_node->getInEdges())
179 {
180 svf_loop->addOutICFGEdge(edge);
181 DBOUT(DPAGBuild, outs() << " out edge: " << edge->toString() << "\n");
182 }
183 }
184 }
185}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DPAGBuild
Definition SVFType.h:584
void addNodeToSVFLoop(const ICFGNode *node, const SVFLoop *loop)
Insert (node, loop) to icfgNodeToSVFLoopVec.
Definition ICFG.h:120
virtual void build(ICFG *icfg)
Start from here.
virtual void buildLLVMLoops(ICFG *icfg)
Build llvm loops based on LoopInfo analysis.
virtual void buildSVFLoops(ICFG *icfg, std::vector< const Loop * > &llvmLoops)
Build SVF loops based on llvm loops.
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:270
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:133
DominatorTree & getDomTree(const Function *fun)
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:160
static const Option< u32_t > LoopBound
Definition Options.h:236
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:204
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:441
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:90
llvm::Function Function
Definition BasicTypes.h:89
llvm::Instruction Instruction
Definition BasicTypes.h:91
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
llvm::Module Module
Definition BasicTypes.h:88
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
llvm::Loop Loop
LLVM Loop.
Definition BasicTypes.h:147