LLVM: lib/Transforms/Utils/LibCallsShrinkWrap.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

42

43#include

44

45using namespace llvm;

46

47#define DEBUG_TYPE "libcalls-shrinkwrap"

48

49STATISTIC(NumWrappedOneCond, "Number of One-Condition Wrappers Inserted");

50STATISTIC(NumWrappedTwoCond, "Number of Two-Condition Wrappers Inserted");

51

52namespace {

53class LibCallsShrinkWrap : public InstVisitor {

54public:

56 : TLI(TLI), DTU(DTU){};

57 void visitCallInst(CallInst &CI) { checkCandidate(CI); }

58 bool perform() {

60 for (auto &CI : WorkList) {

61 LLVM_DEBUG(dbgs() << "CDCE calls: " << CI->getCalledFunction()->getName()

62 << "\n");

63 if (perform(CI)) {

66 }

67 }

69 }

70

71private:

72 bool perform(CallInst *CI);

73 void checkCandidate(CallInst &CI);

74 void shrinkWrapCI(CallInst *CI, Value *Cond);

75 bool performCallDomainErrorOnly(CallInst *CI, const LibFunc &Func);

76 bool performCallErrors(CallInst *CI, const LibFunc &Func);

77 bool performCallRangeErrorOnly(CallInst *CI, const LibFunc &Func);

78 Value *generateOneRangeCond(CallInst *CI, const LibFunc &Func);

79 Value *generateTwoRangeCond(CallInst *CI, const LibFunc &Func);

80 Value *generateCondForPow(CallInst *CI, const LibFunc &Func);

81

82

85 float Val2) {

87 auto Cond2 = createCond(BBBuilder, Arg2, Cmp2, Val2);

88 auto Cond1 = createCond(BBBuilder, Arg, Cmp, Val);

89 return BBBuilder.CreateOr(Cond1, Cond2);

90 }

91

92

96 return createOrCond(CI, Arg, Cmp, Val, Arg, Cmp2, Val2);

97 }

98

99

101 float Val) {

107 return BBBuilder.CreateFCmp(Cmp, Arg, V);

108 }

109

110

112 float Val) {

114 return createCond(BBBuilder, Arg, Cmp, Val);

115 }

116

117

120 return createCond(CI, Arg, Cmp, Val);

121 }

122

123 const TargetLibraryInfo &TLI;

124 DomTreeUpdater &DTU;

126};

127}

128

129

130bool LibCallsShrinkWrap::performCallDomainErrorOnly(CallInst *CI,

131 const LibFunc &Func) {

133

134 switch (Func) {

135 case LibFunc_acos:

136 case LibFunc_acosf:

137 case LibFunc_acosl:

138 case LibFunc_asin:

139 case LibFunc_asinf:

140 case LibFunc_asinl:

141 {

142 ++NumWrappedTwoCond;

144 break;

145 }

146 case LibFunc_cos:

147 case LibFunc_cosf:

148 case LibFunc_cosl:

149 case LibFunc_sin:

150 case LibFunc_sinf:

151 case LibFunc_sinl:

152 {

153 ++NumWrappedTwoCond;

155 -INFINITY);

156 break;

157 }

158 case LibFunc_acosh:

159 case LibFunc_acoshf:

160 case LibFunc_acoshl:

161 {

162 ++NumWrappedOneCond;

164 break;

165 }

166 case LibFunc_sqrt:

167 case LibFunc_sqrtf:

168 case LibFunc_sqrtl:

169 {

170 ++NumWrappedOneCond;

172 break;

173 }

174 default:

175 return false;

176 }

177 shrinkWrapCI(CI, Cond);

178 return true;

179}

180

181

182bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst *CI,

183 const LibFunc &Func) {

185

186 switch (Func) {

187 case LibFunc_cosh:

188 case LibFunc_coshf:

189 case LibFunc_coshl:

190 case LibFunc_exp:

191 case LibFunc_expf:

192 case LibFunc_expl:

193 case LibFunc_exp10:

194 case LibFunc_exp10f:

195 case LibFunc_exp10l:

196 case LibFunc_exp2:

197 case LibFunc_exp2f:

198 case LibFunc_exp2l:

199 case LibFunc_sinh:

200 case LibFunc_sinhf:

201 case LibFunc_sinhl: {

202 Cond = generateTwoRangeCond(CI, Func);

203 break;

204 }

205 case LibFunc_expm1:

206 case LibFunc_expm1f:

207 case LibFunc_expm1l:

208 {

209 Cond = generateOneRangeCond(CI, Func);

210 break;

211 }

212 default:

213 return false;

214 }

215 shrinkWrapCI(CI, Cond);

216 return true;

217}

218

219

