LLVM: lib/Transforms/IPO/SCCP.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

34

35using namespace llvm;

36

37#define DEBUG_TYPE "sccp"

38

39STATISTIC(NumInstRemoved, "Number of instructions removed");

40STATISTIC(NumArgsElimed ,"Number of arguments constant propagated");

41STATISTIC(NumGlobalConst, "Number of globals found to be constant");

42STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");

44 "Number of instructions replaced with (simpler) instruction");

45

48 "The maximum number of iterations function specialization is run"));

49

53

55 return;

56

60 << "Can't zap returns of the function : " << F.getName()

61 << " due to present musttail or \"clang.arc.attachedcall\" call of "

62 "it\n");

63 return;

64 }

65

68 [&Solver](User *U) {

69 if (isa(U) &&

70 !Solver.isBlockExecutable(cast(U)->getParent()))

71 return true;

72

73

74

75

76 if (!isa(U))

77 return true;

78 if (U->getType()->isStructTy()) {

79 return none_of(Solver.getStructLatticeValueFor(U),

80 SCCPSolver::isOverdefined);

81 }

82

83

84

86 if (II->isAssumeLikeIntrinsic())

87 return true;

88 }

89

91 }) &&

92 "We can only zap functions where all live users have a concrete value");

93

95 if (CallInst *CI = BB.getTerminatingMustTailCall()) {

96 LLVM_DEBUG(dbgs() << "Can't zap return of the block due to present "

97 << "musttail call : " << *CI << "\n");

98 (void)CI;

99 return;

100 }

101

104 ReturnsToZap.push_back(RI);

105 }

106}

107

115 bool IsFuncSpecEnabled) {

116 SCCPSolver Solver(DL, GetTLI, M.getContext());

118 GetAC);

119

120

121

123 if (F.isDeclaration())

124 continue;

125

129

130

131

134

135

136

139 continue;

140 }

141

142

144

147 }

148

149

150

151

153 G.removeDeadConstantUsers();

156 }

157

158

160

161 if (IsFuncSpecEnabled) {

162 unsigned Iters = 0;

164 }

165

166

167

168 bool MadeChanges = false;

170 if (F.isDeclaration())

171 continue;

172

173

174

175 if (IsFuncSpecEnabled && Specializer.isDeadFunction(&F)) {

176 MadeChanges = true;

177 continue;

178 }

179

181

183 bool ReplacedPointerArg = false;

186 ReplacedPointerArg |= Arg.getType()->isPointerTy();

187 ++NumArgsElimed;

188 }

189 }

190

191

192

193 if (ReplacedPointerArg) {

194 auto UpdateAttrs = [&](AttributeList AL) {

197 return AL;

198

202

203 return AL.addFnAttribute(

204 F.getContext(),

206 };

207

208 F.setAttributes(UpdateAttrs(F.getAttributes()));

209 for (User *U : F.users()) {

211 if (!CB || CB->getCalledFunction() != &F)

212 continue;

213

214 CB->setAttributes(UpdateAttrs(CB->getAttributes()));

215 }

216 }

217 MadeChanges |= ReplacedPointerArg;

218 }

219

224 ++NumDeadBlocks;

225

226 MadeChanges = true;

227

228 if (&BB != &F.front())

230 continue;

231 }

232

234 BB, InsertedValues, NumInstRemoved, NumInstReplaced);

235 }

236

239 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);

240

241

242

243

244 for (BasicBlock *BB : BlocksToErase) {

246 false, &DTU);

247 }

250 false, &DTU);

251

252 BasicBlock *NewUnreachableBB = nullptr;

255

256 for (BasicBlock *DeadBB : BlocksToErase)

257 if (!DeadBB->hasAddressTaken())

258 DTU.deleteBB(DeadBB);

259

261 }

262

263

264

265

266

267

268

269

270

271

272

274

