LLVM: lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

26#include

27

28using namespace llvm;

29

30#define DEBUG_TYPE "partially-inline-libcalls"

31

32DEBUG_COUNTER(PILCounter, "partially-inline-libcalls-transform",

33 "Controls transformations in partially-inline-libcalls");

34

39

40

41 if (Call->onlyReadsMemory())

42 return false;

43

45 return false;

46

47

48

49

50

51

52

53

54

55

56

57

58

59 Type *Ty = Call->getType();

61

62

63

65 Builder.getTrue(), Call->getNextNode(), false,

66 nullptr, DTU);

67

68 auto *CurrBBTerm = cast(CurrBB.getTerminator());

69

70 cast(CurrBBTerm)->swapSuccessors();

71

72

77 Call->replaceAllUsesWith(Phi);

78

79

81 LibCallBB->setName("call.sqrt");

84 Builder.Insert(LibCall);

85

86

87

88 Call->setDoesNotAccessMemory();

89

90

95 ConstantFP::get(Ty, 0.0));

96 CurrBBTerm->setCondition(FCmp);

97

98

99 Phi->addIncoming(Call, &CurrBB);

100 Phi->addIncoming(LibCall, LibCallBB);

101

103 return true;

104}

105

110 std::optional DTU;

111 if (DT)

112 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);

113

114 bool Changed = false;

115

118 CurrBB = BB++;

119

121 II != IE; ++II) {

122 CallInst *Call = dyn_cast(&*II);

124

125 if (!Call || !(CalledFunc = Call->getCalledFunction()))

126 continue;

127

128 if (Call->isNoBuiltin() || Call->isStrictFP())

129 continue;

130

131 if (Call->isMustTailCall())

132 continue;

133

134

135

138 !TLI->getLibFunc(*CalledFunc, LF) || !TLI->has(LF))

139 continue;

140

141 switch (LF) {

142 case LibFunc_sqrtf:

143 case LibFunc_sqrt:

146 DTU ? &*DTU : nullptr, ORE))

147 break;

148 continue;

149 default:

150 continue;

151 }

152

153 Changed = true;

154 break;

155 }

156 }

157

158 return Changed;

159}

160

171 return PA;

172}

173

174namespace {

175class PartiallyInlineLibCallsLegacyPass : public FunctionPass {

176public:

177 static char ID;

178

179 PartiallyInlineLibCallsLegacyPass() : FunctionPass(ID) {

182 }

183

184 void getAnalysisUsage(AnalysisUsage &AU) const override {

189 FunctionPass::getAnalysisUsage(AU);

190 }

191

193 if (skipFunction(F))

194 return false;

195

197 &getAnalysis().getTLI(F);

199 &getAnalysis().getTTI(F);

201 if (auto *DTWP = getAnalysisIfAvailable())

202 DT = &DTWP->getDomTree();

203 auto *ORE = &getAnalysis().getORE();

205 }

206};

207}

208

209char PartiallyInlineLibCallsLegacyPass::ID = 0;

211 "partially-inline-libcalls",

212 "Partially inline calls to library functions", false,

213 false)

221

223 return new PartiallyInlineLibCallsLegacyPass();

224}

Lower uses of LDS variables from non kernel functions

This file provides an implementation of debug counters.

#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)

static bool runOnFunction(Function &F, bool PostInlining)

uint64_t IntrinsicInst * II

static bool runPartiallyInlineLibCalls(Function &F, TargetLibraryInfo *TLI, const TargetTransformInfo *TTI, DominatorTree *DT, OptimizationRemarkEmitter *ORE)

static bool optimizeSQRT(CallInst *Call, Function *CalledFunc, BasicBlock &CurrBB, Function::iterator &BB, const TargetTransformInfo *TTI, DomTreeUpdater *DTU, OptimizationRemarkEmitter *ORE)

partially inline libcalls

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

Replace intrinsics with calls to vector library

This pass exposes codegen information to IR-level passes.

A container for analyses that lazily runs them and caches their results.

PassT::Result * getCachedResult(IRUnitT &IR) const

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

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

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

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

InstListType::iterator iterator

Instruction iterators...

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

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

static bool shouldExecute(unsigned CounterName)

Analysis pass which computes a DominatorTree.

Legacy analysis pass which computes a DominatorTree.

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

FunctionPass class - This class is used to implement most global optimizations.

BasicBlockListType::iterator iterator

bool hasLocalLinkage() const

Value * CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)

ConstantInt * getTrue()

Get the constant value for i1 true.

PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")

InstTy * Insert(InstTy *I, const Twine &Name="") const

Insert and return the specified instruction.

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

Value * CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY

Return the specified successor. This instruction must be a terminator.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

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.

void preserve()

Mark an analysis as preserved.

Analysis pass providing the TargetTransformInfo.

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.

Wrapper pass for TargetTransformInfo.

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

bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const

Return true if it is faster to check if a floating-point value is NaN (or not-NaN) versus a compariso...

bool haveFastSqrt(Type *Ty) const

Return true if the hardware has a fast square-root instruction.

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

void setName(const Twine &Name)

Change the name of the value.

StringRef getName() const

Return a constant reference to the value's name.

const ParentTy * getParent() const

self_iterator getIterator()

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

void initializePartiallyInlineLibCallsLegacyPassPass(PassRegistry &)

FunctionPass * createPartiallyInlineLibCallsPass()

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 ...