//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
-#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/Analysis.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Statepoint.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Use.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Pass.h"
+#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/BypassSlowDivision.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SimplifyLibCalls.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <utility>
+#include <vector>
using namespace llvm;
using namespace llvm::PatternMatch;
"memcmp that is only being compared against zero."));
namespace {
-typedef SmallPtrSet<Instruction *, 16> SetOfInstrs;
-typedef PointerIntPair<Type *, 1, bool> TypeIsSExt;
-typedef DenseMap<Instruction *, TypeIsSExt> InstrToOrigTy;
-typedef SmallVector<Instruction *, 16> SExts;
-typedef DenseMap<Value *, SExts> ValueToSExts;
+
+using SetOfInstrs = SmallPtrSet<Instruction *, 16>;
+using TypeIsSExt = PointerIntPair<Type *, 1, bool>;
+using InstrToOrigTy = DenseMap<Instruction *, TypeIsSExt>;
+using SExts = SmallVector<Instruction *, 16>;
+using ValueToSExts = DenseMap<Value *, SExts>;
+
class TypePromotionTransaction;
class CodeGenPrepare : public FunctionPass {
- const TargetMachine *TM;
+ const TargetMachine *TM = nullptr;
const TargetSubtargetInfo *SubtargetInfo;
- const TargetLowering *TLI;
+ const TargetLowering *TLI = nullptr;
const TargetRegisterInfo *TRI;
- const TargetTransformInfo *TTI;
+ const TargetTransformInfo *TTI = nullptr;
const TargetLibraryInfo *TLInfo;
const LoopInfo *LI;
std::unique_ptr<BlockFrequencyInfo> BFI;
/// Keeps track of all instructions inserted for the current function.
SetOfInstrs InsertedInsts;
+
/// Keeps track of the type of the related instruction before their
/// promotion for the current function.
InstrToOrigTy PromotedInsts;
bool OptSize;
/// DataLayout for the Function being processed.
- const DataLayout *DL;
+ const DataLayout *DL = nullptr;
public:
static char ID; // Pass identification, replacement for typeid
- CodeGenPrepare()
- : FunctionPass(ID), TM(nullptr), TLI(nullptr), TTI(nullptr),
- DL(nullptr) {
+
+ CodeGenPrepare() : FunctionPass(ID) {
initializeCodeGenPreparePass(*PassRegistry::getPassRegistry());
}
+
bool runOnFunction(Function &F) override;
StringRef getPassName() const override { return "CodeGen Prepare"; }
bool simplifyOffsetableRelocate(Instruction &I);
bool splitIndirectCriticalEdges(Function &F);
};
-}
+
+} // end anonymous namespace
char CodeGenPrepare::ID = 0;
+
INITIALIZE_PASS_BEGIN(CodeGenPrepare, DEBUG_TYPE,
"Optimize for code generation", false, false)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
return true;
}
-
/// Eliminate a basic block that has only phi's and an unconditional branch in
/// it.
void CodeGenPrepare::eliminateMostlyEmptyBlock(BasicBlock *BB) {
/// reduce the number of virtual registers that must be created and coalesced.
///
/// Return true if any changes are made.
-///
static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI,
const DataLayout &DL) {
// Sink only "cheap" (or nop) address-space casts. This is a weaker condition
}
namespace {
+
// This class provides helper functions to expand a memcmp library call into an
// inline expansion.
class MemCmpExpansion {
struct ResultBlock {
- BasicBlock *BB;
- PHINode *PhiSrc1;
- PHINode *PhiSrc2;
- ResultBlock();
+ BasicBlock *BB = nullptr;
+ PHINode *PhiSrc1 = nullptr;
+ PHINode *PhiSrc2 = nullptr;
+
+ ResultBlock() = default;
};
CallInst *CI;
public:
MemCmpExpansion(CallInst *CI, uint64_t Size, unsigned MaxLoadSize,
unsigned NumLoadsPerBlock, const DataLayout &DL);
+
Value *getMemCmpExpansion(uint64_t Size);
};
-} // namespace
-MemCmpExpansion::ResultBlock::ResultBlock()
- : BB(nullptr), PhiSrc1(nullptr), PhiSrc2(nullptr) {}
+} // end anonymous namespace
// Initialize the basic block structure required for expansion of memcmp call
// with given maximum load size and memcmp size parameter.
const DataLayout &TheDataLayout)
: CI(CI), MaxLoadSize(MaxLoadSize), NumLoadsPerBlock(LoadsPerBlock),
DL(TheDataLayout), Builder(CI) {
-
// A memcmp with zero-comparison with only one block of load and compare does
// not need to set up any extra blocks. This case could be handled in the DAG,
// but since we have all of the machinery to flexibly expand any memcpy here,
/// This is an extended version of TargetLowering::AddrMode
/// which holds actual Value*'s for register values.
struct ExtAddrMode : public TargetLowering::AddrMode {
- Value *BaseReg;
- Value *ScaledReg;
- ExtAddrMode() : BaseReg(nullptr), ScaledReg(nullptr) {}
+ Value *BaseReg = nullptr;
+ Value *ScaledReg = nullptr;
+
+ ExtAddrMode() = default;
+
void print(raw_ostream &OS) const;
void dump() const;
}
};
+} // end anonymous namespace
+
#ifndef NDEBUG
static inline raw_ostream &operator<<(raw_ostream &OS, const ExtAddrMode &AM) {
AM.print(OS);
}
#endif
+namespace {
+
/// \brief This class provides transaction based operation on the IR.
/// Every change made through this class is recorded in the internal state and
/// can be undone (rollback) until commit is called.
class TypePromotionTransaction {
-
/// \brief This represents the common interface of the individual transaction.
/// Each class implements the logic for doing one specific modification on
/// the IR via the TypePromotionTransaction.
/// The constructor performs the related action on the IR.
TypePromotionAction(Instruction *Inst) : Inst(Inst) {}
- virtual ~TypePromotionAction() {}
+ virtual ~TypePromotionAction() = default;
/// \brief Undo the modification done by this action.
/// When this method is called, the IR must be in the same state as it was
Instruction *PrevInst;
BasicBlock *BB;
} Point;
+
/// Remember whether or not the instruction had a previous instruction.
bool HasPrevInstruction;
class OperandSetter : public TypePromotionAction {
/// Original operand of the instruction.
Value *Origin;
+
/// Index of the modified instruction.
unsigned Idx;
/// \brief Build a truncate instruction.
class TruncBuilder : public TypePromotionAction {
Value *Val;
+
public:
/// \brief Build a truncate instruction of \p Opnd producing a \p Ty
/// result.
/// \brief Build a sign extension instruction.
class SExtBuilder : public TypePromotionAction {
Value *Val;
+
public:
/// \brief Build a sign extension instruction of \p Opnd producing a \p Ty
/// result.
/// \brief Build a zero extension instruction.
class ZExtBuilder : public TypePromotionAction {
Value *Val;
+
public:
/// \brief Build a zero extension instruction of \p Opnd producing a \p Ty
/// result.
struct InstructionAndIdx {
/// The instruction using the instruction.
Instruction *Inst;
+
/// The index where this instruction is used for Inst.
unsigned Idx;
+
InstructionAndIdx(Instruction *Inst, unsigned Idx)
: Inst(Inst), Idx(Idx) {}
};
/// Keep track of the original uses (pair Instruction, Index).
SmallVector<InstructionAndIdx, 4> OriginalUses;
- typedef SmallVectorImpl<InstructionAndIdx>::iterator use_iterator;
+
+ using use_iterator = SmallVectorImpl<InstructionAndIdx>::iterator;
public:
/// \brief Replace all the use of \p Inst by \p New.
class InstructionRemover : public TypePromotionAction {
/// Original position of the instruction.
InsertionHandler Inserter;
+
/// Helper structure to hide all the link to the instruction. In other
/// words, this helps to do as if the instruction was removed.
OperandsHider Hider;
+
/// Keep track of the uses replaced, if any.
- UsesReplacer *Replacer;
+ UsesReplacer *Replacer = nullptr;
+
/// Keep track of instructions removed.
SetOfInstrs &RemovedInsts;
InstructionRemover(Instruction *Inst, SetOfInstrs &RemovedInsts,
Value *New = nullptr)
: TypePromotionAction(Inst), Inserter(Inst), Hider(Inst),
- Replacer(nullptr), RemovedInsts(RemovedInsts) {
+ RemovedInsts(RemovedInsts) {
if (New)
Replacer = new UsesReplacer(Inst, New);
DEBUG(dbgs() << "Do: InstructionRemover: " << *Inst << "\n");
/// Restoration point.
/// The restoration point is a pointer to an action instead of an iterator
/// because the iterator may be invalidated but not the pointer.
- typedef const TypePromotionAction *ConstRestorationPt;
+ using ConstRestorationPt = const TypePromotionAction *;
TypePromotionTransaction(SetOfInstrs &RemovedInsts)
: RemovedInsts(RemovedInsts) {}
/// Advocate every changes made in that transaction.
void commit();
+
/// Undo all the changes made after the given point.
void rollback(ConstRestorationPt Point);
+
/// Get the current restoration point.
ConstRestorationPt getRestorationPoint() const;
/// @{
/// Same as Instruction::setOperand.
void setOperand(Instruction *Inst, unsigned Idx, Value *NewVal);
+
/// Same as Instruction::eraseFromParent.
void eraseInstruction(Instruction *Inst, Value *NewVal = nullptr);
+
/// Same as Value::replaceAllUsesWith.
void replaceAllUsesWith(Instruction *Inst, Value *New);
+
/// Same as Value::mutateType.
void mutateType(Instruction *Inst, Type *NewTy);
+
/// Same as IRBuilder::createTrunc.
Value *createTrunc(Instruction *Opnd, Type *Ty);
+
/// Same as IRBuilder::createSExt.
Value *createSExt(Instruction *Inst, Value *Opnd, Type *Ty);
+
/// Same as IRBuilder::createZExt.
Value *createZExt(Instruction *Inst, Value *Opnd, Type *Ty);
+
/// Same as Instruction::moveBefore.
void moveBefore(Instruction *Inst, Instruction *Before);
/// @}
private:
/// The ordered list of actions made so far.
SmallVector<std::unique_ptr<TypePromotionAction>, 16> Actions;
- typedef SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator CommitPt;
+
+ using CommitPt = SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator;
+
SetOfInstrs &RemovedInsts;
};
+} // end anonymous namespace
+
void TypePromotionTransaction::setOperand(Instruction *Inst, unsigned Idx,
Value *NewVal) {
- Actions.push_back(
- make_unique<TypePromotionTransaction::OperandSetter>(Inst, Idx, NewVal));
+ Actions.push_back(llvm::make_unique<TypePromotionTransaction::OperandSetter>(
+ Inst, Idx, NewVal));
}
void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
Value *NewVal) {
Actions.push_back(
- make_unique<TypePromotionTransaction::InstructionRemover>(Inst,
- RemovedInsts, NewVal));
+ llvm::make_unique<TypePromotionTransaction::InstructionRemover>(
+ Inst, RemovedInsts, NewVal));
}
void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
Value *New) {
- Actions.push_back(make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
+ Actions.push_back(
+ llvm::make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
}
void TypePromotionTransaction::mutateType(Instruction *Inst, Type *NewTy) {
- Actions.push_back(make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
+ Actions.push_back(
+ llvm::make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
}
Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
void TypePromotionTransaction::moveBefore(Instruction *Inst,
Instruction *Before) {
Actions.push_back(
- make_unique<TypePromotionTransaction::InstructionMoveBefore>(Inst, Before));
+ llvm::make_unique<TypePromotionTransaction::InstructionMoveBefore>(
+ Inst, Before));
}
TypePromotionTransaction::ConstRestorationPt
}
}
+namespace {
+
/// \brief A helper class for matching addressing modes.
///
/// This encapsulates the logic for matching the target-legal addressing modes.
/// The instructions inserted by other CodeGenPrepare optimizations.
const SetOfInstrs &InsertedInsts;
+
/// A map from the instructions to their type before promotion.
InstrToOrigTy &PromotedInsts;
+
/// The ongoing transaction where every action should be registered.
TypePromotionTransaction &TPT;
PromotedInsts(PromotedInsts), TPT(TPT) {
IgnoreProfitability = false;
}
-public:
+public:
/// Find the maximal addressing mode that a load/store of V can fold,
/// give an access type of AccessTy. This returns a list of involved
/// instructions in AddrModeInsts.
(void)Success; assert(Success && "Couldn't select *anything*?");
return Result;
}
+
private:
bool matchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth);
bool matchAddr(Value *V, unsigned Depth);
Value *PromotedOperand) const;
};
+} // end anonymous namespace
+
/// Try adding ScaleReg*Scale to the current addressing mode.
/// Return true and update AddrMode if this addr mode is legal for the target,
/// false if not.
ISDOpcode, TLI.getValueType(DL, PromotedInst->getType()));
}
+namespace {
+
/// \brief Hepler class to perform type promotion.
class TypePromotionHelper {
/// \brief Utility function to check whether or not a sign or zero extension
public:
/// Type for the utility function that promotes the operand of Ext.
- typedef Value *(*Action)(Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts,
- unsigned &CreatedInstsCost,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs,
- const TargetLowering &TLI);
+ using Action = Value *(*)(Instruction *Ext, TypePromotionTransaction &TPT,
+ InstrToOrigTy &PromotedInsts,
+ unsigned &CreatedInstsCost,
+ SmallVectorImpl<Instruction *> *Exts,
+ SmallVectorImpl<Instruction *> *Truncs,
+ const TargetLowering &TLI);
+
/// \brief Given a sign/zero extend instruction \p Ext, return the approriate
/// action to promote the operand of \p Ext instead of using Ext.
/// \return NULL if no promotable action is possible with the current
const InstrToOrigTy &PromotedInsts);
};
+} // end anonymous namespace
+
bool TypePromotionHelper::canGetThrough(const Instruction *Inst,
Type *ConsideredExtType,
const InstrToOrigTy &PromotedInsts,
}
Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
- llvm::Instruction *SExt, TypePromotionTransaction &TPT,
+ Instruction *SExt, TypePromotionTransaction &TPT,
InstrToOrigTy &PromotedInsts, unsigned &CreatedInstsCost,
SmallVectorImpl<Instruction *> *Exts,
SmallVectorImpl<Instruction *> *Truncs, const TargetLowering &TLI) {
return true;
}
-} // end anonymous namespace
-
/// Return true if the specified values are defined in a
/// different basic block than BB.
static bool IsNonLocalValue(Value *V, BasicBlock *BB) {
// b2:
// x = phi x1', x2'
// y = and x, 0xff
-//
-
bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
-
if (!Load->isSimple() ||
!(Load->getType()->isIntegerTy() || Load->getType()->isPointerTy()))
return false;
}
switch (I->getOpcode()) {
- case llvm::Instruction::And: {
+ case Instruction::And: {
auto *AndC = dyn_cast<ConstantInt>(I->getOperand(1));
if (!AndC)
return false;
break;
}
- case llvm::Instruction::Shl: {
+ case Instruction::Shl: {
auto *ShlC = dyn_cast<ConstantInt>(I->getOperand(1));
if (!ShlC)
return false;
break;
}
- case llvm::Instruction::Trunc: {
+ case Instruction::Trunc: {
EVT TruncVT = TLI->getValueType(*DL, I->getType());
unsigned TruncBitWidth = TruncVT.getSizeInBits();
DemandBits.setLowBits(TruncBitWidth);
namespace {
+
/// \brief Helper class to promote a scalar operation to a vector one.
/// This class is used to move downward extractelement transition.
/// E.g.,
/// The transition being moved downwards.
Instruction *Transition;
+
/// The sequence of instructions to be promoted.
SmallVector<Instruction *, 4> InstsToBePromoted;
+
/// Cost of combining a store and an extract.
unsigned StoreExtractCombineCost;
+
/// Instruction that will be combined with the transition.
- Instruction *CombineInst;
+ Instruction *CombineInst = nullptr;
/// \brief The instruction that represents the current end of the transition.
/// Since we are faking the promotion until we reach the end of the chain
/// <undef, ..., undef, Val, undef, ..., undef> where \p Val is only
/// used at the index of the extract.
Value *getConstantVector(Constant *Val, bool UseSplat) const {
- unsigned ExtractIdx = UINT_MAX;
+ unsigned ExtractIdx = std::numeric_limits<unsigned>::max();
if (!UseSplat) {
// If we cannot determine where the constant must be, we have to
// use a splat constant.
const TargetTransformInfo &TTI, Instruction *Transition,
unsigned CombineCost)
: DL(DL), TLI(TLI), TTI(TTI), Transition(Transition),
- StoreExtractCombineCost(CombineCost), CombineInst(nullptr) {
+ StoreExtractCombineCost(CombineCost) {
assert(Transition && "Do not know how to promote null");
}
return true;
}
};
-} // End of anonymous namespace.
+
+} // end anonymous namespace
void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
// At this point, we know that all the operands of ToBePromoted but Def
/// Try to push the extractelement towards the stores when the target
/// has this feature and this is profitable.
bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
- unsigned CombineCost = UINT_MAX;
+ unsigned CombineCost = std::numeric_limits<unsigned>::max();
if (DisableStoreExtract || !TLI ||
(!StressStoreExtract &&
!TLI->canCombineStoreAndExtract(Inst->getOperand(0)->getType(),
/// \brief Scale down both weights to fit into uint32_t.
static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse) {
uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;
- uint32_t Scale = (NewMax / UINT32_MAX) + 1;
+ uint32_t Scale = (NewMax / std::numeric_limits<uint32_t>::max()) + 1;
NewTrue = NewTrue / Scale;
NewFalse = NewFalse / Scale;
}
-//===-- ImplicitNullChecks.cpp - Fold null checks into memory accesses ----===//
+//===- ImplicitNullChecks.cpp - Fold null checks into memory accesses -----===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/FaultMaps.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Instruction.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetOpcodes.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
using namespace llvm;
const TargetInstrInfo *TII = nullptr;
const TargetRegisterInfo *TRI = nullptr;
AliasAnalysis *AA = nullptr;
- MachineModuleInfo *MMI = nullptr;
MachineFrameInfo *MFI = nullptr;
bool analyzeBlockForNullChecks(MachineBasicBlock &MBB,
AR_MayAlias,
AR_WillAliasEverything
};
+
/// Returns AR_NoAlias if \p MI memory operation does not alias with
/// \p PrevMI, AR_MayAlias if they may alias and AR_WillAliasEverything if
/// they may alias and any further memory operation may alias with \p PrevMI.
SR_Unsuitable,
SR_Impossible
};
+
/// Return SR_Suitable if \p MI a memory operation that can be used to
/// implicitly null check the value in \p PointerReg, SR_Unsuitable if
/// \p MI cannot be used to null check and SR_Impossible if there is
}
bool runOnMachineFunction(MachineFunction &MF) override;
+
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AAResultsWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
};
-}
+} // end anonymous namespace
bool ImplicitNullChecks::canHandle(const MachineInstr *MI) {
if (MI->isCall() || MI->hasUnmodeledSideEffects())
ImplicitNullChecks::computeDependence(const MachineInstr *MI,
ArrayRef<MachineInstr *> Block) {
assert(llvm::all_of(Block, canHandle) && "Check this first!");
- assert(!llvm::is_contained(Block, MI) && "Block must be exclusive of MI!");
+ assert(!is_contained(Block, MI) && "Block must be exclusive of MI!");
Optional<ArrayRef<MachineInstr *>::iterator> Dep;
bool ImplicitNullChecks::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getRegInfo().getTargetRegisterInfo();
- MMI = &MF.getMMI();
MFI = &MF.getFrameInfo();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
/// NullCheckList and return true, else return false.
bool ImplicitNullChecks::analyzeBlockForNullChecks(
MachineBasicBlock &MBB, SmallVectorImpl<NullCheck> &NullCheckList) {
- typedef TargetInstrInfo::MachineBranchPredicate MachineBranchPredicate;
+ using MachineBranchPredicate = TargetInstrInfo::MachineBranchPredicate;
MDNode *BranchMD = nullptr;
if (auto *BB = MBB.getBasicBlock())
}
// If MI re-defines the PointerReg then we cannot move further.
- if (any_of(MI.operands(), [&](MachineOperand &MO) {
+ if (llvm::any_of(MI.operands(), [&](MachineOperand &MO) {
return MO.isReg() && MO.getReg() && MO.isDef() &&
TRI->regsOverlap(MO.getReg(), PointerReg);
}))
}
}
-
char ImplicitNullChecks::ID = 0;
+
char &llvm::ImplicitNullChecksID = ImplicitNullChecks::ID;
+
INITIALIZE_PASS_BEGIN(ImplicitNullChecks, DEBUG_TYPE,
"Implicit null checks", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-//===-------- InlineSpiller.cpp - Insert spills and restores inline -------===//
+//===- InlineSpiller.cpp - Insert spills and restores inline --------------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
+#include "LiveRangeCalc.h"
#include "Spiller.h"
#include "SplitKit.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveRangeEdit.h"
#include "llvm/CodeGen/LiveStackAnalysis.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
-#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/VirtRegMap.h"
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/Support/BlockFrequency.h"
+#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetOpcodes.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+#include <cassert>
+#include <iterator>
+#include <tuple>
+#include <utility>
+#include <vector>
using namespace llvm;
cl::desc("Disable inline spill hoisting"));
namespace {
+
class HoistSpillHelper : private LiveRangeEdit::Delegate {
MachineFunction &MF;
LiveIntervals &LIS;
MachineDominatorTree &MDT;
MachineLoopInfo &Loops;
VirtRegMap &VRM;
- MachineFrameInfo &MFI;
MachineRegisterInfo &MRI;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
// Map from StackSlot to its original register.
DenseMap<int, unsigned> StackSlotToReg;
+
// Map from pair of (StackSlot and Original VNI) to a set of spills which
// have the same stackslot and have equal values defined by Original VNI.
// These spills are mergeable and are hoist candiates.
- typedef MapVector<std::pair<int, VNInfo *>, SmallPtrSet<MachineInstr *, 16>>
- MergeableSpillsMap;
+ using MergeableSpillsMap =
+ MapVector<std::pair<int, VNInfo *>, SmallPtrSet<MachineInstr *, 16>>;
MergeableSpillsMap MergeableSpills;
/// This is the map from original register to a set containing all its
AA(&pass.getAnalysis<AAResultsWrapperPass>().getAAResults()),
MDT(pass.getAnalysis<MachineDominatorTree>()),
Loops(pass.getAnalysis<MachineLoopInfo>()), VRM(vrm),
- MFI(mf.getFrameInfo()), MRI(mf.getRegInfo()),
- TII(*mf.getSubtarget().getInstrInfo()),
+ MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
TRI(*mf.getSubtarget().getRegisterInfo()),
MBFI(pass.getAnalysis<MachineBlockFrequencyInfo>()),
IPA(LIS, mf.getNumBlockIDs()) {}
MachineDominatorTree &MDT;
MachineLoopInfo &Loops;
VirtRegMap &VRM;
- MachineFrameInfo &MFI;
MachineRegisterInfo &MRI;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
// Object records spills information and does the hoisting.
HoistSpillHelper HSpiller;
- ~InlineSpiller() override {}
+ ~InlineSpiller() override = default;
public:
InlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm)
AA(&pass.getAnalysis<AAResultsWrapperPass>().getAAResults()),
MDT(pass.getAnalysis<MachineDominatorTree>()),
Loops(pass.getAnalysis<MachineLoopInfo>()), VRM(vrm),
- MFI(mf.getFrameInfo()), MRI(mf.getRegInfo()),
- TII(*mf.getSubtarget().getInstrInfo()),
+ MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
TRI(*mf.getSubtarget().getRegisterInfo()),
MBFI(pass.getAnalysis<MachineBlockFrequencyInfo>()),
HSpiller(pass, mf, vrm) {}
void reMaterializeAll();
bool coalesceStackAccess(MachineInstr *MI, unsigned Reg);
- bool foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> >,
+ bool foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>>,
MachineInstr *LoadMI = nullptr);
void insertReload(unsigned VReg, SlotIndex, MachineBasicBlock::iterator MI);
void insertSpill(unsigned VReg, bool isKill, MachineBasicBlock::iterator MI);
void spillAroundUses(unsigned Reg);
void spillAll();
};
-}
-namespace llvm {
+} // end anonymous namespace
-Spiller::~Spiller() { }
-void Spiller::anchor() { }
+Spiller::~Spiller() = default;
-Spiller *createInlineSpiller(MachineFunctionPass &pass,
- MachineFunction &mf,
- VirtRegMap &vrm) {
- return new InlineSpiller(pass, mf, vrm);
-}
+void Spiller::anchor() {}
+Spiller *llvm::createInlineSpiller(MachineFunctionPass &pass,
+ MachineFunction &mf,
+ VirtRegMap &vrm) {
+ return new InlineSpiller(pass, mf, vrm);
}
//===----------------------------------------------------------------------===//
} while (!WorkList.empty());
}
-
//===----------------------------------------------------------------------===//
// Rematerialization
//===----------------------------------------------------------------------===//
/// reMaterializeFor - Attempt to rematerialize before MI instead of reloading.
bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
-
// Analyze instruction
SmallVector<std::pair<MachineInstr *, unsigned>, 8> Ops;
MIBundleOperands::VirtRegInfo RI =
DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n");
}
-
//===----------------------------------------------------------------------===//
// Spilling
//===----------------------------------------------------------------------===//
/// @param LoadMI Load instruction to use instead of stack slot when non-null.
/// @return True on success.
bool InlineSpiller::
-foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops,
+foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
MachineInstr *LoadMI) {
if (Ops.empty())
return false;
}
/// Optimizations after all the reg selections and spills are done.
-///
void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
/// When a spill is inserted, add the spill to MergeableSpills map.
-///
void HoistSpillHelper::addToMergeableSpills(MachineInstr &Spill, int StackSlot,
unsigned Original) {
StackSlotToReg[StackSlot] = Original;
/// When a spill is removed, remove the spill from MergeableSpills map.
/// Return true if the spill is removed successfully.
-///
bool HoistSpillHelper::rmFromMergeableSpills(MachineInstr &Spill,
int StackSlot) {
int Original = StackSlotToReg[StackSlot];
/// Check BB to see if it is a possible target BB to place a hoisted spill,
/// i.e., there should be a living sibling of OrigReg at the insert point.
-///
bool HoistSpillHelper::isSpillCandBB(unsigned OrigReg, VNInfo &OrigVNI,
MachineBasicBlock &BB, unsigned &LiveReg) {
SlotIndex Idx;
/// Remove redundant spills in the same BB. Save those redundant spills in
/// SpillsToRm, and save the spill to keep and its BB in SpillBBToSpill map.
-///
void HoistSpillHelper::rmRedundantSpills(
SmallPtrSet<MachineInstr *, 16> &Spills,
SmallVectorImpl<MachineInstr *> &SpillsToRm,
/// time. \p SpillBBToSpill will be populated as part of the process and
/// maps a basic block to the first store occurring in the basic block.
/// \post SpillsToRm.union(Spills\@post) == Spills\@pre
-///
void HoistSpillHelper::getVisitOrders(
MachineBasicBlock *Root, SmallPtrSet<MachineInstr *, 16> &Spills,
SmallVectorImpl<MachineDomTreeNode *> &Orders,
/// Try to hoist spills according to BB hotness. The spills to removed will
/// be saved in \p SpillsToRm. The spills to be inserted will be saved in
/// \p SpillsToIns.
-///
void HoistSpillHelper::runHoistSpills(
unsigned OrigReg, VNInfo &OrigVNI, SmallPtrSet<MachineInstr *, 16> &Spills,
SmallVectorImpl<MachineInstr *> &SpillsToRm,
// nodes set and the cost of all the spills inside those nodes.
// The nodes set are the locations where spills are to be inserted
// in the subtree of current node.
- typedef std::pair<SmallPtrSet<MachineDomTreeNode *, 16>, BlockFrequency>
- NodesCostPair;
+ using NodesCostPair =
+ std::pair<SmallPtrSet<MachineDomTreeNode *, 16>, BlockFrequency>;
DenseMap<MachineDomTreeNode *, NodesCostPair> SpillsInSubTreeMap;
+
// Iterate Orders set in reverse order, which will be a bottom-up order
// in the dominator tree. Once we visit a dom tree node, we know its
// children have already been visited and the spill locations in the
/// bottom-up order, and for each node, we will decide whether to hoist spills
/// inside its subtree to that node. In this way, we can get benefit locally
/// even if hoisting all the equal spills to one cold place is impossible.
-///
void HoistSpillHelper::hoistAllSpills() {
SmallVector<unsigned, 4> NewVRegs;
LiveRangeEdit Edit(nullptr, NewVRegs, MF, LIS, &VRM, this);
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <cassert>
+#include <iterator>
+
using namespace llvm;
#define DEBUG_TYPE "machine-cp"
STATISTIC(NumDeletes, "Number of dead copies deleted");
namespace {
- typedef SmallVector<unsigned, 4> RegList;
- typedef DenseMap<unsigned, RegList> SourceMap;
- typedef DenseMap<unsigned, MachineInstr*> Reg2MIMap;
+
+using RegList = SmallVector<unsigned, 4>;
+using SourceMap = DenseMap<unsigned, RegList>;
+using Reg2MIMap = DenseMap<unsigned, MachineInstr *>;
class MachineCopyPropagation : public MachineFunctionPass {
const TargetRegisterInfo *TRI;
public:
static char ID; // Pass identification, replacement for typeid
+
MachineCopyPropagation() : MachineFunctionPass(ID) {
initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry());
}
/// Candidates for deletion.
SmallSetVector<MachineInstr*, 8> MaybeDeadCopies;
+
/// Def -> available copies map.
Reg2MIMap AvailCopyMap;
+
/// Def -> copies map.
Reg2MIMap CopyMap;
+
/// Src -> Def map
SourceMap SrcMap;
+
bool Changed;
};
-}
+
+} // end anonymous namespace
+
char MachineCopyPropagation::ID = 0;
+
char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
return Changed;
}
-
-//===-- MachineSink.cpp - Sinking for machine instructions ----------------===//
+//===- MachineSink.cpp - Sinking for machine instructions -----------------===//
//
// The LLVM Compiler Infrastructure
//
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
// Remember which edges we are about to split.
// This is different from CEBCandidates since those edges
// will be split.
- SetVector<std::pair<MachineBasicBlock*, MachineBasicBlock*> > ToSplit;
+ SetVector<std::pair<MachineBasicBlock *, MachineBasicBlock *>> ToSplit;
SparseBitVector<> RegsToClearKillFlags;
- typedef std::map<MachineBasicBlock *, SmallVector<MachineBasicBlock *, 4>>
- AllSuccsCache;
+ using AllSuccsCache =
+ std::map<MachineBasicBlock *, SmallVector<MachineBasicBlock *, 4>>;
public:
static char ID; // Pass identification
bool isWorthBreakingCriticalEdge(MachineInstr &MI,
MachineBasicBlock *From,
MachineBasicBlock *To);
+
/// \brief Postpone the splitting of the given critical
/// edge (\p From, \p To).
///
MachineBasicBlock *To,
bool BreakPHIEdge);
bool SinkInstruction(MachineInstr &MI, bool &SawStore,
+
AllSuccsCache &AllSuccessors);
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB,
MachineBasicBlock *DefMBB,
} // end anonymous namespace
char MachineSinking::ID = 0;
+
char &llvm::MachineSinkingID = MachineSinking::ID;
+
INITIALIZE_PASS_BEGIN(MachineSinking, DEBUG_TYPE,
"Machine code sinking", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
SmallVector<MachineBasicBlock *, 4> &
MachineSinking::GetAllSortedSuccessors(MachineInstr &MI, MachineBasicBlock *MBB,
AllSuccsCache &AllSuccessors) const {
-
// Do we have the sorted successors in cache ?
auto Succs = AllSuccessors.find(MBB);
if (Succs != AllSuccessors.end())
static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI,
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI) {
- typedef TargetInstrInfo::MachineBranchPredicate MachineBranchPredicate;
+ using MachineBranchPredicate = TargetInstrInfo::MachineBranchPredicate;
auto *MBB = MI.getParent();
if (MBB->pred_size() != 1)
if (!SuccToSinkTo)
return false;
-
// If the instruction to move defines a dead physical register which is live
// when leaving the basic block, don't move it because it could turn into a
// "zombie" define of that preg. E.g., EFLAGS. (<rdar://problem/8030636>)
-//===--- llvm/CodeGen/Spiller.h - Spiller -*- C++ -*-----------------------===//
+//===- llvm/CodeGen/Spiller.h - Spiller -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
namespace llvm {
- class LiveRangeEdit;
- class MachineFunction;
- class MachineFunctionPass;
- class VirtRegMap;
- class LiveIntervals;
+class LiveRangeEdit;
+class MachineFunction;
+class MachineFunctionPass;
+class VirtRegMap;
/// Spiller interface.
///
/// demand.
class Spiller {
virtual void anchor();
+
public:
virtual ~Spiller() = 0;
/// spill - Spill the LRE.getParent() live interval.
virtual void spill(LiveRangeEdit &LRE) = 0;
- virtual void postOptimization(){};
+
+ virtual void postOptimization() {}
};
/// Create and return a spiller that will insert spill code directly instead
Spiller *createInlineSpiller(MachineFunctionPass &pass,
MachineFunction &mf,
VirtRegMap &vrm);
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_SPILLER_H
-//===---------- SplitKit.cpp - Toolkit for splitting live ranges ----------===//
+//===- SplitKit.cpp - Toolkit for splitting live ranges -------------------===//
//
// The LLVM Compiler Infrastructure
//
//===----------------------------------------------------------------------===//
#include "SplitKit.h"
+#include "LiveRangeCalc.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveRangeEdit.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/VirtRegMap.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/LaneBitmask.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BlockFrequency.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOpcodes.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <limits>
+#include <tuple>
+#include <utility>
using namespace llvm;
SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm, const LiveIntervals &lis,
const MachineLoopInfo &mli)
: MF(vrm.getMachineFunction()), VRM(vrm), LIS(lis), Loops(mli),
- TII(*MF.getSubtarget().getInstrInfo()), CurLI(nullptr),
- IPA(lis, MF.getNumBlockIDs()) {}
+ TII(*MF.getSubtarget().getInstrInfo()), IPA(lis, MF.getNumBlockIDs()) {}
void SplitAnalysis::clear() {
UseSlots.clear();
// Loop over basic blocks where CurLI is live.
MachineFunction::iterator MFI =
LIS.getMBBFromIndex(LVI->start)->getIterator();
- for (;;) {
+ while (true) {
BlockInfo BI;
BI.MBB = &*MFI;
SlotIndex Start, Stop;
MachineFunction::const_iterator MFI =
LIS.getMBBFromIndex(LVI->start)->getIterator();
SlotIndex Stop = LIS.getMBBEndIdx(&*MFI);
- for (;;) {
+ while (true) {
++Count;
LVI = li->advanceTo(LVI, Stop);
if (LVI == LVE)
analyzeUses();
}
-
//===----------------------------------------------------------------------===//
// Split Editor
//===----------------------------------------------------------------------===//
MRI(vrm.getMachineFunction().getRegInfo()), MDT(mdt),
TII(*vrm.getMachineFunction().getSubtarget().getInstrInfo()),
TRI(*vrm.getMachineFunction().getSubtarget().getRegisterInfo()),
- MBFI(mbfi), Edit(nullptr), OpenIdx(0), SpillMode(SM_Partition),
- RegAssign(Allocator) {}
+ MBFI(mbfi), RegAssign(Allocator) {}
void SplitEditor::reset(LiveRangeEdit &LRE, ComplementSpillMode SM) {
Edit = &LRE;
LaneBitmask LanesLeft = LaneMask & ~(TRI.getSubRegIndexLaneMask(BestIdx));
while (LanesLeft.any()) {
unsigned BestIdx = 0;
- int BestCover = INT_MIN;
+ int BestCover = std::numeric_limits<int>::min();
for (unsigned Idx : PossibleIndexes) {
LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(Idx);
// Early exit if we found a perfect match.
// Best candidate so far.
MachineBasicBlock *BestMBB = MBB;
- unsigned BestDepth = UINT_MAX;
+ unsigned BestDepth = std::numeric_limits<unsigned>::max();
- for (;;) {
+ while (true) {
const MachineLoop *Loop = Loops.getLoopFor(MBB);
// MBB isn't in a loop, it doesn't get any better. All dominators have a
// Track the nearest common dominator for all back-copies for each ParentVNI,
// indexed by ParentVNI->id.
- typedef std::pair<MachineBasicBlock*, SlotIndex> DomPair;
+ using DomPair = std::pair<MachineBasicBlock *, SlotIndex>;
SmallVector<DomPair, 8> NearestDom(Parent->getNumValNums());
// The total cost of all the back-copies for each ParentVNI.
SmallVector<BlockFrequency, 8> Costs(Parent->getNumValNums());
removeBackCopies(BackCopies);
}
-
/// transferValues - Transfer all possible values to the new live ranges.
/// Values that were rematerialized are left alone, they need LRCalc.extend().
bool SplitEditor::transferValues() {
struct ExtPoint {
ExtPoint(const MachineOperand &O, unsigned R, SlotIndex N)
: MO(O), RegIdx(R), Next(N) {}
+
MachineOperand MO;
unsigned RegIdx;
SlotIndex Next;
assert(!LRMap || LRMap->size() == Edit->size());
}
-
//===----------------------------------------------------------------------===//
// Single Block Splitting
//===----------------------------------------------------------------------===//
}
}
-
//===----------------------------------------------------------------------===//
// Global Live Range Splitting Support
//===----------------------------------------------------------------------===//
assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference");
}
-
void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI,
unsigned IntvIn, SlotIndex LeaveBefore) {
SlotIndex Start, Stop;
-//===-------- SplitKit.h - Toolkit for splitting live ranges ----*- C++ -*-===//
+//===- SplitKit.h - Toolkit for splitting live ranges -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#include "LiveRangeCalc.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/MC/LaneBitmask.h"
+#include "llvm/Support/Compiler.h"
+#include <utility>
namespace llvm {
-class ConnectedVNInfoEqClasses;
-class LiveInterval;
class LiveIntervals;
class LiveRangeEdit;
class MachineBlockFrequencyInfo;
-class MachineInstr;
+class MachineDominatorTree;
class MachineLoopInfo;
class MachineRegisterInfo;
class TargetInstrInfo;
class TargetRegisterInfo;
class VirtRegMap;
-class VNInfo;
-class raw_ostream;
/// Determines the latest safe point in a block in which we can insert a split,
/// spill or other instruction related with CurLI.
private:
// Current live interval.
- const LiveInterval *CurLI;
+ const LiveInterval *CurLI = nullptr;
/// Insert Point Analysis.
InsertPointAnalysis IPA;
/// analyze(li).
unsigned countLiveBlocks(const LiveInterval *li) const;
- typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet;
+ using BlockPtrSet = SmallPtrSet<const MachineBasicBlock *, 16>;
/// shouldSplitSingleBlock - Returns true if it would help to create a local
/// live range for the instructions in BI. There is normally no benefit to
}
};
-
/// SplitEditor - Edit machine code and LiveIntervals for live range
/// splitting.
///
const MachineBlockFrequencyInfo &MBFI;
public:
-
/// ComplementSpillMode - Select how the complement live range should be
/// created. SplitEditor automatically creates interval 0 to contain
/// anything that isn't added to another interval. This complement interval
};
private:
-
/// Edit - The current parent register and new intervals created.
- LiveRangeEdit *Edit;
+ LiveRangeEdit *Edit = nullptr;
/// Index into Edit of the currently open interval.
/// The index 0 is used for the complement, so the first interval started by
/// openIntv will be 1.
- unsigned OpenIdx;
+ unsigned OpenIdx = 0;
/// The current spill mode, selected by reset().
- ComplementSpillMode SpillMode;
+ ComplementSpillMode SpillMode = SM_Partition;
- typedef IntervalMap<SlotIndex, unsigned> RegAssignMap;
+ using RegAssignMap = IntervalMap<SlotIndex, unsigned>;
/// Allocator for the interval map. This will eventually be shared with
/// SlotIndexes and LiveIntervals.
/// Idx.
RegAssignMap RegAssign;
- typedef PointerIntPair<VNInfo*, 1> ValueForcePair;
- typedef DenseMap<std::pair<unsigned, unsigned>, ValueForcePair> ValueMap;
+ using ValueForcePair = PointerIntPair<VNInfo *, 1>;
+ using ValueMap = DenseMap<std::pair<unsigned, unsigned>, ValueForcePair>;
/// Values - keep track of the mapping from parent values to values in the new
/// intervals. Given a pair (RegIdx, ParentVNI->id), Values contains:
public:
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
/// Newly created intervals will be appended to newIntervals.
- SplitEditor(SplitAnalysis &SA, AliasAnalysis &AA, LiveIntervals&,
- VirtRegMap&, MachineDominatorTree&,
- MachineBlockFrequencyInfo &);
+ SplitEditor(SplitAnalysis &sa, AliasAnalysis &aa, LiveIntervals &lis,
+ VirtRegMap &vrm, MachineDominatorTree &mdt,
+ MachineBlockFrequencyInfo &mbfi);
/// reset - Prepare for a new split.
void reset(LiveRangeEdit&, ComplementSpillMode = SM_Partition);
unsigned IntvOut, SlotIndex EnterAfter);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_LIB_CODEGEN_SPLITKIT_H