220bool LibCallsShrinkWrap::performCallErrors(CallInst *CI,

221 const LibFunc &Func) {

223

224 switch (Func) {

225 case LibFunc_atanh:

226

227

228 case LibFunc_atanhf:

229 case LibFunc_atanhl:

230 {

231 ++NumWrappedTwoCond;

233 break;

234 }

235 case LibFunc_log:

236

237

238 case LibFunc_logf:

239 case LibFunc_logl:

240 case LibFunc_log10:

241 case LibFunc_log10f:

242 case LibFunc_log10l:

243 case LibFunc_log2:

244 case LibFunc_log2f:

245 case LibFunc_log2l:

246 case LibFunc_logb:

247 case LibFunc_logbf:

248 case LibFunc_logbl:

249 {

250 ++NumWrappedOneCond;

252 break;

253 }

254 case LibFunc_log1p:

255

256

257 case LibFunc_log1pf:

258 case LibFunc_log1pl:

259 {

260 ++NumWrappedOneCond;

262 break;

263 }

264 case LibFunc_pow:

265

266

267 case LibFunc_powf:

268 case LibFunc_powl: {

269 Cond = generateCondForPow(CI, Func);

270 if (Cond == nullptr)

271 return false;

272 break;

273 }

274 default:

275 return false;

276 }

277 assert(Cond && "performCallErrors should not see an empty condition");

278 shrinkWrapCI(CI, Cond);

279 return true;

280}

281

282

283

284void LibCallsShrinkWrap::checkCandidate(CallInst &CI) {

286 return;

287

288

289

290

292 return;

293

294 LibFunc Func;

296 if (!Callee)

297 return;

298 if (!TLI.getLibFunc(*Callee, Func) || !TLI.has(Func))

299 return;

300

302 return;

303

307 return;

308

309 WorkList.push_back(&CI);

310}

311

312

313Value *LibCallsShrinkWrap::generateOneRangeCond(CallInst *CI,

314 const LibFunc &Func) {

315 float UpperBound;

316 switch (Func) {

317 case LibFunc_expm1:

318 UpperBound = 709.0f;

319 break;

320 case LibFunc_expm1f:

321 UpperBound = 88.0f;

322 break;

323 case LibFunc_expm1l:

324 UpperBound = 11356.0f;

325 break;

326 default:

328 }

329

330 ++NumWrappedOneCond;

332}

333

334

335Value *LibCallsShrinkWrap::generateTwoRangeCond(CallInst *CI,

336 const LibFunc &Func) {

337 float UpperBound, LowerBound;

338 switch (Func) {

339 case LibFunc_cosh:

340 case LibFunc_sinh:

341 LowerBound = -710.0f;

342 UpperBound = 710.0f;

343 break;

344 case LibFunc_coshf:

345 case LibFunc_sinhf:

346 LowerBound = -89.0f;

347 UpperBound = 89.0f;

348 break;

349 case LibFunc_coshl:

350 case LibFunc_sinhl:

351 LowerBound = -11357.0f;

352 UpperBound = 11357.0f;

353 break;

354 case LibFunc_exp:

355 LowerBound = -745.0f;

356 UpperBound = 709.0f;

357 break;

358 case LibFunc_expf:

359 LowerBound = -103.0f;

360 UpperBound = 88.0f;

361 break;

362 case LibFunc_expl:

363 LowerBound = -11399.0f;

364 UpperBound = 11356.0f;

365 break;

366 case LibFunc_exp10:

367 LowerBound = -323.0f;

368 UpperBound = 308.0f;

369 break;

370 case LibFunc_exp10f:

371 LowerBound = -45.0f;

372 UpperBound = 38.0f;

373 break;

374 case LibFunc_exp10l:

375 LowerBound = -4950.0f;

376 UpperBound = 4932.0f;

377 break;

378 case LibFunc_exp2:

379 LowerBound = -1074.0f;

380 UpperBound = 1023.0f;

381 break;

382 case LibFunc_exp2f:

383 LowerBound = -149.0f;

384 UpperBound = 127.0f;

385 break;

386 case LibFunc_exp2l:

387 LowerBound = -16445.0f;

388 UpperBound = 11383.0f;

389 break;

390 default:

392 }

393

394 ++NumWrappedTwoCond;

396 LowerBound);

397}

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414Value *LibCallsShrinkWrap::generateCondForPow(CallInst *CI,

415 const LibFunc &Func) {

416

417 if (Func != LibFunc_pow) {

418 LLVM_DEBUG(dbgs() << "Not handled powf() and powl()\n");

419 return nullptr;

420 }

421

424

425

427 double D = CF->getValueAPF().convertToDouble();

429 LLVM_DEBUG(dbgs() << "Not handled pow(): constant base out of range\n");

430 return nullptr;

431 }

