Static Value-Flow Analysis
Loading...
Searching...
No Matches
BreakConstantExpr.cpp
Go to the documentation of this file.
1/* SVF - Static Value-Flow Analysis Framework
2Copyright (C) 2015 Yulei Sui
3Copyright (C) 2015 Jingling Xue
4
5This library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Lesser General Public
7License as published by the Free Software Foundation; either
8version 2.1 of the License, or (at your option) any later version.
9
10This library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Lesser General Public License for more details.
14
15You should have received a copy of the GNU Lesser General Public
16License along with this library; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/*
21 * BreakConstantExpr.cpp
22 *
23 * Created on: Oct 8, 2013
24 * Author: Yulei Sui
25 */
26
27
28
29//===- BreakConstantGEPs.cpp - Change constant GEPs into GEP instructions - --//
30//
31// The SAFECode Compiler
32//
33// This file was developed by the LLVM research group and is distributed under
34// the University of Illinois Open Source License. See LICENSE.TXT for details.
35//
36//===----------------------------------------------------------------------===//
37//
38// This pass changes all GEP constant expressions into GEP instructions. This
39// permits the rest of SAFECode to put run-time checks on them if necessary.
40//
41//===----------------------------------------------------------------------===//
42
43
44#include "llvm/ADT/Statistic.h"
45#include "llvm/IR/Constants.h"
46#include "llvm/IR/InstrTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/LLVMContext.h"
50#include "llvm/IR/InstIterator.h"
51
52#include "SVF-LLVM/BasicTypes.h"
54
55#include <iostream>
56#include <map>
57#include <utility>
58
59using namespace SVF;
60
61// Identifier variable for the pass
64
65#define DEBUG_TYPE "break-constgeps"
66
67// Statistics
68STATISTIC (GEPChanges, "Number of Converted GEP Constant Expressions");
69STATISTIC (TotalChanges, "Number of Converted Constant Expressions");
70
71//
72// Function: hasConstantGEP()
73//
74// Description:
75// This function determines whether the given value is a constant expression
76// that has a constant GEP expression embedded within it.
77//
78// Inputs:
79// V - The value to check.
80//
81// Return value:
82// nullptr - This value is not a constant expression with a constant expression
83// GEP within it.
84// ~nullptr - A pointer to the value casted into a ConstantExpr is returned.
85//
86static ConstantExpr *
88{
89 if (ConstantExpr * CE = SVFUtil::dyn_cast<ConstantExpr>(V))
90 {
91 if (CE->getOpcode() == Instruction::GetElementPtr)
92 {
93 return CE;
94 }
95 else
96 {
97 for (u32_t index = 0; index < CE->getNumOperands(); ++index)
98 {
99 if (hasConstantGEP (CE->getOperand(index)))
100 return CE;
101 }
102 }
103 }
104
105 return nullptr;
106}
107
108// Description:
109// This function determines whether the given value is a constant expression
110// that has a constant binary or unary operator expression embedded within it.
111static ConstantExpr *
113{
114 if (ConstantExpr * CE = SVFUtil::dyn_cast<ConstantExpr>(V))
115 {
116 if (Instruction::isBinaryOp(CE->getOpcode()) || Instruction::isUnaryOp(CE->getOpcode()))
117 {
118 return CE;
119 }
120 else
121 {
122 for (u32_t index = 0; index < CE->getNumOperands(); ++index)
123 {
124 if (hasConstantBinaryOrUnaryOp (CE->getOperand(index)))
125 return CE;
126 }
127 }
128 }
129
130 return nullptr;
131}
132
133// Description:
134// Return true if this is a constant Gep or binaryOp or UnaryOp expression
135static ConstantExpr *
137{
139 {
140 return gep;
141 }
143 {
144 return buop;
145 }
146 else
147 {
148 return nullptr;
149 }
150}
151
152
153//
154// Function: convertExpression()
155//
156// Description:
157// Convert a constant expression into an instruction. This routine does *not*
158// perform any recursion, so the resulting instruction may have constant
159// expression operands.
160//
161static Instruction*
163{
164 //
165 // Convert this constant expression into a regular instruction.
166 //
167 if (CE->getOpcode() == Instruction::GetElementPtr)
168 ++GEPChanges;
169 ++TotalChanges;
170 Instruction* Result = CE->getAsInstruction();
171 Result->insertBefore(InsertPt);
172 return Result;
173}
174
175//
176// Method: runOnFunction()
177//
178// Description:
179// Entry point for this LLVM pass.
180//
181// Return value:
182// true - The function was modified.
183// false - The function was not modified.
184//
185bool
187{
188 bool modified = false;
189 for (Module::iterator F = module.begin(), E = module.end(); F != E; ++F)
190 {
191 // Worklist of values to check for constant GEP expressions
192 std::vector<Instruction* > Worklist;
193
194 //
195 // Initialize the worklist by finding all instructions that have one or more
196 // operands containing a constant GEP expression.
197 //
198 for (Function::iterator BB = (*F).begin(); BB != (*F).end(); ++BB)
199 {
200 for (BasicBlock::iterator i = BB->begin(); i != BB->end(); ++i)
201 {
202 //
203 // Scan through the operands of this instruction. If it is a constant
204 // expression GEP, insert an instruction GEP before the instruction.
205 //
206 Instruction* I = &(*i);
207 for (u32_t index = 0; index < I->getNumOperands(); ++index)
208 {
209 if (hasConstantExpr(I->getOperand(index)))
210 {
211 Worklist.push_back (I);
212 }
213 }
214 }
215 }
216
217 //
218 // Determine whether we will modify anything.
219 //
220 if (Worklist.size()) modified = true;
221
222 //
223 // While the worklist is not empty, take an item from it, convert the
224 // operands into instructions if necessary, and determine if the newly
225 // added instructions need to be processed as well.
226 //
227 while (Worklist.size())
228 {
229 Instruction* I = Worklist.back();
230 Worklist.pop_back();
231
232 //
233 // Scan through the operands of this instruction and convert each into an
234 // instruction. Note that this works a little differently for phi
235 // instructions because the new instruction must be added to the
236 // appropriate predecessor block.
237 //
238 if (PHINode * PHI = SVFUtil::dyn_cast<PHINode>(I))
239 {
240 for (u32_t index = 0; index < PHI->getNumIncomingValues(); ++index)
241 {
242 //
243 // For PHI Nodes, if an operand is a constant expression with a GEP, we
244 // want to insert the new instructions in the predecessor basic block.
245 //
246 // Note: It seems that it's possible for a phi to have the same
247 // incoming basic block listed multiple times; this seems okay as long
248 // the same value is listed for the incoming block.
249 //
250 Instruction* InsertPt = PHI->getIncomingBlock(index)->getTerminator();
251 if (ConstantExpr * CE = hasConstantExpr(PHI->getIncomingValue(index)))
252 {
254 for (u32_t i2 = index; i2 < PHI->getNumIncomingValues(); ++i2)
255 {
256 if ((PHI->getIncomingBlock (i2)) == PHI->getIncomingBlock (index))
257 PHI->setIncomingValue (i2, NewInst);
258 }
259 Worklist.push_back (NewInst);
260 }
261 }
262 }
263 else
264 {
265 for (u32_t index = 0; index < I->getNumOperands(); ++index)
266 {
267 //
268 // For other instructions, we want to insert instructions replacing
269 // constant expressions immediately before the instruction using the
270 // constant expression.
271 //
272 if (ConstantExpr * CE = hasConstantExpr(I->getOperand(index)))
273 {
275 I->replaceUsesOfWith (CE, NewInst);
276 Worklist.push_back (NewInst);
277 }
278 }
279 }
280 }
281
282 }
283 return modified;
284}
285
286
287
288
static Instruction * convertExpression(ConstantExpr *CE, Instruction *InsertPt)
static ConstantExpr * hasConstantExpr(Value *V)
STATISTIC(GEPChanges, "Number of Converted GEP Constant Expressions")
static ConstantExpr * hasConstantBinaryOrUnaryOp(Value *V)
static ConstantExpr * hasConstantGEP(Value *V)
unsigned u32_t
Definition CommandLine.h:18
#define F(f)
int index
Definition cJSON.h:170
virtual bool runOnModule(Module &M)
for isBitcode
Definition BasicTypes.h:68
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:120
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
llvm::Module Module
Definition BasicTypes.h:84
llvm::PHINode PHINode
Definition BasicTypes.h:165
unsigned u32_t
Definition GeneralType.h:46