LLVM 24.0.0git
MergeICmps.cpp
Go to the documentation of this file.
1//===- MergeICmps.cpp - Optimize chains of integer comparisons ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass turns chains of integer comparisons into memcmp (the memcmp is
10// later typically inlined as a chain of efficient hardware comparisons). This
11// typically benefits c++ member or nonmember operator==().
12//
13// The basic idea is to replace a longer chain of integer comparisons loaded
14// from contiguous memory locations into a shorter chain of larger integer
15// comparisons. Benefits are double:
16// - There are less jumps, and therefore less opportunities for mispredictions
17// and I-cache misses.
18// - Code size is smaller, both because jumps are removed and because the
19// encoding of a 2*n byte compare is smaller than that of two n-byte
20// compares.
21//
22// Example:
23//
24// struct S {
25// int a;
26// char b;
27// char c;
28// uint16_t d;
29// bool operator==(const S& o) const {
30// return a == o.a && b == o.b && c == o.c && d == o.d;
31// }
32// };
33//
34// Is optimized as :
35//
36// bool S::operator==(const S& o) const {
37// return memcmp(this, &o, 8) == 0;
38// }
39//
40// Which will later be expanded (ExpandMemCmp) as a single 8-bytes icmp.
41//
42//===----------------------------------------------------------------------===//
43
48#include "llvm/Analysis/Loads.h"
51#include "llvm/IR/Dominators.h"
52#include "llvm/IR/Function.h"
53#include "llvm/IR/IRBuilder.h"
54#include "llvm/IR/Instruction.h"
58#include <algorithm>
59#include <numeric>
60#include <utility>
61#include <vector>
62
63using namespace llvm;
64
65#define DEBUG_TYPE "mergeicmps"
66
67namespace {
68
69// A BCE atom "Binary Compare Expression Atom" represents an integer load
70// that is a constant offset from a base value, e.g. `a` or `o.c` in the example
71// at the top.
72struct BCEAtom {
73 BCEAtom() = default;
74 BCEAtom(GetElementPtrInst *GEP, LoadInst *LoadI, int BaseId, APInt Offset)
75 : GEP(GEP), LoadI(LoadI), BaseId(BaseId), Offset(std::move(Offset)) {}
76
77 BCEAtom(const BCEAtom &) = delete;
78 BCEAtom &operator=(const BCEAtom &) = delete;
79
80 BCEAtom(BCEAtom &&that) = default;
81 BCEAtom &operator=(BCEAtom &&that) {
82 if (this == &that)
83 return *this;
84 GEP = that.GEP;
85 LoadI = that.LoadI;
86 BaseId = that.BaseId;
87 Offset = std::move(that.Offset);
88 return *this;
89 }
90
91 // We want to order BCEAtoms by (Base, Offset). However we cannot use
92 // the pointer values for Base because these are non-deterministic.
93 // To make sure that the sort order is stable, we first assign to each atom
94 // base value an index based on its order of appearance in the chain of
95 // comparisons. We call this index `BaseOrdering`. For example, for:
96 // b[3] == c[2] && a[1] == d[1] && b[4] == c[3]
97 // | block 1 | | block 2 | | block 3 |
98 // b gets assigned index 0 and a index 1, because b appears as LHS in block 1,
99 // which is before block 2.
100 // We then sort by (BaseOrdering[LHS.Base()], LHS.Offset), which is stable.
101 bool operator<(const BCEAtom &O) const {
102 return BaseId != O.BaseId ? BaseId < O.BaseId : Offset.slt(O.Offset);
103 }
104
105 GetElementPtrInst *GEP = nullptr;
106 LoadInst *LoadI = nullptr;
107 unsigned BaseId = 0;
109};
110
111// A class that assigns increasing ids to values in the order in which they are
112// seen. See comment in `BCEAtom::operator<()``.
113class BaseIdentifier {
114public:
115 // Returns the id for value `Base`, after assigning one if `Base` has not been
116 // seen before.
117 int getBaseId(const Value *Base) {
118 assert(Base && "invalid base");
119 const auto Insertion = BaseToIndex.try_emplace(Base, Order);
120 if (Insertion.second)
121 ++Order;
122 return Insertion.first->second;
123 }
124
125private:
126 unsigned Order = 1;
127 DenseMap<const Value*, int> BaseToIndex;
128};
129} // namespace
130
131// If this value is a load from a constant offset w.r.t. a base address, and
132// there are no other users of the load or address, returns the base address and
133// the offset.
134static BCEAtom visitICmpLoadOperand(Value *const Val, BaseIdentifier &BaseId) {
135 auto *const LoadI = dyn_cast<LoadInst>(Val);
136 if (!LoadI)
137 return {};
138 LLVM_DEBUG(dbgs() << "load\n");
139 if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) {
140 LLVM_DEBUG(dbgs() << "used outside of block\n");
141 return {};
142 }
143 // Do not optimize atomic loads to non-atomic memcmp
144 if (!LoadI->isSimple()) {
145 LLVM_DEBUG(dbgs() << "volatile or atomic\n");
146 return {};
147 }
148 Value *Addr = LoadI->getOperand(0);
149 if (Addr->getType()->getPointerAddressSpace() != 0) {
150 LLVM_DEBUG(dbgs() << "from non-zero AddressSpace\n");
151 return {};
152 }
153
154 // This pass only works correctly when all of the compared elements have
155 // byte-multiple sizes.
156 const auto &DL = LoadI->getDataLayout();
157 if (!DL.typeSizeEqualsStoreSize(LoadI->getType())) {
158 LLVM_DEBUG(dbgs() << "type size is not a byte multiple\n");
159 return {};
160 }
161
162 APInt Offset = APInt(DL.getIndexTypeSizeInBits(Addr->getType()), 0);
163 Value *Base = Addr;
164 auto *GEP = dyn_cast<GetElementPtrInst>(Addr);
165 if (GEP) {
166 LLVM_DEBUG(dbgs() << "GEP\n");
167 if (GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
168 LLVM_DEBUG(dbgs() << "used outside of block\n");
169 return {};
170 }
171 if (!GEP->accumulateConstantOffset(DL, Offset))
172 return {};
173 Base = GEP->getPointerOperand();
174 }
175 return BCEAtom(GEP, LoadI, BaseId.getBaseId(Base), Offset);
176}
177
178namespace {
179// A comparison between two BCE atoms, e.g. `a == o.a` in the example at the
180// top.
181// Note: the terminology is misleading: the comparison is symmetric, so there
182// is no real {l/r}hs. What we want though is to have the same base on the
183// left (resp. right), so that we can detect consecutive loads. To ensure this
184// we put the smallest atom on the left.
185struct BCECmp {
186 BCEAtom Lhs;
187 BCEAtom Rhs;
188 int SizeBits;
189 const ICmpInst *CmpI;
190
191 BCECmp(BCEAtom L, BCEAtom R, int SizeBits, const ICmpInst *CmpI)
192 : Lhs(std::move(L)), Rhs(std::move(R)), SizeBits(SizeBits), CmpI(CmpI) {
193 if (Rhs < Lhs) std::swap(Rhs, Lhs);
194 }
195};
196
197// A basic block with a comparison between two BCE atoms.
198// The block might do extra work besides the atom comparison, in which case
199// doesOtherWork() returns true. Under some conditions, the block can be
200// split into the atom comparison part and the "other work" part
201// (see canSplit()).
202class BCECmpBlock {
203 public:
204 typedef SmallDenseSet<const Instruction *, 8> InstructionSet;
205
206 BCECmpBlock(BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
207 : BB(BB), BlockInsts(std::move(BlockInsts)), Cmp(std::move(Cmp)) {}
208
209 const BCEAtom &Lhs() const { return Cmp.Lhs; }
210 const BCEAtom &Rhs() const { return Cmp.Rhs; }
211 int SizeBits() const { return Cmp.SizeBits; }
212
213 DebugLoc getCmpDebugLoc() const { return Cmp.CmpI->getDebugLoc(); }
214
215 // Returns true if the block does other works besides comparison.
216 bool doesOtherWork() const;
217
218 // Returns true if the non-BCE-cmp instructions can be separated from BCE-cmp
219 // instructions in the block.
220 // SplitAt is set to the instruction before which the block will have to be
221 // split.
222 bool canSplit(AliasAnalysis &AA, Instruction *&SplitAt) const;
223
224 // Return true if this all the relevant instructions in the BCE-cmp-block can
225 // be sunk below this instruction. By doing this, we know we can separate the
226 // BCE-cmp-block instructions from the non-BCE-cmp-block instructions in the
227 // block.
228 bool canSinkBCECmpInst(const Instruction *, AliasAnalysis &AA) const;
229
230 // We can separate the BCE-cmp-block instructions and the non-BCE-cmp-block
231 // instructions. Split the old block and move all non-BCE-cmp-insts into the
232 // new parent block.
233 void split(BasicBlock *NewParent, AliasAnalysis &AA) const;
234
235 // The basic block where this comparison happens.
236 BasicBlock *BB;
237 // Instructions relating to the BCECmp and branch.
238 InstructionSet BlockInsts;
239 // The block requires splitting.
240 bool RequireSplit = false;
241 // Original order of this block in the chain.
242 unsigned OrigOrder = 0;
243
244private:
245 BCECmp Cmp;
246};
247} // namespace
248
249bool BCECmpBlock::canSinkBCECmpInst(const Instruction *Inst,
250 AliasAnalysis &AA) const {
251 // If this instruction may clobber the loads and is in middle of the BCE cmp
252 // block instructions, then bail for now.
253 if (Inst->mayWriteToMemory()) {
254 auto MayClobber = [&](LoadInst *LI) {
255 // If a potentially clobbering instruction comes before the load,
256 // we can still safely sink the load.
257 return (Inst->getParent() != LI->getParent() || !Inst->comesBefore(LI)) &&
259 };
260 if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
261 return false;
262 }
263 // Make sure this instruction does not use any of the BCE cmp block
264 // instructions as operand.
265 return llvm::none_of(Inst->operands(), [&](const Value *Op) {
266 const Instruction *OpI = dyn_cast<Instruction>(Op);
267 return OpI && BlockInsts.contains(OpI);
268 });
269}
270
271void BCECmpBlock::split(BasicBlock *NewParent, AliasAnalysis &AA) const {
272 llvm::SmallVector<Instruction *, 4> OtherInsts;
273 for (Instruction &Inst : *BB) {
274 if (BlockInsts.count(&Inst))
275 continue;
276 assert(canSinkBCECmpInst(&Inst, AA) && "Split unsplittable block");
277 // This is a non-BCE-cmp-block instruction. And it can be separated
278 // from the BCE-cmp-block instruction.
279 OtherInsts.push_back(&Inst);
280 }
281
282 // Do the actual spliting.
283 for (Instruction *Inst : reverse(OtherInsts))
284 Inst->moveBeforePreserving(*NewParent, NewParent->begin());
285}
286
287bool BCECmpBlock::canSplit(AliasAnalysis &AA, Instruction *&SplitAt) const {
288 SplitAt = nullptr;
289 for (Instruction &Inst : *BB) {
290 if (!BlockInsts.count(&Inst)) {
291 SplitAt = Inst.getNextNode();
292 if (!canSinkBCECmpInst(&Inst, AA))
293 return false;
294 }
295 }
296 return true;
297}
298
299bool BCECmpBlock::doesOtherWork() const {
300 // TODO(courbet): Can we allow some other things ? This is very conservative.
301 // We might be able to get away with anything does not have any side
302 // effects outside of the basic block.
303 // Note: The GEPs and/or loads are not necessarily in the same block.
304 for (const Instruction &Inst : *BB) {
305 if (!BlockInsts.count(&Inst))
306 return true;
307 }
308 return false;
309}
310
311// Visit the given comparison. If this is a comparison between two valid
312// BCE atoms, returns the comparison.
313static std::optional<BCECmp>
314visitICmp(const ICmpInst *const CmpI,
315 const ICmpInst::Predicate ExpectedPredicate, BaseIdentifier &BaseId) {
316 // The comparison can only be used once:
317 // - For intermediate blocks, as a branch condition.
318 // - For the final block, as an incoming value for the Phi.
319 // If there are any other uses of the comparison, we cannot merge it with
320 // other comparisons as we would create an orphan use of the value.
321 if (!CmpI->hasOneUse()) {
322 LLVM_DEBUG(dbgs() << "cmp has several uses\n");
323 return std::nullopt;
324 }
325 if (CmpI->getPredicate() != ExpectedPredicate)
326 return std::nullopt;
327 LLVM_DEBUG(dbgs() << "cmp "
328 << (ExpectedPredicate == ICmpInst::ICMP_EQ ? "eq" : "ne")
329 << "\n");
330 auto Lhs = visitICmpLoadOperand(CmpI->getOperand(0), BaseId);
331 if (!Lhs.BaseId)
332 return std::nullopt;
333 auto Rhs = visitICmpLoadOperand(CmpI->getOperand(1), BaseId);
334 if (!Rhs.BaseId)
335 return std::nullopt;
336
337 const auto &DL = CmpI->getDataLayout();
338 return BCECmp(std::move(Lhs), std::move(Rhs),
339 DL.getTypeSizeInBits(CmpI->getOperand(0)->getType()), CmpI);
340}
341
342// Visit the given comparison block. If this is a comparison between two valid
343// BCE atoms, returns the comparison.
344static std::optional<BCECmpBlock>
346 const BasicBlock *const PhiBlock, BaseIdentifier &BaseId) {
347 if (Block->empty())
348 return std::nullopt;
349 auto *Term = Block->getTerminator();
350 Value *Cond;
351 ICmpInst::Predicate ExpectedPredicate;
352 if (isa<UncondBrInst>(Term)) {
353 // In this case, we expect an incoming value which is the result of the
354 // comparison. This is the last link in the chain of comparisons (note
355 // that this does not mean that this is the last incoming value, blocks
356 // can be reordered).
357 Cond = Val;
358 ExpectedPredicate = ICmpInst::ICMP_EQ;
359 } else if (auto *BranchI = dyn_cast<CondBrInst>(Term)) {
360 // In this case, we expect a constant incoming value (the comparison is
361 // chained).
362 const auto *const Const = cast<ConstantInt>(Val);
363 LLVM_DEBUG(dbgs() << "const\n");
364 if (!Const->isZero())
365 return std::nullopt;
366 LLVM_DEBUG(dbgs() << "false\n");
367 assert(BranchI->getNumSuccessors() == 2 && "expecting a cond branch");
368 BasicBlock *const FalseBlock = BranchI->getSuccessor(1);
369 Cond = BranchI->getCondition();
370 ExpectedPredicate =
371 FalseBlock == PhiBlock ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
372 } else
373 return std::nullopt;
374
375 auto *CmpI = dyn_cast<ICmpInst>(Cond);
376 if (!CmpI)
377 return std::nullopt;
378 LLVM_DEBUG(dbgs() << "icmp\n");
379
380 std::optional<BCECmp> Result = visitICmp(CmpI, ExpectedPredicate, BaseId);
381 if (!Result)
382 return std::nullopt;
383
384 BCECmpBlock::InstructionSet BlockInsts(
385 {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, Term});
386 if (Result->Lhs.GEP)
387 BlockInsts.insert(Result->Lhs.GEP);
388 if (Result->Rhs.GEP)
389 BlockInsts.insert(Result->Rhs.GEP);
390 return BCECmpBlock(std::move(*Result), Block, BlockInsts);
391}
392
393static inline void enqueueBlock(std::vector<BCECmpBlock> &Comparisons,
394 BCECmpBlock &&Comparison) {
395 LLVM_DEBUG(dbgs() << "Block '" << Comparison.BB->getName()
396 << "': Found cmp of " << Comparison.SizeBits()
397 << " bits between " << Comparison.Lhs().BaseId << " + "
398 << Comparison.Lhs().Offset << " and "
399 << Comparison.Rhs().BaseId << " + "
400 << Comparison.Rhs().Offset << "\n");
401 LLVM_DEBUG(dbgs() << "\n");
402 Comparison.OrigOrder = Comparisons.size();
403 Comparisons.push_back(std::move(Comparison));
404}
405
406namespace {
407// A chain of comparisons.
408class BCECmpChain {
409public:
410 using ContiguousBlocks = std::vector<BCECmpBlock>;
411
412 BCECmpChain(const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
413 AliasAnalysis &AA);
414
415 bool isDereferenceable();
416
417 bool simplify(const TargetLibraryInfo &TLI, AliasAnalysis &AA,
418 DomTreeUpdater &DTU);
419
420 bool atLeastOneMerged() const {
421 return any_of(MergedBlocks_,
422 [](const auto &Blocks) { return Blocks.size() > 1; });
423 }
424
425private:
426 PHINode &Phi_;
427 // The list of all blocks in the chain, grouped by contiguity.
428 std::vector<ContiguousBlocks> MergedBlocks_;
429 // The original entry block (before sorting);
430 BasicBlock *EntryBlock_;
431 // The instruction before which the entry block needs to be split (or null
432 // if no splitting required).
433 Instruction *SplitAt = nullptr;
434};
435} // namespace
436
437static bool areContiguous(const BCECmpBlock &First, const BCECmpBlock &Second) {
438 return First.Lhs().BaseId == Second.Lhs().BaseId &&
439 First.Rhs().BaseId == Second.Rhs().BaseId &&
440 First.Lhs().Offset + First.SizeBits() / 8 == Second.Lhs().Offset &&
441 First.Rhs().Offset + First.SizeBits() / 8 == Second.Rhs().Offset;
442}
443
444static unsigned getMinOrigOrder(const BCECmpChain::ContiguousBlocks &Blocks) {
445 unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
446 for (const BCECmpBlock &Block : Blocks)
447 MinOrigOrder = std::min(MinOrigOrder, Block.OrigOrder);
448 return MinOrigOrder;
449}
450
451/// Given a chain of comparison blocks, groups the blocks into contiguous
452/// ranges that can be merged together into a single comparison.
453static std::vector<BCECmpChain::ContiguousBlocks>
454mergeBlocks(std::vector<BCECmpBlock> &&Blocks) {
455 std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
456
457 // Sort to detect continuous offsets.
458 llvm::sort(Blocks,
459 [](const BCECmpBlock &LhsBlock, const BCECmpBlock &RhsBlock) {
460 return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
461 std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
462 });
463
464 BCECmpChain::ContiguousBlocks *LastMergedBlock = nullptr;
465 for (BCECmpBlock &Block : Blocks) {
466 if (!LastMergedBlock || !areContiguous(LastMergedBlock->back(), Block)) {
467 MergedBlocks.emplace_back();
468 LastMergedBlock = &MergedBlocks.back();
469 } else {
470 LLVM_DEBUG(dbgs() << "Merging block " << Block.BB->getName() << " into "
471 << LastMergedBlock->back().BB->getName() << "\n");
472 }
473 LastMergedBlock->push_back(std::move(Block));
474 }
475
476 // While we allow reordering for merging, do not reorder unmerged comparisons.
477 // Doing so may introduce branch on poison.
478 llvm::sort(MergedBlocks, [](const BCECmpChain::ContiguousBlocks &LhsBlocks,
479 const BCECmpChain::ContiguousBlocks &RhsBlocks) {
480 return getMinOrigOrder(LhsBlocks) < getMinOrigOrder(RhsBlocks);
481 });
482
483 return MergedBlocks;
484}
485
486BCECmpChain::BCECmpChain(const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
487 AliasAnalysis &AA)
488 : Phi_(Phi) {
489 assert(!Blocks.empty() && "a chain should have at least one block");
490 // Now look inside blocks to check for BCE comparisons.
491 std::vector<BCECmpBlock> Comparisons;
492 BaseIdentifier BaseId;
493 for (BasicBlock *const Block : Blocks) {
494 assert(Block && "invalid block");
495 if (Block->hasAddressTaken()) {
496 LLVM_DEBUG(dbgs() << "cannot merge blocks with blockaddress\n");
497 return;
498 }
499 std::optional<BCECmpBlock> Comparison = visitCmpBlock(
500 Phi.getIncomingValueForBlock(Block), Block, Phi.getParent(), BaseId);
501 if (!Comparison) {
502 LLVM_DEBUG(dbgs() << "chain with invalid BCECmpBlock, no merge.\n");
503 return;
504 }
505 if (Comparison->doesOtherWork()) {
506 LLVM_DEBUG(dbgs() << "block '" << Comparison->BB->getName()
507 << "' does extra work besides compare\n");
508 if (Comparisons.empty()) {
509 // This is the initial block in the chain, in case this block does other
510 // work, we can try to split the block and move the irrelevant
511 // instructions to the predecessor.
512 //
513 // If this is not the initial block in the chain, splitting it wont
514 // work.
515 //
516 // As once split, there will still be instructions before the BCE cmp
517 // instructions that do other work in program order, i.e. within the
518 // chain before sorting. Unless we can abort the chain at this point
519 // and start anew.
520 //
521 // NOTE: we only handle blocks a with single predecessor for now.
522 if (Comparison->canSplit(AA, SplitAt)) {
524 << "Split initial block '" << Comparison->BB->getName()
525 << "' that does extra work besides compare\n");
526 Comparison->RequireSplit = true;
527 enqueueBlock(Comparisons, std::move(*Comparison));
528 } else {
529 SplitAt = nullptr;
531 << "ignoring initial block '" << Comparison->BB->getName()
532 << "' that does extra work besides compare\n");
533 }
534 continue;
535 }
536 // TODO(courbet): Right now we abort the whole chain. We could be
537 // merging only the blocks that don't do other work and resume the
538 // chain from there. For example:
539 // if (a[0] == b[0]) { // bb1
540 // if (a[1] == b[1]) { // bb2
541 // some_value = 3; //bb3
542 // if (a[2] == b[2]) { //bb3
543 // do a ton of stuff //bb4
544 // }
545 // }
546 // }
547 //
548 // This is:
549 //
550 // bb1 --eq--> bb2 --eq--> bb3* -eq--> bb4 --+
551 // \ \ \ \
552 // ne ne ne \
553 // \ \ \ v
554 // +------------+-----------+----------> bb_phi
555 //
556 // We can only merge the first two comparisons, because bb3* does
557 // "other work" (setting some_value to 3).
558 // We could still merge bb1 and bb2 though.
559 return;
560 }
561 enqueueBlock(Comparisons, std::move(*Comparison));
562 }
563
564 // It is possible we have no suitable comparison to merge.
565 if (Comparisons.empty()) {
566 LLVM_DEBUG(dbgs() << "chain with no BCE basic blocks, no merge\n");
567 return;
568 }
569 EntryBlock_ = Comparisons[0].BB;
570 MergedBlocks_ = mergeBlocks(std::move(Comparisons));
571}
572
573namespace {
574
575// A class to compute the name of a set of merged basic blocks.
576// This is optimized for the common case of no block names.
577class MergedBlockName {
578 // Storage for the uncommon case of several named blocks.
579 SmallString<16> Scratch;
580
581public:
582 explicit MergedBlockName(ArrayRef<BCECmpBlock> Comparisons)
583 : Name(makeName(Comparisons)) {}
584 const StringRef Name;
585
586private:
587 StringRef makeName(ArrayRef<BCECmpBlock> Comparisons) {
588 assert(!Comparisons.empty() && "no basic block");
589 // Fast path: only one block, or no names at all.
590 if (Comparisons.size() == 1)
591 return Comparisons[0].BB->getName();
592 const int size = std::accumulate(Comparisons.begin(), Comparisons.end(), 0,
593 [](int i, const BCECmpBlock &Cmp) {
594 return i + Cmp.BB->getName().size();
595 });
596 if (size == 0)
597 return StringRef("", 0);
598
599 // Slow path: at least two blocks, at least one block with a name.
600 Scratch.clear();
601 // We'll have `size` bytes for name and `Comparisons.size() - 1` bytes for
602 // separators.
603 Scratch.reserve(size + Comparisons.size() - 1);
604 const auto append = [this](StringRef str) {
605 Scratch.append(str.begin(), str.end());
606 };
607 append(Comparisons[0].BB->getName());
608 for (int I = 1, E = Comparisons.size(); I < E; ++I) {
609 const BasicBlock *const BB = Comparisons[I].BB;
610 if (!BB->getName().empty()) {
611 append("+");
612 append(BB->getName());
613 }
614 }
615 return Scratch.str();
616 }
617};
618} // namespace
619
620/// Determine the branch weights for the resulting conditional branch, resulting
621/// after merging \p Comparisons.
622static std::optional<SmallVector<uint32_t, 2>>
624 assert(!Comparisons.empty());
625 if (Comparisons.size() == 1) {
627 if (!extractBranchWeights(*Comparisons[0].BB->getTerminator(), Weights))
628 return std::nullopt;
629 return Weights;
630 }
631 // The probability to go to the phi block is the disjunction of the
632 // probability to go to the phi block from the individual Comparisons. We'll
633 // swap the weights because `getDisjunctionWeights` computes the disjunction
634 // for the "true" branch, then swap back.
635 SmallVector<uint64_t, 2> Weights{0, 1};
636 // At this point, Weights encodes "0-probability" for the "true" side.
637 for (const auto &C : Comparisons) {
639 if (!extractBranchWeights(*C.BB->getTerminator(), W))
640 return std::nullopt;
641
642 std::swap(W[0], W[1]);
643 Weights = getDisjunctionWeights(Weights, W);
644 }
645 std::swap(Weights[0], Weights[1]);
646 return fitWeights(Weights);
647}
648
649// Merges the given contiguous comparison blocks into one memcmp block.
651 BasicBlock *const InsertBefore,
652 BasicBlock *const NextCmpBlock,
653 PHINode &Phi, const TargetLibraryInfo &TLI,
655 assert(!Comparisons.empty() && "merging zero comparisons");
656 LLVMContext &Context = NextCmpBlock->getContext();
657 const BCECmpBlock &FirstCmp = Comparisons[0];
658
659 // Create a new cmp block before next cmp block.
660 BasicBlock *const BB =
661 BasicBlock::Create(Context, MergedBlockName(Comparisons).Name,
662 NextCmpBlock->getParent(), InsertBefore);
663 IRBuilder<> Builder(BB);
664 // Add the GEPs from the first BCECmpBlock.
665 Value *Lhs, *Rhs;
666 if (FirstCmp.Lhs().GEP)
667 Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone());
668 else
669 Lhs = FirstCmp.Lhs().LoadI->getPointerOperand();
670 if (FirstCmp.Rhs().GEP)
671 Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone());
672 else
673 Rhs = FirstCmp.Rhs().LoadI->getPointerOperand();
674
675 Value *IsEqual = nullptr;
676 LLVM_DEBUG(dbgs() << "Merging " << Comparisons.size() << " comparisons -> "
677 << BB->getName() << "\n");
678
679 // If there is one block that requires splitting, we do it now, i.e.
680 // just before we know we will collapse the chain. The instructions
681 // can be executed before any of the instructions in the chain.
682 const auto *ToSplit = llvm::find_if(
683 Comparisons, [](const BCECmpBlock &B) { return B.RequireSplit; });
684 if (ToSplit != Comparisons.end()) {
685 LLVM_DEBUG(dbgs() << "Splitting non_BCE work to header\n");
686 ToSplit->split(BB, AA);
687 }
688
689 if (Comparisons.size() == 1) {
690 LLVM_DEBUG(dbgs() << "Only one comparison, updating branches\n");
691 // Use clone to keep the metadata
692 Instruction *const LhsLoad = Builder.Insert(FirstCmp.Lhs().LoadI->clone());
693 Instruction *const RhsLoad = Builder.Insert(FirstCmp.Rhs().LoadI->clone());
694 LhsLoad->replaceUsesOfWith(LhsLoad->getOperand(0), Lhs);
695 RhsLoad->replaceUsesOfWith(RhsLoad->getOperand(0), Rhs);
696 // There are no blocks to merge, just do the comparison.
697 // If we condition on this IsEqual, we already have its probabilities.
698 Builder.SetCurrentDebugLocation(Comparisons[0].getCmpDebugLoc());
699 IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
700 } else {
701 const unsigned TotalSizeBits = std::accumulate(
702 Comparisons.begin(), Comparisons.end(), 0u,
703 [](int Size, const BCECmpBlock &C) { return Size + C.SizeBits(); });
704
705 // Find the merged debug location for our generated comparison instructions.
706 SmallVector<DebugLoc> OrigCmpDebugLocs;
707 OrigCmpDebugLocs.reserve(Comparisons.size());
708 for (auto &Comparison : Comparisons)
709 OrigCmpDebugLocs.push_back(Comparison.getCmpDebugLoc());
710 DebugLoc CmpDebugLoc = DebugLoc::getMergedLocations(OrigCmpDebugLocs);
711 Builder.SetCurrentDebugLocation(CmpDebugLoc);
712
713 // memcmp expects a 'size_t' argument and returns 'int'.
714 unsigned SizeTBits = TLI.getSizeTSize(*Phi.getModule());
715 unsigned IntBits = TLI.getIntSize();
716
717 // Create memcmp() == 0.
718 const auto &DL = Phi.getDataLayout();
719 Value *const MemCmpCall = emitMemCmp(
720 Lhs, Rhs,
721 ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
722 Builder, DL, &TLI);
723 IsEqual = Builder.CreateICmpEQ(
724 MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
725 }
726
727 // Find the merged debug location for our generated branches.
728 SmallVector<DebugLoc> OrigBranchDebugLocs;
729 OrigBranchDebugLocs.reserve(Comparisons.size());
730 for (auto &Comparison : Comparisons)
731 OrigBranchDebugLocs.push_back(
732 Comparison.BB->getTerminator()->getDebugLoc());
733 DebugLoc BranchDebugLoc = DebugLoc::getMergedLocations(OrigBranchDebugLocs);
734 Builder.SetCurrentDebugLocation(BranchDebugLoc);
735
736 BasicBlock *const PhiBB = Phi.getParent();
737 // Add a branch to the next basic block in the chain.
738 if (NextCmpBlock == PhiBB) {
739 // Continue to phi, passing it the comparison result.
740 Builder.CreateBr(PhiBB);
741 Phi.addIncoming(IsEqual, BB);
742 DTU.applyUpdates({{DominatorTree::Insert, BB, PhiBB}});
743 } else {
744 // Continue to next block if equal, exit to phi else.
745 auto *BI = Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
746 if (auto BranchWeights = computeMergedBranchWeights(Comparisons))
747 setBranchWeights(*BI, BranchWeights.value(), /*IsExpected=*/false);
748 Phi.addIncoming(ConstantInt::getFalse(Context), BB);
749 DTU.applyUpdates({{DominatorTree::Insert, BB, NextCmpBlock},
750 {DominatorTree::Insert, BB, PhiBB}});
751 }
752 return BB;
753}
754
755// The transform may change the order in which the comparison is performed,
756// in which case we may perform loads that were not performed by the original
757// program. As such, we need to ensure that all the accessed memory is
758// dereferenceable.
759bool BCECmpChain::isDereferenceable() {
760 // We know that there can be no frees inside the merged blocks, so it's
761 // sufficient for dereferenceability to hold at the entry block. One
762 // exception to this is if the entry block performs "other work" and will
763 // get split. In that case, we need to consider frees prior to the splitting
764 // point.
765 Instruction *CtxI = SplitAt ? SplitAt : &EntryBlock_->front();
766
767 for (const auto &Blocks : MergedBlocks_) {
768 const BCECmpBlock &LowestBlock = Blocks.front();
769 const Value *Lhs = LowestBlock.Lhs().LoadI->getPointerOperand();
770 const Value *Rhs = LowestBlock.Rhs().LoadI->getPointerOperand();
771 const DataLayout &DL = LowestBlock.Lhs().LoadI->getDataLayout();
772
773 unsigned SizeInBits = 0;
774 for (const BCECmpBlock &Block : Blocks)
775 SizeInBits += Block.SizeBits();
776
777 APInt Size(64, SizeInBits / 8);
778 SimplifyQuery SQ(DL, CtxI);
779 if (!isDereferenceablePointer(Lhs, Size, SQ) ||
781 return false;
782 }
783 return true;
784}
785
786bool BCECmpChain::simplify(const TargetLibraryInfo &TLI, AliasAnalysis &AA,
787 DomTreeUpdater &DTU) {
788 assert(atLeastOneMerged() && "simplifying trivial BCECmpChain");
789 LLVM_DEBUG(dbgs() << "Simplifying comparison chain starting at block "
790 << EntryBlock_->getName() << "\n");
791
792 // Effectively merge blocks. We go in the reverse direction from the phi block
793 // so that the next block is always available to branch to.
794 BasicBlock *InsertBefore = EntryBlock_;
795 BasicBlock *NextCmpBlock = Phi_.getParent();
796 for (const auto &Blocks : reverse(MergedBlocks_)) {
797 InsertBefore = NextCmpBlock = mergeComparisons(
798 Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
799 }
800
801 // Replace the original cmp chain with the new cmp chain by pointing all
802 // predecessors of EntryBlock_ to NextCmpBlock instead. This makes all cmp
803 // blocks in the old chain unreachable.
804 while (!pred_empty(EntryBlock_)) {
805 BasicBlock* const Pred = *pred_begin(EntryBlock_);
806 LLVM_DEBUG(dbgs() << "Updating jump into old chain from " << Pred->getName()
807 << "\n");
808 Pred->getTerminator()->replaceUsesOfWith(EntryBlock_, NextCmpBlock);
809 DTU.applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
810 {DominatorTree::Insert, Pred, NextCmpBlock}});
811 }
812
813 // If the old cmp chain was the function entry, we need to update the function
814 // entry.
815 const bool ChainEntryIsFnEntry = EntryBlock_->isEntryBlock();
816 if (ChainEntryIsFnEntry && DTU.hasDomTree()) {
817 LLVM_DEBUG(dbgs() << "Changing function entry from "
818 << EntryBlock_->getName() << " to "
819 << NextCmpBlock->getName() << "\n");
820 DTU.getDomTree().setNewRoot(NextCmpBlock);
821 DTU.applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
822 }
823 EntryBlock_ = nullptr;
824
825 // Delete merged blocks. This also removes incoming values in phi.
826 SmallVector<BasicBlock *, 16> DeadBlocks;
827 for (const auto &Blocks : MergedBlocks_) {
828 for (const BCECmpBlock &Block : Blocks) {
829 LLVM_DEBUG(dbgs() << "Deleting merged block " << Block.BB->getName()
830 << "\n");
831 DeadBlocks.push_back(Block.BB);
832 }
833 }
834 DeleteDeadBlocks(DeadBlocks, &DTU);
835
836 MergedBlocks_.clear();
837 return true;
838}
839
840static std::vector<BasicBlock *>
841getOrderedBlocks(PHINode &Phi, BasicBlock *const LastBlock, int NumBlocks) {
842 // Walk up from the last block to find other blocks.
843 std::vector<BasicBlock *> Blocks(NumBlocks);
844 assert(LastBlock && "invalid last block");
845 BasicBlock *CurBlock = LastBlock;
846 for (int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
847 if (CurBlock->hasAddressTaken()) {
848 // Somebody is jumping to the block through an address, all bets are
849 // off.
850 LLVM_DEBUG(dbgs() << "skip: block " << BlockIndex
851 << " has its address taken\n");
852 return {};
853 }
854 Blocks[BlockIndex] = CurBlock;
855 auto *SinglePredecessor = CurBlock->getSinglePredecessor();
856 if (!SinglePredecessor) {
857 // The block has two or more predecessors.
858 LLVM_DEBUG(dbgs() << "skip: block " << BlockIndex
859 << " has two or more predecessors\n");
860 return {};
861 }
862 if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
863 // The block does not link back to the phi.
864 LLVM_DEBUG(dbgs() << "skip: block " << BlockIndex
865 << " does not link back to the phi\n");
866 return {};
867 }
868 CurBlock = SinglePredecessor;
869 }
870 Blocks[0] = CurBlock;
871 return Blocks;
872}
873
874static bool processPhi(PHINode &Phi, const TargetLibraryInfo &TLI,
876 LLVM_DEBUG(dbgs() << "processPhi()\n");
877 if (Phi.getNumIncomingValues() <= 1) {
878 LLVM_DEBUG(dbgs() << "skip: only one incoming value in phi\n");
879 return false;
880 }
881 // We are looking for something that has the following structure:
882 // bb1 --eq--> bb2 --eq--> bb3 --eq--> bb4 --+
883 // \ \ \ \
884 // ne ne ne \
885 // \ \ \ v
886 // +------------+-----------+----------> bb_phi
887 //
888 // - The last basic block (bb4 here) must branch unconditionally to bb_phi.
889 // It's the only block that contributes a non-constant value to the Phi.
890 // - All other blocks (b1, b2, b3) must have exactly two successors, one of
891 // them being the phi block.
892 // - All intermediate blocks (bb2, bb3) must have only one predecessor.
893 // - Blocks cannot do other work besides the comparison, see doesOtherWork()
894
895 // The blocks are not necessarily ordered in the phi, so we start from the
896 // last block and reconstruct the order.
897 BasicBlock *LastBlock = nullptr;
898 for (unsigned I = 0; I < Phi.getNumIncomingValues(); ++I) {
899 if (isa<ConstantInt>(Phi.getIncomingValue(I))) continue;
900 if (LastBlock) {
901 // There are several non-constant values.
902 LLVM_DEBUG(dbgs() << "skip: several non-constant values\n");
903 return false;
904 }
905 if (!isa<ICmpInst>(Phi.getIncomingValue(I)) ||
906 cast<ICmpInst>(Phi.getIncomingValue(I))->getParent() !=
907 Phi.getIncomingBlock(I)) {
908 // Non-constant incoming value is not from a cmp instruction or not
909 // produced by the last block. We could end up processing the value
910 // producing block more than once.
911 //
912 // This is an uncommon case, so we bail.
914 dbgs()
915 << "skip: non-constant value not from cmp or not from last block.\n");
916 return false;
917 }
918 LastBlock = Phi.getIncomingBlock(I);
919 }
920 if (!LastBlock) {
921 // There is no non-constant block.
922 LLVM_DEBUG(dbgs() << "skip: no non-constant block\n");
923 return false;
924 }
925 if (LastBlock->getSingleSuccessor() != Phi.getParent()) {
926 LLVM_DEBUG(dbgs() << "skip: last block non-phi successor\n");
927 return false;
928 }
929
930 const auto Blocks =
931 getOrderedBlocks(Phi, LastBlock, Phi.getNumIncomingValues());
932 if (Blocks.empty()) return false;
933 BCECmpChain CmpChain(Blocks, Phi, AA);
934
935 if (!CmpChain.atLeastOneMerged()) {
936 LLVM_DEBUG(dbgs() << "skip: nothing merged\n");
937 return false;
938 }
939
940 if (!CmpChain.isDereferenceable()) {
941 LLVM_DEBUG(dbgs() << "not dereferenceable\n");
942 return false;
943 }
944
945 return CmpChain.simplify(TLI, AA, DTU);
946}
947
950 DominatorTree *DT) {
951 LLVM_DEBUG(dbgs() << "MergeICmpsPass: " << F.getName() << "\n");
952
953 // We only try merging comparisons if the target wants to expand memcmp later.
954 // The rationale is to avoid turning small chains into memcmp calls.
955 if (!TTI.enableMemCmpExpansion(F.hasOptSize(), true))
956 return false;
957
958 // Make sure we can emit calls to memcmp().
959 if (!isLibFuncEmittable(F.getParent(), &TLI, LibFunc_memcmp))
960 return false;
961
962 DomTreeUpdater DTU(DT, /*PostDominatorTree*/ nullptr,
963 DomTreeUpdater::UpdateStrategy::Eager);
964
965 bool MadeChange = false;
966
967 for (BasicBlock &BB : llvm::drop_begin(F)) {
968 // A Phi operation is always first in a basic block.
969 if (auto *const Phi = dyn_cast<PHINode>(&*BB.begin()))
970 MadeChange |= processPhi(*Phi, TLI, AA, DTU);
971 }
972
973 return MadeChange;
974}
975
979 auto &TTI = AM.getResult<TargetIRAnalysis>(F);
980 auto &AA = AM.getResult<AAManager>(F);
982 const bool MadeChanges = runImpl(F, TLI, TTI, AA, DT);
983 if (!MadeChanges)
984 return PreservedAnalyses::all();
987 return PA;
988}
const TargetLowering & TLI
SDValue Pred
Ops append({Chain, DAG.getConstant(SVEStores[NumParts - 2], DL, MVT::i32)})
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
Definition CFIFixup.cpp:304
hexagon bit simplify
Hexagon Common GEP
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static void enqueueBlock(std::vector< BCECmpBlock > &Comparisons, BCECmpBlock &&Comparison)
static std::vector< BCECmpChain::ContiguousBlocks > mergeBlocks(std::vector< BCECmpBlock > &&Blocks)
Given a chain of comparison blocks, groups the blocks into contiguous ranges that can be merged toget...
static std::optional< SmallVector< uint32_t, 2 > > computeMergedBranchWeights(ArrayRef< BCECmpBlock > Comparisons)
Determine the branch weights for the resulting conditional branch, resulting after merging Comparison...
static std::optional< BCECmpBlock > visitCmpBlock(Value *const Val, BasicBlock *const Block, const BasicBlock *const PhiBlock, BaseIdentifier &BaseId)
static bool areContiguous(const BCECmpBlock &First, const BCECmpBlock &Second)
static std::vector< BasicBlock * > getOrderedBlocks(PHINode &Phi, BasicBlock *const LastBlock, int NumBlocks)
static unsigned getMinOrigOrder(const BCECmpChain::ContiguousBlocks &Blocks)
static BCEAtom visitICmpLoadOperand(Value *const Val, BaseIdentifier &BaseId)
static std::optional< BCECmp > visitICmp(const ICmpInst *const CmpI, const ICmpInst::Predicate ExpectedPredicate, BaseIdentifier &BaseId)
static BasicBlock * mergeComparisons(ArrayRef< BCECmpBlock > Comparisons, BasicBlock *const InsertBefore, BasicBlock *const NextCmpBlock, PHINode &Phi, const TargetLibraryInfo &TLI, AliasAnalysis &AA, DomTreeUpdater &DTU)
static bool processPhi(PHINode &Phi, const TargetLibraryInfo &TLI, AliasAnalysis &AA, DomTreeUpdater &DTU)
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
This file defines the SmallString class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
A manager for alias analyses.
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Check whether or not an instruction may read or write the optionally specified memory location.
Class for arbitrary precision integers.
Definition APInt.h:78
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 a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
Definition BasicBlock.h:666
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI bool isEntryBlock() const
Return true if this is the entry block of the containing function.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction & front() const
Definition BasicBlock.h:463
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
A debug info location.
Definition DebugLoc.h:126
static LLVM_ABI DebugLoc getMergedLocations(ArrayRef< DebugLoc > Locs)
Try to combine the vector of locations passed as input in a single one.
Definition DebugLoc.cpp:173
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
DomTreeNodeBase< NodeT > * setNewRoot(NodeT *BB)
Add a new node to the forward dominator tree and make it a new root.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
bool hasDomTree() const
Returns true if it holds a DomTreeT.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2947
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI void moveBeforePreserving(InstListType::iterator MovePos)
Perform a moveBefore operation, while signalling that the caller intends to preserve the original ord...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
An instruction for reading from memory.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
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.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
op_range operands()
Definition User.h:267
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:187
const ParentTy * getParent() const
Definition ilist_node.h:34
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
Abstract Attribute helper functions.
Definition Attributor.h:164
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:577
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
LLVM_ABI Value * emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memcmp function.
LLVM_ABI SmallVector< uint32_t > fitWeights(ArrayRef< uint64_t > Weights)
Push the weights right to fit in uint32_t.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
iterator_range< SplittingIterator > split(StringRef Str, StringRef Separator)
Split the specified string over a separator and return a range-compatible iterable over its partition...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
TargetTransformInfo TTI
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
SmallVector< uint64_t, 2 > getDisjunctionWeights(const SmallVector< T1, 2 > &B1, const SmallVector< T2, 2 > &B2)
Get the branch weights of a branch conditioned on b1 || b2, where b1 and b2 are 2 booleans that are t...
bool pred_empty(const BasicBlock *BB)
Definition CFG.h:107
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void DeleteDeadBlocks(ArrayRef< BasicBlock * > BBs, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified blocks from BB.
LLVM_ABI bool isDereferenceablePointer(const Value *V, Type *Ty, const SimplifyQuery &Q, bool IgnoreFree=false)
Equivalent to isDereferenceableAndAlignedPointer with an alignment of 1.
Definition Loads.cpp:266
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)