LLVM: lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

20

21namespace {

22using namespace llvm;

26

30 else

31 return false;

32 };

33 for (auto &BB : F)

34 if (findCallInst(*BB.getTerminator()) ||

35 llvm::any_of(BB.instructionsWithoutDebug(), findCallInst))

37

38 return BBs;

39}

40}

41

42

43

44

45namespace llvm {

46namespace orc {

47

48

51 assert(BB != nullptr && "Traversing Null BB to find calls?");

52

54 auto CalledValue = Call->getCalledOperand()->stripPointerCasts();

57 };

61

64}

65

71

72

73

74size_t BlockFreqQuery::numBBToGet(size_t numBB) {

75

76 if (numBB < 4)

77 return numBB;

78

79 else if (numBB < 20)

80 return (numBB / 2);

81 else

82 return (numBB / 2) + (numBB / 4);

83}

84

89

92 PB.registerFunctionAnalyses(FAM);

93

94 auto IBBs = findBBwithCalls(F);

95

96 if (IBBs.empty())

97 return std::nullopt;

98

100

101 for (const auto I : IBBs)

102 BBFreqs.push_back({I, BFI.getBlockFreq(I).getFrequency()});

103

104 assert(IBBs.size() == BBFreqs.size() && "BB Count Mismatch");

105

106 llvm::sort(BBFreqs, [](decltype(BBFreqs)::const_reference BBF,

107 decltype(BBFreqs)::const_reference BBS) {

108 return BBF.second > BBS.second ? true : false;

109 });

110

111

112 auto Topk = numBBToGet(BBFreqs.size());

113

114 for (size_t i = 0; i < Topk; i++)

115 findCalles(BBFreqs[i].first, Calles);

116

117 assert(!Calles.empty() && "Running Analysis on Function with no calls?");

118

119 CallerAndCalles.insert({F.getName(), std::move(Calles)});

120

121 return CallerAndCalles;

122}

123

124

125std::size_t SequenceBBQuery::getHottestBlocks(std::size_t TotalBlocks) {

126 if (TotalBlocks == 1)

127 return TotalBlocks;

128 return TotalBlocks / 2;

129}

130

131

133SequenceBBQuery::rearrangeBB(const Function &F, const BlockListTy &BBList) {

135

136 for (auto &Block : F)

139

140 assert(RearrangedBBSet.size() == BBList.size() &&

141 "BasicBlock missing while rearranging?");

142 return RearrangedBBSet;

143}

144

145void SequenceBBQuery::traverseToEntryBlock(const BasicBlock *AtBB,

146 const BlockListTy &CallerBlocks,

147 const BackEdgesInfoTy &BackEdgesInfo,

151 if (Itr != VisitedBlocks.end()) {

152 if (!Itr->second.Upward)

153 return;

154 Itr->second.Upward = false;

155 } else {

156

157 WalkDirection BlockHint;

158 BlockHint.Upward = false;

159

161 BlockHint.CallerBlock = true;

163 }

164

166

167

168

169 if (PIt == EIt)

170 return;

171

172 DenseSet<const BasicBlock *> PredSkipNodes;

173

174

175

176 for (auto &I : BackEdgesInfo)

177 if (I.second == AtBB)

178 PredSkipNodes.insert(I.first);

179

180

181 for (; PIt != EIt; ++PIt)

182

183 if (BPI->isEdgeHot(*PIt, AtBB) && !PredSkipNodes.count(*PIt))

184 traverseToEntryBlock(*PIt, CallerBlocks, BackEdgesInfo, BPI,

186}

187

188void SequenceBBQuery::traverseToExitBlock(const BasicBlock *AtBB,

189 const BlockListTy &CallerBlocks,

190 const BackEdgesInfoTy &BackEdgesInfo,

191 const BranchProbabilityInfo *BPI,

195 if (!Itr->second.Downward)

196 return;

197 Itr->second.Downward = false;

198 } else {

199

200 WalkDirection BlockHint;

201 BlockHint.Downward = false;

202

204 BlockHint.CallerBlock = true;

206 }

207

209 if (PIt == EIt)

210 return;

211

212

213 DenseSet<const BasicBlock *> SuccSkipNodes;

214

215

216

217 for (auto &I : BackEdgesInfo)

218 if (I.first == AtBB)

219 SuccSkipNodes.insert(I.second);

220

221 for (; PIt != EIt; ++PIt)

222 if (BPI->isEdgeHot(AtBB, *PIt) && !SuccSkipNodes.count(*PIt))

223 traverseToExitBlock(*PIt, CallerBlocks, BackEdgesInfo, BPI,

225}

226

227

228

229

231SequenceBBQuery::queryCFG(Function &F, const BlockListTy &CallerBlocks) {

232

236

237 PassBuilder PB;

240

241 auto &BFI = FAM.getResult(F);

242

244

245 for (const auto I : CallerBlocks)

246 BBFreqs.push_back({I, BFI.getBlockFreq(I).getFrequency()});

247

248 llvm::sort(BBFreqs, [](decltype(BBFreqs)::const_reference Bbf,

249 decltype(BBFreqs)::const_reference Bbs) {

250 return Bbf.second > Bbs.second;

251 });

252

254 HotBlocksRef =

255 HotBlocksRef.drop_back(BBFreqs.size() - getHottestBlocks(BBFreqs.size()));

256

257 BranchProbabilityInfo *BPI =

259

260

261

262

263

264 for (auto I : HotBlocksRef) {

265 traverseToEntryBlock(I.first, CallerBlocks, BackEdgesInfo, BPI,

267 traverseToExitBlock(I.first, CallerBlocks, BackEdgesInfo, BPI,

269 }

270

273 if (I.second.CallerBlock)

274 MinCallerBlocks.push_back(std::move(I.first));

275

276 return rearrangeBB(F, MinCallerBlocks);

277}

278

280

285

286 CallerBlocks = findBBwithCalls(F);

287 if (CallerBlocks.empty())

288 return std::nullopt;

289

291 SequencedBlocks = rearrangeBB(F, CallerBlocks);

292 else

293 SequencedBlocks = queryCFG(F, CallerBlocks);

294

295 for (const auto *BB : SequencedBlocks)

297

298 CallerAndCalles.insert({F.getName(), std::move(Calles)});

299 return CallerAndCalles;

300}

301

302}

303}

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

SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks

This file defines the DenseMap class.

This header defines various interfaces for pass management in LLVM.

static const Function * getCalledFunction(const Value *V)

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)

This file defines the SmallVector class.

Contains the Analyses and Result Interpretation to select likely functions to Speculatively compile b...

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.

LLVM Basic Block Representation.

LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const

Return a const iterator range over the instructions in the block, skipping any debug instructions.

LLVM_ABI const BasicBlock * getSingleSuccessor() const

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

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

Analysis pass which computes BlockFrequencyInfo.

Analysis providing branch probability information.

LLVM_ABI bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const

Test if an edge is hot relative to other out-edges of the Src.

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

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Implements a dense probed hash-table based set.

This class provides access to building LLVM's passes.

LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM)

Registers all available function analysis passes.

iterator find(ConstPtrType Ptr) const

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

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

std::pair< iterator, bool > insert(const ValueT &V)

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

LLVM_ABI ResultTy operator()(Function &F)

Definition SpeculateAnalyses.cpp:85

LLVM_ABI ResultTy operator()(Function &F)

Definition SpeculateAnalyses.cpp:279

SmallVector< std::pair< const BasicBlock *, uint64_t >, 8 > BlockFreqInfoTy

DenseMap< const BasicBlock *, WalkDirection > VisitedBlocksInfoTy

SmallVector< const BasicBlock *, 8 > BlockListTy

SmallVector< std::pair< const BasicBlock *, const BasicBlock * >, 8 > BackEdgesInfoTy

std::optional< DenseMap< StringRef, DenseSet< StringRef > > > ResultTy

LLVM_ABI bool isStraightLine(const Function &F)

Definition SpeculateAnalyses.cpp:66

LLVM_ABI void findCalles(const BasicBlock *, DenseSet< StringRef > &)

Definition SpeculateAnalyses.cpp:49

Interfaces for registering analysis passes, producing common pass manager configurations,...

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.

auto pred_end(const MachineBasicBlock *BB)

decltype(auto) dyn_cast(const From &Val)

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

PredIterator< const BasicBlock, Value::const_user_iterator > const_pred_iterator

bool any_of(R &&range, UnaryPredicate P)

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

void sort(IteratorTy Start, IteratorTy End)

RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)

RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)

ArrayRef(const T &OneElt) -> ArrayRef< T >

auto pred_begin(const MachineBasicBlock *BB)

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

SuccIterator< const Instruction, const BasicBlock > const_succ_iterator

LLVM_ABI void FindFunctionBackedges(const Function &F, SmallVectorImpl< std::pair< const BasicBlock *, const BasicBlock * > > &Result)

Analyze the specified function to find all of the loop backedges in the function and return them.