278 assert(F->getReturnType()->isVoidTy() &&

279 "should not track void functions");

282 }

283

285 assert(F->getReturnType()->isStructTy() &&

286 "The return type should be a struct");

290 }

291

292

294 for (ReturnInst *RI : ReturnsToZap) {

295 Function *F = RI->getParent()->getParent();

297

298 FuncZappedReturn.insert(F);

299 }

300

301

302

303

304

306 AttributeFuncs::getUBImplyingAttributes();

307 for (Function *F : FuncZappedReturn) {

309 F->removeParamAttr(A.getArgNo(), Attribute::Returned);

310 F->removeRetAttrs(UBImplyingAttributes);

311 for (Use &U : F->uses()) {

313 if (!CB) {

315 all_of(U.getUser()->users(), [](const User *UserUser) {

316 return cast(UserUser)->isAssumeLikeIntrinsic();

317 }));

318 continue;

319 }

320

321 for (Use &Arg : CB->args())

324 }

325 }

326

327

328

332 continue;

334 << "' is constant!\n");

336

337

339 "Only Store|Load Instruction can be user of GlobalVariable at "

340 "reaching here.");

344 I->eraseFromParent();

345 }

346

347

348

351 if (GVEs.size() == 1) {

355 GVEs[0]->replaceOperandWith(1, InitExpr);

356 }

357

358 MadeChanges = true;

359 M.eraseGlobalVariable(GV);

360 ++NumGlobalConst;

361 }

362

363 return MadeChanges;

364}

365

371 };

374 };

377 };

380 };

383 };

384

385

386 if (runIPSCCP(M, DL, &FAM, GetTLI, GetTTI, GetAC, GetDT, GetBFI,

389

394 return PA;

395}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static void findReturnsToZap(Function &F, SmallVector< ReturnInst *, 8 > &ReturnsToZap, SCCPSolver &Solver)

Definition SCCP.cpp:50

static cl::opt< unsigned > FuncSpecMaxIters("funcspec-max-iters", cl::init(10), cl::Hidden, cl::desc("The maximum number of iterations function specialization is run"))

static bool runIPSCCP(Module &M, const DataLayout &DL, FunctionAnalysisManager *FAM, std::function< const TargetLibraryInfo &(Function &)> GetTLI, std::function< TargetTransformInfo &(Function &)> GetTTI, std::function< AssumptionCache &(Function &)> GetAC, std::function< DominatorTree &(Function &)> GetDT, std::function< BlockFrequencyInfo &(Function &)> GetBFI, bool IsFuncSpecEnabled)

Definition SCCP.cpp:108

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

This file implements a set that has insertion order iteration characteristics.

#define STATISTIC(VARNAME, DESC)

This pass exposes codegen information to IR-level passes.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

This class represents an incoming formal argument to a Function.

A function analysis which provides an AssumptionCache.

A cache of @llvm.assume calls within a function.

This class stores enough information to efficiently remove some attributes from an existing AttrBuild...

static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)

LLVM Basic Block Representation.

Analysis pass which computes BlockFrequencyInfo.

BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)

Removes the attribute from the given argument.

void removeRetAttrs(const AttributeMask &AttrsToRemove)

Removes the attributes from the return value.

iterator_range< User::op_iterator > args()

Iteration adapter for range-for loops.

unsigned getArgOperandNo(const Use *U) const

Given a use for a arg operand, get the arg operand number that corresponds to it.

This class represents a function call, abstracting a target machine's calling convention.

A parsed version of the target data layout string in and methods for querying it.

Analysis pass which computes a DominatorTree.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

LLVM_ABI bool run()

Attempt to specialize functions in the module to enable constant propagation across function boundari...

bool isDeadFunction(Function *F)

Type * getValueType() const

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

LLVM_ABI void getDebugInfo(SmallVectorImpl< DIGlobalVariableExpression * > &GVs) const

Fill the vector with all debug info attachements.