432

433 ++NumWrappedOneCond;

435 }

436

437

439 if (I) {

440 LLVM_DEBUG(dbgs() << "Not handled pow(): FP type base\n");

441 return nullptr;

442 }

443 unsigned Opcode = I->getOpcode();

444 if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {

445 unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();

446 float UpperV = 0.0f;

447 if (BW == 8)

448 UpperV = 128.0f;

449 else if (BW == 16)

450 UpperV = 64.0f;

451 else if (BW == 32)

452 UpperV = 32.0f;

453 else {

454 LLVM_DEBUG(dbgs() << "Not handled pow(): type too wide\n");

455 return nullptr;

456 }

457

458 ++NumWrappedTwoCond;

461 }

462 LLVM_DEBUG(dbgs() << "Not handled pow(): base not from integer convert\n");

463 return nullptr;

464}

465

466

467void LibCallsShrinkWrap::shrinkWrapCI(CallInst *CI, Value *Cond) {

468 assert(Cond != nullptr && "ShrinkWrapCI is not expecting an empty call inst");

469 MDNode *BranchWeights =

470 MDBuilder(CI->getContext()).createUnlikelyBranchWeights();

471

475 CallBB->setName("cdce.call");

477 assert(SuccBB && "The split block should have a single successor");

478 SuccBB->setName("cdce.end");

484}

485

486

487bool LibCallsShrinkWrap::perform(CallInst *CI) {

488 LibFunc Func;

490 assert(Callee && "perform() should apply to a non-empty callee");

492 assert(Func && "perform() is not expecting an empty function");

493

494 if (performCallDomainErrorOnly(CI, Func) || performCallRangeErrorOnly(CI, Func))

495 return true;

496 return performCallErrors(CI, Func);

497}

498

501 if (F.hasOptSize())

502 return false;

503 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);

504 LibCallsShrinkWrap CCDCE(TLI, DTU);

505 CCDCE.visit(F);

506 bool Changed = CCDCE.perform();

507

508

510 DTU.getDomTree().verify(DominatorTree::VerificationLevel::Fast));

512}

513

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

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

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

static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)

This is the interface for a simple mod/ref and alias analysis over globals.

FunctionAnalysisManager FAM

const SmallVectorImpl< MachineOperand > & Cond

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static APInt getMaxValue(unsigned numBits)

Gets maximum unsigned value of APInt for specific bit width.

LLVM_ABI const_iterator getFirstInsertionPt() const

Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...

const Function * getParent() const

Return the enclosing method, or null if none.

LLVM_ABI const BasicBlock * getSinglePredecessor() const

Return the predecessor of this block if it has a single predecessor block.

LLVM_ABI const BasicBlock * getSingleSuccessor() const

Return the successor of this block if it has a single successor.

bool isNoBuiltin() const

Return true if the call should not be treated as a call to a builtin.

Function * getCalledFunction() const

Returns the function called, or null if this is an indirect function invocation or the function signa...

Value * getArgOperand(unsigned i) const

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

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_OGE

0 0 1 1 True if ordered and greater than or equal

@ FCMP_OLE

0 1 0 1 True if ordered and less than or equal

Analysis pass which computes a DominatorTree.

bool verify(VerificationLevel VL=VerificationLevel::Full) const

verify - checks if the tree is correct.

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

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

DomTreeT & getDomTree()

Flush DomTree updates and return DomTree.

Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)

BasicBlock * GetInsertBlock() const

void setIsFPConstrained(bool IsCon)

Enable/Disable use of constrained floating point math.

LLVMContext & getContext() const

Base class for instruction visitors.

LLVM_ABI void removeFromParent()

This method unlinks 'this' from the containing basic block, but does not delete it.

LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)

Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...

PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)

Definition LibCallsShrinkWrap.cpp:514

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.

Analysis pass providing the TargetLibraryInfo.

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

bool has(LibFunc F) const

Tests whether a library function is available.

bool getLibFunc(StringRef funcName, LibFunc &F) const

Searches for a particular function name.

bool isX86_FP80Ty() const

Return true if this is x86 long double.

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

bool isDoubleTy() const

Return true if this is 'double', a 64-bit IEEE fp type.

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI void setName(const Twine &Name)

Change the name of the value.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

const ParentTy * getParent() const

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ BasicBlock

Various leaf nodes.

NodeAddr< FuncNode * > Func

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

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

LLVM_ABI raw_ostream & dbgs()

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

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >

LLVM_ABI Constant * ConstantFoldCastInstruction(unsigned opcode, Constant *V, Type *DestTy)

LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)

Split the containing block at the specified instruction - everything before SplitBefore stays in the ...

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.