bool isFuncSpecEnabled() const

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition SCCP.cpp:366

ModRefInfo getModRef(Location Loc) const

Get ModRefInfo for the given Location.

static MemoryEffectsBase unknown()

A Module instance is used to store all the information related to an LLVM module.

static LLVM_ABI PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

Analysis pass which computes a PostDominatorTree.

PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

PreservedAnalyses & preserve()

Mark an analysis as preserved.

Return a value (possibly void), from a function.

SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...

LLVM_ABI void trackValueOfGlobalVariable(GlobalVariable *GV)

trackValueOfGlobalVariable - Clients can use this method to inform the SCCPSolver that it should trac...

LLVM_ABI bool tryToReplaceWithConstant(Value *V)

LLVM_ABI void inferArgAttributes() const

LLVM_ABI bool isStructLatticeConstant(Function *F, StructType *STy)

LLVM_ABI void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC)

LLVM_ABI void trackValueOfArgument(Argument *V)

trackValueOfArgument - Mark the specified argument overdefined unless it have range attribute.

LLVM_ABI const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals() const

getTrackedGlobals - Get and return the set of inferred initializers for global variables.

LLVM_ABI void addTrackedFunction(Function *F)

addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...

LLVM_ABI void solveWhileResolvedUndefsIn(Module &M)

LLVM_ABI const SmallPtrSet< Function *, 16 > & getMRVFunctionsTracked() const

getMRVFunctionsTracked - Get the set of functions which return multiple values tracked by the pass.

LLVM_ABI void addArgumentTrackedFunction(Function *F)

LLVM_ABI bool simplifyInstsInBlock(BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)

LLVM_ABI const ValueLatticeElement & getLatticeValueFor(Value *V) const

LLVM_ABI bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const

LLVM_ABI bool isBlockExecutable(BasicBlock *BB) const

LLVM_ABI void inferReturnAttributes() const

LLVM_ABI bool markBlockExecutable(BasicBlock *BB)

markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...

static LLVM_ABI bool isConstant(const ValueLatticeElement &LV)

LLVM_ABI const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals() const

getTrackedRetVals - Get the inferred return value map.

LLVM_ABI bool mustPreserveReturn(Function *F)

Returns true if the return of the given function cannot be modified.

static LLVM_ABI bool isOverdefined(const ValueLatticeElement &LV)

LLVM_ABI bool isArgumentTrackedFunction(Function *F)

Returns true if the given function is in the solver's set of argument-tracked functions.

LLVM_ABI void removeSSACopies(Function &F)

bool insert(const value_type &X)

Insert a new element into the SetVector.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

A SetVector that performs no allocations if smaller than a certain size.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Class to represent struct types.

Analysis pass providing the TargetTransformInfo.

Analysis pass providing the TargetLibraryInfo.

Provides information about what library functions are available for the current target.

This pass provides access to the codegen interfaces that are needed for IR-level transformations.

A Use represents the edge between a Value definition and its users.

iterator_range< user_iterator > users()

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy

Provide the FunctionAnalysisManager to Module proxy.

MemoryEffectsBase< IRMemLocation > MemoryEffects

Summary of how a function affects memory in the program.

bool canTrackGlobalVariableInterprocedurally(GlobalVariable *GV)

Determine if the value maintained in the given global variable can be tracked interprocedurally.

LLVM_ABI DIExpression * getExpressionForConstant(DIBuilder &DIB, const Constant &C, Type &Ty)

Given a constant, create a debug information expression.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)

Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...

ModRefInfo

Flags indicating whether a memory access modifies or references memory.

@ ArgMem

Access to memory via argument pointers.

bool canTrackReturnsInterprocedurally(Function *F)

Determine if the values of the given function's returns can be tracked interprocedurally.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

bool canTrackArgumentsInterprocedurally(Function *F)

Determine if the values of the given function's arguments can be tracked interprocedurally.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.