forked from OSchip/llvm-project
[CodeGen] Fix some Clang-tidy modernize-use-default-member-init and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 314046
This commit is contained in:
parent
85317f23df
commit
f193332994
|
@ -1,4 +1,4 @@
|
|||
//===-- AtomicExpandPass.cpp - Expand atomic instructions -------===//
|
||||
//===- AtomicExpandPass.cpp - Expand atomic instructions ------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -15,31 +15,54 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/AtomicExpandUtils.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/RuntimeLibcalls.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/AtomicOrdering.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "atomic-expand"
|
||||
|
||||
namespace {
|
||||
|
||||
class AtomicExpand: public FunctionPass {
|
||||
const TargetLowering *TLI;
|
||||
const TargetLowering *TLI = nullptr;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
AtomicExpand() : FunctionPass(ID), TLI(nullptr) {
|
||||
|
||||
AtomicExpand() : FunctionPass(ID) {
|
||||
initializeAtomicExpandPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -92,39 +115,41 @@ namespace {
|
|||
llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI,
|
||||
CreateCmpXchgInstFun CreateCmpXchg);
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char AtomicExpand::ID = 0;
|
||||
|
||||
char &llvm::AtomicExpandID = AtomicExpand::ID;
|
||||
|
||||
INITIALIZE_PASS(AtomicExpand, DEBUG_TYPE, "Expand Atomic instructions",
|
||||
false, false)
|
||||
|
||||
FunctionPass *llvm::createAtomicExpandPass() { return new AtomicExpand(); }
|
||||
|
||||
namespace {
|
||||
// Helper functions to retrieve the size of atomic instructions.
|
||||
unsigned getAtomicOpSize(LoadInst *LI) {
|
||||
static unsigned getAtomicOpSize(LoadInst *LI) {
|
||||
const DataLayout &DL = LI->getModule()->getDataLayout();
|
||||
return DL.getTypeStoreSize(LI->getType());
|
||||
}
|
||||
|
||||
unsigned getAtomicOpSize(StoreInst *SI) {
|
||||
static unsigned getAtomicOpSize(StoreInst *SI) {
|
||||
const DataLayout &DL = SI->getModule()->getDataLayout();
|
||||
return DL.getTypeStoreSize(SI->getValueOperand()->getType());
|
||||
}
|
||||
|
||||
unsigned getAtomicOpSize(AtomicRMWInst *RMWI) {
|
||||
static unsigned getAtomicOpSize(AtomicRMWInst *RMWI) {
|
||||
const DataLayout &DL = RMWI->getModule()->getDataLayout();
|
||||
return DL.getTypeStoreSize(RMWI->getValOperand()->getType());
|
||||
}
|
||||
|
||||
unsigned getAtomicOpSize(AtomicCmpXchgInst *CASI) {
|
||||
static unsigned getAtomicOpSize(AtomicCmpXchgInst *CASI) {
|
||||
const DataLayout &DL = CASI->getModule()->getDataLayout();
|
||||
return DL.getTypeStoreSize(CASI->getCompareOperand()->getType());
|
||||
}
|
||||
|
||||
// Helper functions to retrieve the alignment of atomic instructions.
|
||||
unsigned getAtomicOpAlign(LoadInst *LI) {
|
||||
static unsigned getAtomicOpAlign(LoadInst *LI) {
|
||||
unsigned Align = LI->getAlignment();
|
||||
// In the future, if this IR restriction is relaxed, we should
|
||||
// return DataLayout::getABITypeAlignment when there's no align
|
||||
|
@ -133,7 +158,7 @@ unsigned getAtomicOpAlign(LoadInst *LI) {
|
|||
return Align;
|
||||
}
|
||||
|
||||
unsigned getAtomicOpAlign(StoreInst *SI) {
|
||||
static unsigned getAtomicOpAlign(StoreInst *SI) {
|
||||
unsigned Align = SI->getAlignment();
|
||||
// In the future, if this IR restriction is relaxed, we should
|
||||
// return DataLayout::getABITypeAlignment when there's no align
|
||||
|
@ -142,7 +167,7 @@ unsigned getAtomicOpAlign(StoreInst *SI) {
|
|||
return Align;
|
||||
}
|
||||
|
||||
unsigned getAtomicOpAlign(AtomicRMWInst *RMWI) {
|
||||
static unsigned getAtomicOpAlign(AtomicRMWInst *RMWI) {
|
||||
// TODO(PR27168): This instruction has no alignment attribute, but unlike the
|
||||
// default alignment for load/store, the default here is to assume
|
||||
// it has NATURAL alignment, not DataLayout-specified alignment.
|
||||
|
@ -150,7 +175,7 @@ unsigned getAtomicOpAlign(AtomicRMWInst *RMWI) {
|
|||
return DL.getTypeStoreSize(RMWI->getValOperand()->getType());
|
||||
}
|
||||
|
||||
unsigned getAtomicOpAlign(AtomicCmpXchgInst *CASI) {
|
||||
static unsigned getAtomicOpAlign(AtomicCmpXchgInst *CASI) {
|
||||
// TODO(PR27168): same comment as above.
|
||||
const DataLayout &DL = CASI->getModule()->getDataLayout();
|
||||
return DL.getTypeStoreSize(CASI->getCompareOperand()->getType());
|
||||
|
@ -160,14 +185,12 @@ unsigned getAtomicOpAlign(AtomicCmpXchgInst *CASI) {
|
|||
// and is of appropriate alignment, to be passed through for target
|
||||
// lowering. (Versus turning into a __atomic libcall)
|
||||
template <typename Inst>
|
||||
bool atomicSizeSupported(const TargetLowering *TLI, Inst *I) {
|
||||
static bool atomicSizeSupported(const TargetLowering *TLI, Inst *I) {
|
||||
unsigned Size = getAtomicOpSize(I);
|
||||
unsigned Align = getAtomicOpAlign(I);
|
||||
return Align >= Size && Size <= TLI->getMaxAtomicSizeInBitsSupported() / 8;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
bool AtomicExpand::runOnFunction(Function &F) {
|
||||
auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
|
||||
if (!TPC)
|
||||
|
@ -556,6 +579,7 @@ struct PartwordMaskValues {
|
|||
Value *Mask;
|
||||
Value *Inv_Mask;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// This is a helper function which builds instructions to provide
|
||||
|
@ -574,7 +598,6 @@ struct PartwordMaskValues {
|
|||
/// include only the part that would've been loaded from Addr.
|
||||
///
|
||||
/// Inv_Mask: The inverse of Mask.
|
||||
|
||||
static PartwordMaskValues createMaskInstrs(IRBuilder<> &Builder, Instruction *I,
|
||||
Type *ValueType, Value *Addr,
|
||||
unsigned WordSize) {
|
||||
|
@ -680,7 +703,6 @@ static Value *performMaskedAtomicOp(AtomicRMWInst::BinOp Op,
|
|||
/// part of the value.
|
||||
void AtomicExpand::expandPartwordAtomicRMW(
|
||||
AtomicRMWInst *AI, TargetLoweringBase::AtomicExpansionKind ExpansionKind) {
|
||||
|
||||
assert(ExpansionKind == TargetLoweringBase::AtomicExpansionKind::CmpXChg);
|
||||
|
||||
AtomicOrdering MemOpOrder = AI->getOrdering();
|
||||
|
@ -937,7 +959,6 @@ AtomicCmpXchgInst *AtomicExpand::convertCmpXchgToIntegerType(AtomicCmpXchgInst *
|
|||
return NewCI;
|
||||
}
|
||||
|
||||
|
||||
bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
|
||||
AtomicOrdering SuccessOrder = CI->getSuccessOrdering();
|
||||
AtomicOrdering FailureOrder = CI->getFailureOrdering();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- DwarfEHPrepare - Prepare exception handling for code generation ---===//
|
||||
//===- DwarfEHPrepare - Prepare exception handling for code generation ----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -13,20 +13,29 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/CFG.h"
|
||||
#include "llvm/Analysis/EHPersonalities.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/RuntimeLibcalls.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include <cstddef>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "dwarfehprepare"
|
||||
|
@ -34,12 +43,13 @@ using namespace llvm;
|
|||
STATISTIC(NumResumesLowered, "Number of resume calls lowered");
|
||||
|
||||
namespace {
|
||||
|
||||
class DwarfEHPrepare : public FunctionPass {
|
||||
// RewindFunction - _Unwind_Resume or the target equivalent.
|
||||
Constant *RewindFunction;
|
||||
Constant *RewindFunction = nullptr;
|
||||
|
||||
DominatorTree *DT;
|
||||
const TargetLowering *TLI;
|
||||
DominatorTree *DT = nullptr;
|
||||
const TargetLowering *TLI = nullptr;
|
||||
|
||||
bool InsertUnwindResumeCalls(Function &Fn);
|
||||
Value *GetExceptionObject(ResumeInst *RI);
|
||||
|
@ -51,9 +61,7 @@ namespace {
|
|||
public:
|
||||
static char ID; // Pass identification, replacement for typeid.
|
||||
|
||||
DwarfEHPrepare()
|
||||
: FunctionPass(ID), RewindFunction(nullptr), DT(nullptr), TLI(nullptr) {
|
||||
}
|
||||
DwarfEHPrepare() : FunctionPass(ID) {}
|
||||
|
||||
bool runOnFunction(Function &Fn) override;
|
||||
|
||||
|
@ -68,9 +76,11 @@ namespace {
|
|||
return "Exception handling preparation";
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char DwarfEHPrepare::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(DwarfEHPrepare, DEBUG_TYPE,
|
||||
"Prepare DWARF exceptions", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- GlobalMerge.cpp - Internal globals merging -----------------------===//
|
||||
//===- GlobalMerge.cpp - Internal globals merging -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -6,6 +6,7 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This pass merges globals with internal linkage into one. This way all the
|
||||
// globals which were merged into a biggest one can be addressed using offsets
|
||||
// from the same base pointer (no need for separate base pointer for each of the
|
||||
|
@ -57,30 +58,45 @@
|
|||
// - it can increase register pressure when the uses are disparate enough.
|
||||
//
|
||||
// We use heuristics to discover the best global grouping we can (cf cl::opts).
|
||||
//
|
||||
// ===---------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalAlias.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "global-merge"
|
||||
|
@ -117,9 +133,12 @@ EnableGlobalMergeOnExternal("global-merge-on-external", cl::Hidden,
|
|||
cl::desc("Enable global merge pass on external linkage"));
|
||||
|
||||
STATISTIC(NumMerged, "Number of globals merged");
|
||||
|
||||
namespace {
|
||||
|
||||
class GlobalMerge : public FunctionPass {
|
||||
const TargetMachine *TM;
|
||||
const TargetMachine *TM = nullptr;
|
||||
|
||||
// FIXME: Infer the maximum possible offset depending on the actual users
|
||||
// (these max offsets are different for the users inside Thumb or ARM
|
||||
// functions), see the code that passes in the offset in the ARM backend
|
||||
|
@ -130,15 +149,16 @@ namespace {
|
|||
/// Currently, this applies a dead simple heuristic: only consider globals
|
||||
/// used in minsize functions for merging.
|
||||
/// FIXME: This could learn about optsize, and be used in the cost model.
|
||||
bool OnlyOptimizeForSize;
|
||||
bool OnlyOptimizeForSize = false;
|
||||
|
||||
/// Whether we should merge global variables that have external linkage.
|
||||
bool MergeExternalGlobals;
|
||||
bool MergeExternalGlobals = false;
|
||||
|
||||
bool IsMachO;
|
||||
|
||||
bool doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
|
||||
Module &M, bool isConst, unsigned AddrSpace) const;
|
||||
|
||||
/// \brief Merge everything in \p Globals for which the corresponding bit
|
||||
/// in \p GlobalSet is set.
|
||||
bool doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
|
||||
|
@ -164,9 +184,9 @@ namespace {
|
|||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid.
|
||||
|
||||
explicit GlobalMerge()
|
||||
: FunctionPass(ID), TM(nullptr), MaxOffset(GlobalMergeMaxOffset),
|
||||
OnlyOptimizeForSize(false), MergeExternalGlobals(false) {
|
||||
: FunctionPass(ID), MaxOffset(GlobalMergeMaxOffset) {
|
||||
initializeGlobalMergePass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -189,9 +209,11 @@ namespace {
|
|||
FunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char GlobalMerge::ID = 0;
|
||||
|
||||
INITIALIZE_PASS(GlobalMerge, DEBUG_TYPE, "Merge global variables", false, false)
|
||||
|
||||
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
|
||||
|
@ -231,9 +253,10 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
|
|||
|
||||
// We keep track of the sets of globals used together "close enough".
|
||||
struct UsedGlobalSet {
|
||||
UsedGlobalSet(size_t Size) : Globals(Size), UsageCount(1) {}
|
||||
BitVector Globals;
|
||||
unsigned UsageCount;
|
||||
unsigned UsageCount = 1;
|
||||
|
||||
UsedGlobalSet(size_t Size) : Globals(Size) {}
|
||||
};
|
||||
|
||||
// Each set is unique in UsedGlobalSets.
|
||||
|
@ -545,7 +568,7 @@ bool GlobalMerge::doInitialization(Module &M) {
|
|||
IsMachO = Triple(M.getTargetTriple()).isOSBinFormatMachO();
|
||||
|
||||
auto &DL = M.getDataLayout();
|
||||
DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals,
|
||||
DenseMap<unsigned, SmallVector<GlobalVariable *, 16>> Globals, ConstGlobals,
|
||||
BSSGlobals;
|
||||
bool Changed = false;
|
||||
setMustKeepGlobalVariables(M);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- IfConversion.cpp - Machine code if conversion pass. ---------------===//
|
||||
//===- IfConversion.cpp - Machine code if conversion pass -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -16,16 +16,26 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/SparseSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/CodeGen/LivePhysRegs.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/TargetSchedule.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/BranchProbability.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
@ -35,7 +45,12 @@
|
|||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -77,6 +92,7 @@ STATISTIC(NumDupBBs, "Number of duplicated blocks");
|
|||
STATISTIC(NumUnpred, "Number of true blocks of diamonds unpredicated");
|
||||
|
||||
namespace {
|
||||
|
||||
class IfConverter : public MachineFunctionPass {
|
||||
enum IfcvtKind {
|
||||
ICNotClassfied, // BB data valid, but not classified.
|
||||
|
@ -125,21 +141,20 @@ namespace {
|
|||
bool IsUnpredicable : 1;
|
||||
bool CannotBeCopied : 1;
|
||||
bool ClobbersPred : 1;
|
||||
unsigned NonPredSize;
|
||||
unsigned ExtraCost;
|
||||
unsigned ExtraCost2;
|
||||
MachineBasicBlock *BB;
|
||||
MachineBasicBlock *TrueBB;
|
||||
MachineBasicBlock *FalseBB;
|
||||
unsigned NonPredSize = 0;
|
||||
unsigned ExtraCost = 0;
|
||||
unsigned ExtraCost2 = 0;
|
||||
MachineBasicBlock *BB = nullptr;
|
||||
MachineBasicBlock *TrueBB = nullptr;
|
||||
MachineBasicBlock *FalseBB = nullptr;
|
||||
SmallVector<MachineOperand, 4> BrCond;
|
||||
SmallVector<MachineOperand, 4> Predicate;
|
||||
|
||||
BBInfo() : IsDone(false), IsBeingAnalyzed(false),
|
||||
IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false),
|
||||
IsBrReversible(false), HasFallThrough(false),
|
||||
IsUnpredicable(false), CannotBeCopied(false),
|
||||
ClobbersPred(false), NonPredSize(0), ExtraCost(0),
|
||||
ExtraCost2(0), BB(nullptr), TrueBB(nullptr),
|
||||
FalseBB(nullptr) {}
|
||||
ClobbersPred(false) {}
|
||||
};
|
||||
|
||||
/// Record information about pending if-conversions to attempt:
|
||||
|
@ -161,6 +176,7 @@ namespace {
|
|||
bool NeedSubsumption : 1;
|
||||
bool TClobbersPred : 1;
|
||||
bool FClobbersPred : 1;
|
||||
|
||||
IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0,
|
||||
bool tc = false, bool fc = false)
|
||||
: BBI(b), Kind(k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
|
||||
|
@ -182,13 +198,14 @@ namespace {
|
|||
|
||||
bool PreRegAlloc;
|
||||
bool MadeChange;
|
||||
int FnNum;
|
||||
int FnNum = -1;
|
||||
std::function<bool(const MachineFunction &)> PredicateFtor;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
IfConverter(std::function<bool(const MachineFunction &)> Ftor = nullptr)
|
||||
: MachineFunctionPass(ID), FnNum(-1), PredicateFtor(std::move(Ftor)) {
|
||||
: MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
|
||||
initializeIfConverterPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -309,8 +326,9 @@ namespace {
|
|||
}
|
||||
};
|
||||
|
||||
char IfConverter::ID = 0;
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
char IfConverter::ID = 0;
|
||||
|
||||
char &llvm::IfConverterID = IfConverter::ID;
|
||||
|
||||
|
@ -433,7 +451,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ICDiamond: {
|
||||
case ICDiamond:
|
||||
if (DisableDiamond) break;
|
||||
DEBUG(dbgs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
|
||||
<< BBI.TrueBB->getNumber() << ",F:"
|
||||
|
@ -444,8 +462,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
|||
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
if (RetVal) ++NumDiamonds;
|
||||
break;
|
||||
}
|
||||
case ICForkedDiamond: {
|
||||
case ICForkedDiamond:
|
||||
if (DisableForkedDiamond) break;
|
||||
DEBUG(dbgs() << "Ifcvt (Forked Diamond): BB#"
|
||||
<< BBI.BB->getNumber() << " (T:"
|
||||
|
@ -458,7 +475,6 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
|||
if (RetVal) ++NumForkedDiamonds;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RetVal && MRI->tracksLiveness())
|
||||
recomputeLivenessFlags(*BBI.BB);
|
||||
|
@ -617,7 +633,6 @@ bool IfConverter::CountDuplicatedInstructions(
|
|||
unsigned &Dups1, unsigned &Dups2,
|
||||
MachineBasicBlock &TBB, MachineBasicBlock &FBB,
|
||||
bool SkipUnconditionalBranches) const {
|
||||
|
||||
while (TIB != TIE && FIB != FIE) {
|
||||
// Skip dbg_value instructions. These do not count.
|
||||
TIB = skipDebugInstructionsForward(TIB, TIE);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- InterferenceCache.cpp - Caching per-block interference ---------*--===//
|
||||
//===- InterferenceCache.cpp - Caching per-block interference -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -12,9 +12,21 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "InterferenceCache.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/CodeGen/LiveInterval.h"
|
||||
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
||||
#include "llvm/CodeGen/LiveIntervalUnion.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <tuple>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -149,7 +161,7 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {
|
|||
BlockInterference *BI = &Blocks[MBBNum];
|
||||
ArrayRef<SlotIndex> RegMaskSlots;
|
||||
ArrayRef<const uint32_t*> RegMaskBits;
|
||||
for (;;) {
|
||||
while (true) {
|
||||
BI->Tag = Tag;
|
||||
BI->First = BI->Last = SlotIndex();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===//
|
||||
//===- InterferenceCache.h - Caching per-block interference ----*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -15,47 +15,53 @@
|
|||
#ifndef LLVM_LIB_CODEGEN_INTERFERENCECACHE_H
|
||||
#define LLVM_LIB_CODEGEN_INTERFERENCECACHE_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/LiveInterval.h"
|
||||
#include "llvm/CodeGen/LiveIntervalUnion.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LiveIntervals;
|
||||
class MachineFunction;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY InterferenceCache {
|
||||
const TargetRegisterInfo *TRI;
|
||||
LiveIntervalUnion *LIUArray;
|
||||
MachineFunction *MF;
|
||||
|
||||
/// BlockInterference - information about the interference in a single basic
|
||||
/// block.
|
||||
struct BlockInterference {
|
||||
BlockInterference() : Tag(0) {}
|
||||
unsigned Tag;
|
||||
unsigned Tag = 0;
|
||||
SlotIndex First;
|
||||
SlotIndex Last;
|
||||
|
||||
BlockInterference() = default;
|
||||
};
|
||||
|
||||
/// Entry - A cache entry containing interference information for all aliases
|
||||
/// of PhysReg in all basic blocks.
|
||||
class Entry {
|
||||
/// PhysReg - The register currently represented.
|
||||
unsigned PhysReg;
|
||||
unsigned PhysReg = 0;
|
||||
|
||||
/// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions
|
||||
/// change.
|
||||
unsigned Tag;
|
||||
unsigned Tag = 0;
|
||||
|
||||
/// RefCount - The total number of Cursor instances referring to this Entry.
|
||||
unsigned RefCount;
|
||||
unsigned RefCount = 0;
|
||||
|
||||
/// MF - The current function.
|
||||
MachineFunction *MF;
|
||||
|
||||
/// Indexes - Mapping block numbers to SlotIndex ranges.
|
||||
SlotIndexes *Indexes;
|
||||
SlotIndexes *Indexes = nullptr;
|
||||
|
||||
/// LIS - Used for accessing register mask interference maps.
|
||||
LiveIntervals *LIS;
|
||||
LiveIntervals *LIS = nullptr;
|
||||
|
||||
/// PrevPos - The previous position the iterators were moved to.
|
||||
SlotIndex PrevPos;
|
||||
|
@ -72,13 +78,12 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
|
|||
unsigned VirtTag;
|
||||
|
||||
/// Fixed interference in RegUnit.
|
||||
LiveRange *Fixed;
|
||||
LiveRange *Fixed = nullptr;
|
||||
|
||||
/// Iterator pointing into the fixed RegUnit interference.
|
||||
LiveInterval::iterator FixedI;
|
||||
|
||||
RegUnitInfo(LiveIntervalUnion &LIU)
|
||||
: VirtTag(LIU.getTag()), Fixed(nullptr) {
|
||||
RegUnitInfo(LiveIntervalUnion &LIU) : VirtTag(LIU.getTag()) {
|
||||
VirtI.setMap(LIU.getMap());
|
||||
}
|
||||
};
|
||||
|
@ -94,7 +99,7 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
|
|||
void update(unsigned MBBNum);
|
||||
|
||||
public:
|
||||
Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(nullptr), LIS(nullptr) {}
|
||||
Entry() = default;
|
||||
|
||||
void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) {
|
||||
assert(!hasRefs() && "Cannot clear cache entry with references");
|
||||
|
@ -134,13 +139,17 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
|
|||
// robin manner.
|
||||
enum { CacheEntries = 32 };
|
||||
|
||||
const TargetRegisterInfo *TRI = nullptr;
|
||||
LiveIntervalUnion *LIUArray = nullptr;
|
||||
MachineFunction *MF = nullptr;
|
||||
|
||||
// Point to an entry for each physreg. The entry pointed to may not be up to
|
||||
// date, and it may have been reused for a different physreg.
|
||||
unsigned char* PhysRegEntries;
|
||||
size_t PhysRegEntriesCount;
|
||||
unsigned char* PhysRegEntries = nullptr;
|
||||
size_t PhysRegEntriesCount = 0;
|
||||
|
||||
// Next round-robin entry to be picked.
|
||||
unsigned RoundRobin;
|
||||
unsigned RoundRobin = 0;
|
||||
|
||||
// The actual cache entries.
|
||||
Entry Entries[CacheEntries];
|
||||
|
@ -149,9 +158,9 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
|
|||
Entry *get(unsigned PhysReg);
|
||||
|
||||
public:
|
||||
InterferenceCache()
|
||||
: TRI(nullptr), LIUArray(nullptr), MF(nullptr), PhysRegEntries(nullptr),
|
||||
PhysRegEntriesCount(0), RoundRobin(0) {}
|
||||
friend class Cursor;
|
||||
|
||||
InterferenceCache() = default;
|
||||
|
||||
~InterferenceCache() {
|
||||
free(PhysRegEntries);
|
||||
|
@ -160,8 +169,9 @@ public:
|
|||
void reinitPhysRegEntries();
|
||||
|
||||
/// init - Prepare cache for a new function.
|
||||
void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*,
|
||||
const TargetRegisterInfo *);
|
||||
void init(MachineFunction *mf, LiveIntervalUnion *liuarray,
|
||||
SlotIndexes *indexes, LiveIntervals *lis,
|
||||
const TargetRegisterInfo *tri);
|
||||
|
||||
/// getMaxCursors - Return the maximum number of concurrent cursors that can
|
||||
/// be supported.
|
||||
|
@ -169,8 +179,8 @@ public:
|
|||
|
||||
/// Cursor - The primary query interface for the block interference cache.
|
||||
class Cursor {
|
||||
Entry *CacheEntry;
|
||||
const BlockInterference *Current;
|
||||
Entry *CacheEntry = nullptr;
|
||||
const BlockInterference *Current = nullptr;
|
||||
static const BlockInterference NoInterference;
|
||||
|
||||
void setEntry(Entry *E) {
|
||||
|
@ -186,10 +196,9 @@ public:
|
|||
|
||||
public:
|
||||
/// Cursor - Create a dangling cursor.
|
||||
Cursor() : CacheEntry(nullptr), Current(nullptr) {}
|
||||
~Cursor() { setEntry(nullptr); }
|
||||
Cursor() = default;
|
||||
|
||||
Cursor(const Cursor &O) : CacheEntry(nullptr), Current(nullptr) {
|
||||
Cursor(const Cursor &O) {
|
||||
setEntry(O.CacheEntry);
|
||||
}
|
||||
|
||||
|
@ -198,6 +207,8 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
~Cursor() { setEntry(nullptr); }
|
||||
|
||||
/// setPhysReg - Point this cursor to PhysReg's interference.
|
||||
void setPhysReg(InterferenceCache &Cache, unsigned PhysReg) {
|
||||
// Release reference before getting a new one. That guarantees we can
|
||||
|
@ -229,10 +240,8 @@ public:
|
|||
return Current->Last;
|
||||
}
|
||||
};
|
||||
|
||||
friend class Cursor;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_CODEGEN_INTERFERENCECACHE_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--------------------- InterleavedAccessPass.cpp ----------------------===//
|
||||
//===- InterleavedAccessPass.cpp ------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -42,17 +42,32 @@
|
|||
//
|
||||
// Similarly, a set of interleaved stores can be transformed into an optimized
|
||||
// sequence of shuffles followed by a set of target specific stores for X86.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.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/TargetSubtargetInfo.h"
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -66,10 +81,10 @@ static cl::opt<bool> LowerInterleavedAccesses(
|
|||
namespace {
|
||||
|
||||
class InterleavedAccess : public FunctionPass {
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
InterleavedAccess() : FunctionPass(ID), DT(nullptr), TLI(nullptr) {
|
||||
|
||||
InterleavedAccess() : FunctionPass(ID) {
|
||||
initializeInterleavedAccessPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -83,8 +98,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
DominatorTree *DT;
|
||||
const TargetLowering *TLI;
|
||||
DominatorTree *DT = nullptr;
|
||||
const TargetLowering *TLI = nullptr;
|
||||
|
||||
/// The maximum supported interleave factor.
|
||||
unsigned MaxFactor;
|
||||
|
@ -104,9 +119,11 @@ private:
|
|||
bool tryReplaceExtracts(ArrayRef<ExtractElementInst *> Extracts,
|
||||
ArrayRef<ShuffleVectorInst *> Shuffles);
|
||||
};
|
||||
|
||||
} // end anonymous namespace.
|
||||
|
||||
char InterleavedAccess::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(InterleavedAccess, DEBUG_TYPE,
|
||||
"Lower interleaved memory accesses to target specific intrinsics", false,
|
||||
false)
|
||||
|
@ -331,7 +348,6 @@ bool InterleavedAccess::lowerInterleavedLoad(
|
|||
bool InterleavedAccess::tryReplaceExtracts(
|
||||
ArrayRef<ExtractElementInst *> Extracts,
|
||||
ArrayRef<ShuffleVectorInst *> Shuffles) {
|
||||
|
||||
// If there aren't any extractelement instructions to modify, there's nothing
|
||||
// to do.
|
||||
if (Extracts.empty())
|
||||
|
@ -342,7 +358,6 @@ bool InterleavedAccess::tryReplaceExtracts(
|
|||
DenseMap<ExtractElementInst *, std::pair<Value *, int>> ReplacementMap;
|
||||
|
||||
for (auto *Extract : Extracts) {
|
||||
|
||||
// The vector index that is extracted.
|
||||
auto *IndexOperand = cast<ConstantInt>(Extract->getIndexOperand());
|
||||
auto Index = IndexOperand->getSExtValue();
|
||||
|
@ -351,7 +366,6 @@ bool InterleavedAccess::tryReplaceExtracts(
|
|||
// extractelement instruction (which uses an interleaved load) to use one
|
||||
// of the shufflevector instructions instead of the load.
|
||||
for (auto *Shuffle : Shuffles) {
|
||||
|
||||
// If the shufflevector instruction doesn't dominate the extract, we
|
||||
// can't create a use of it.
|
||||
if (!DT->dominates(Shuffle, Extract))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- MachineLICM.cpp - Machine Loop Invariant Code Motion Pass ---------===//
|
||||
//===- MachineLICM.cpp - Machine Loop Invariant Code Motion Pass ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -16,26 +16,42 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.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/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/TargetSchedule.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "machinelicm"
|
||||
|
@ -68,6 +84,7 @@ STATISTIC(NumPostRAHoisted,
|
|||
"Number of machine instructions hoisted out of loops post regalloc");
|
||||
|
||||
namespace {
|
||||
|
||||
class MachineLICM : public MachineFunctionPass {
|
||||
const TargetInstrInfo *TII;
|
||||
const TargetLoweringBase *TLI;
|
||||
|
@ -75,7 +92,7 @@ namespace {
|
|||
const MachineFrameInfo *MFI;
|
||||
MachineRegisterInfo *MRI;
|
||||
TargetSchedModel SchedModel;
|
||||
bool PreRegAlloc;
|
||||
bool PreRegAlloc = true;
|
||||
|
||||
// Various analyses that we use...
|
||||
AliasAnalysis *AA; // Alias analysis info.
|
||||
|
@ -89,7 +106,7 @@ namespace {
|
|||
MachineBasicBlock *CurPreheader; // The preheader for CurLoop.
|
||||
|
||||
// Exit blocks for CurLoop.
|
||||
SmallVector<MachineBasicBlock*, 8> ExitBlocks;
|
||||
SmallVector<MachineBasicBlock *, 8> ExitBlocks;
|
||||
|
||||
bool isExitBlock(const MachineBasicBlock *MBB) const {
|
||||
return is_contained(ExitBlocks, MBB);
|
||||
|
@ -107,7 +124,7 @@ namespace {
|
|||
SmallVector<SmallVector<unsigned, 8>, 16> BackTrace;
|
||||
|
||||
// For each opcode, keep a list of potential CSE instructions.
|
||||
DenseMap<unsigned, std::vector<const MachineInstr*> > CSEMap;
|
||||
DenseMap<unsigned, std::vector<const MachineInstr *>> CSEMap;
|
||||
|
||||
enum {
|
||||
SpeculateFalse = 0,
|
||||
|
@ -122,15 +139,15 @@ namespace {
|
|||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
MachineLICM() :
|
||||
MachineFunctionPass(ID), PreRegAlloc(true) {
|
||||
initializeMachineLICMPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
explicit MachineLICM(bool PreRA) :
|
||||
MachineFunctionPass(ID), PreRegAlloc(PreRA) {
|
||||
MachineLICM() : MachineFunctionPass(ID) {
|
||||
initializeMachineLICMPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
explicit MachineLICM(bool PreRA)
|
||||
: MachineFunctionPass(ID), PreRegAlloc(PreRA) {
|
||||
initializeMachineLICMPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
|
@ -157,6 +174,7 @@ namespace {
|
|||
MachineInstr *MI;
|
||||
unsigned Def;
|
||||
int FI;
|
||||
|
||||
CandidateInfo(MachineInstr *mi, unsigned def, int fi)
|
||||
: MI(mi), Def(def), FI(fi) {}
|
||||
};
|
||||
|
@ -233,10 +251,13 @@ namespace {
|
|||
|
||||
MachineBasicBlock *getCurPreheader();
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char MachineLICM::ID = 0;
|
||||
|
||||
char &llvm::MachineLICMID = MachineLICM::ID;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(MachineLICM, DEBUG_TYPE,
|
||||
"Machine Loop Invariant Code Motion", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
||||
|
@ -425,7 +446,7 @@ void MachineLICM::ProcessMI(MachineInstr *MI,
|
|||
// Only consider reloads for now and remats which do not have register
|
||||
// operands. FIXME: Consider unfold load folding instructions.
|
||||
if (Def && !RuledOut) {
|
||||
int FI = INT_MIN;
|
||||
int FI = std::numeric_limits<int>::min();
|
||||
if ((!HasNonInvariantUse && IsLICMCandidate(*MI)) ||
|
||||
(TII->isLoadFromStackSlot(*MI, FI) && MFI->isSpillSlotObjectIndex(FI)))
|
||||
Candidates.push_back(CandidateInfo(MI, Def, FI));
|
||||
|
@ -492,7 +513,7 @@ void MachineLICM::HoistRegionPostRA() {
|
|||
// registers read by the terminator. Similarly its def should not be
|
||||
// clobbered by the terminator.
|
||||
for (CandidateInfo &Candidate : Candidates) {
|
||||
if (Candidate.FI != INT_MIN &&
|
||||
if (Candidate.FI != std::numeric_limits<int>::min() &&
|
||||
StoredFIs.count(Candidate.FI))
|
||||
continue;
|
||||
|
||||
|
@ -617,7 +638,6 @@ void MachineLICM::ExitScopeIfDone(MachineDomTreeNode *Node,
|
|||
/// specified header block, and that are in the current loop) in depth first
|
||||
/// order w.r.t the DominatorTree. This allows us to visit definitions before
|
||||
/// uses, allowing us to hoist a loop body in one pass without iteration.
|
||||
///
|
||||
void MachineLICM::HoistOutOfLoop(MachineDomTreeNode *HeaderN) {
|
||||
MachineBasicBlock *Preheader = getCurPreheader();
|
||||
if (!Preheader)
|
||||
|
@ -836,7 +856,7 @@ MachineLICM::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen,
|
|||
/// Return true if this machine instruction loads from global offset table or
|
||||
/// constant pool.
|
||||
static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI) {
|
||||
assert (MI.mayLoad() && "Expected MI that loads!");
|
||||
assert(MI.mayLoad() && "Expected MI that loads!");
|
||||
|
||||
// If we lost memory operands, conservatively assume that the instruction
|
||||
// reads from everything..
|
||||
|
@ -876,7 +896,6 @@ bool MachineLICM::IsLICMCandidate(MachineInstr &I) {
|
|||
/// I.e., all virtual register operands are defined outside of the loop,
|
||||
/// physical registers aren't accessed explicitly, and there are no side
|
||||
/// effects that aren't captured by the operands or other flags.
|
||||
///
|
||||
bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
|
||||
if (!IsLICMCandidate(I))
|
||||
return false;
|
||||
|
@ -928,7 +947,6 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Return true if the specified instruction is used by a phi node and hoisting
|
||||
/// it could cause a copy to be inserted.
|
||||
bool MachineLICM::HasLoopPHIUse(const MachineInstr *MI) const {
|
||||
|
@ -1233,7 +1251,7 @@ MachineLICM::LookForDuplicate(const MachineInstr *MI,
|
|||
/// the existing instruction rather than hoisting the instruction to the
|
||||
/// preheader.
|
||||
bool MachineLICM::EliminateCSE(MachineInstr *MI,
|
||||
DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator &CI) {
|
||||
DenseMap<unsigned, std::vector<const MachineInstr *>>::iterator &CI) {
|
||||
// Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
|
||||
// the undef property onto uses.
|
||||
if (CI == CSEMap.end() || MI->isImplicitDef())
|
||||
|
@ -1292,7 +1310,7 @@ bool MachineLICM::EliminateCSE(MachineInstr *MI,
|
|||
/// the loop.
|
||||
bool MachineLICM::MayCSE(MachineInstr *MI) {
|
||||
unsigned Opcode = MI->getOpcode();
|
||||
DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator
|
||||
DenseMap<unsigned, std::vector<const MachineInstr *>>::iterator
|
||||
CI = CSEMap.find(Opcode);
|
||||
// Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
|
||||
// the undef property onto uses.
|
||||
|
@ -1333,7 +1351,7 @@ bool MachineLICM::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader) {
|
|||
|
||||
// Look for opportunity to CSE the hoisted instruction.
|
||||
unsigned Opcode = MI->getOpcode();
|
||||
DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator
|
||||
DenseMap<unsigned, std::vector<const MachineInstr *>>::iterator
|
||||
CI = CSEMap.find(Opcode);
|
||||
if (!EliminateCSE(MI, CI)) {
|
||||
// Otherwise, splice the instruction to the preheader.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===- RegisterCoalescer.cpp - Generic Register Coalescing Interface -------==//
|
||||
//===- RegisterCoalescer.cpp - Generic Register Coalescing Interface ------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -14,32 +14,49 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "RegisterCoalescer.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/CodeGen/LiveInterval.h"
|
||||
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
||||
#include "llvm/CodeGen/LiveRangeEdit.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.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/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/RegisterClassInfo.h"
|
||||
#include "llvm/CodeGen/VirtRegMap.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCRegisterInfo.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/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "regalloc"
|
||||
|
@ -79,11 +96,11 @@ VerifyCoalescing("verify-coalescing",
|
|||
cl::Hidden);
|
||||
|
||||
namespace {
|
||||
|
||||
class RegisterCoalescer : public MachineFunctionPass,
|
||||
private LiveRangeEdit::Delegate {
|
||||
MachineFunction* MF;
|
||||
MachineRegisterInfo* MRI;
|
||||
const TargetMachine* TM;
|
||||
const TargetRegisterInfo* TRI;
|
||||
const TargetInstrInfo* TII;
|
||||
LiveIntervals *LIS;
|
||||
|
@ -260,6 +277,7 @@ namespace {
|
|||
|
||||
public:
|
||||
static char ID; ///< Class identification, replacement for typeinfo
|
||||
|
||||
RegisterCoalescer() : MachineFunctionPass(ID) {
|
||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
@ -274,8 +292,11 @@ namespace {
|
|||
/// Implement the dump method.
|
||||
void print(raw_ostream &O, const Module* = nullptr) const override;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char RegisterCoalescer::ID = 0;
|
||||
|
||||
char &llvm::RegisterCoalescerID = RegisterCoalescer::ID;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing",
|
||||
|
@ -287,8 +308,6 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
|||
INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
|
||||
"Simple Register Coalescing", false, false)
|
||||
|
||||
char RegisterCoalescer::ID = 0;
|
||||
|
||||
static bool isMoveInstr(const TargetRegisterInfo &tri, const MachineInstr *MI,
|
||||
unsigned &Src, unsigned &Dst,
|
||||
unsigned &SrcSub, unsigned &DstSub) {
|
||||
|
@ -626,8 +645,7 @@ bool RegisterCoalescer::hasOtherReachingDefs(LiveInterval &IntA,
|
|||
/// Copy segements with value number @p SrcValNo from liverange @p Src to live
|
||||
/// range @Dst and use value number @p DstValNo there.
|
||||
static void addSegmentsWithValNo(LiveRange &Dst, VNInfo *DstValNo,
|
||||
const LiveRange &Src, const VNInfo *SrcValNo)
|
||||
{
|
||||
const LiveRange &Src, const VNInfo *SrcValNo) {
|
||||
for (const LiveRange::Segment &S : Src.segments) {
|
||||
if (S.valno != SrcValNo)
|
||||
continue;
|
||||
|
@ -1546,7 +1564,6 @@ bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) {
|
|||
}
|
||||
|
||||
bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
|
||||
|
||||
Again = false;
|
||||
DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI);
|
||||
|
||||
|
@ -1931,6 +1948,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
|
|||
// lane value escapes the block, the join is aborted.
|
||||
|
||||
namespace {
|
||||
|
||||
/// Track information about values in a single virtual register about to be
|
||||
/// joined. Objects of this class are always created in pairs - one for each
|
||||
/// side of the CoalescerPair (or one for each lane of a side of the coalescer
|
||||
|
@ -1938,6 +1956,7 @@ namespace {
|
|||
class JoinVals {
|
||||
/// Live range we work on.
|
||||
LiveRange &LR;
|
||||
|
||||
/// (Main) register we work on.
|
||||
const unsigned Reg;
|
||||
|
||||
|
@ -1945,6 +1964,7 @@ class JoinVals {
|
|||
/// subregister SubIdx in the coalesced register. Either CP.DstIdx or
|
||||
/// CP.SrcIdx.
|
||||
const unsigned SubIdx;
|
||||
|
||||
/// The LaneMask that this liverange will occupy the coalesced register. May
|
||||
/// be smaller than the lanemask produced by SubIdx when merging subranges.
|
||||
const LaneBitmask LaneMask;
|
||||
|
@ -1952,6 +1972,7 @@ class JoinVals {
|
|||
/// This is true when joining sub register ranges, false when joining main
|
||||
/// ranges.
|
||||
const bool SubRangeJoin;
|
||||
|
||||
/// Whether the current LiveInterval tracks subregister liveness.
|
||||
const bool TrackSubRegLiveness;
|
||||
|
||||
|
@ -1999,7 +2020,7 @@ class JoinVals {
|
|||
/// joined register, so they can be compared directly between SrcReg and
|
||||
/// DstReg.
|
||||
struct Val {
|
||||
ConflictResolution Resolution;
|
||||
ConflictResolution Resolution = CR_Keep;
|
||||
|
||||
/// Lanes written by this def, 0 for unanalyzed values.
|
||||
LaneBitmask WriteLanes;
|
||||
|
@ -2009,10 +2030,10 @@ class JoinVals {
|
|||
LaneBitmask ValidLanes;
|
||||
|
||||
/// Value in LI being redefined by this def.
|
||||
VNInfo *RedefVNI;
|
||||
VNInfo *RedefVNI = nullptr;
|
||||
|
||||
/// Value in the other live range that overlaps this def, if any.
|
||||
VNInfo *OtherVNI;
|
||||
VNInfo *OtherVNI = nullptr;
|
||||
|
||||
/// Is this value an IMPLICIT_DEF that can be erased?
|
||||
///
|
||||
|
@ -2025,18 +2046,16 @@ class JoinVals {
|
|||
/// ProcessImplicitDefs can very rarely create IMPLICIT_DEF values with
|
||||
/// longer live ranges. Such IMPLICIT_DEF values should be treated like
|
||||
/// normal values.
|
||||
bool ErasableImplicitDef;
|
||||
bool ErasableImplicitDef = false;
|
||||
|
||||
/// True when the live range of this value will be pruned because of an
|
||||
/// overlapping CR_Replace value in the other live range.
|
||||
bool Pruned;
|
||||
bool Pruned = false;
|
||||
|
||||
/// True once Pruned above has been computed.
|
||||
bool PrunedComputed;
|
||||
bool PrunedComputed = false;
|
||||
|
||||
Val() : Resolution(CR_Keep), WriteLanes(), ValidLanes(),
|
||||
RedefVNI(nullptr), OtherVNI(nullptr), ErasableImplicitDef(false),
|
||||
Pruned(false), PrunedComputed(false) {}
|
||||
Val() = default;
|
||||
|
||||
bool isAnalyzed() const { return WriteLanes.any(); }
|
||||
};
|
||||
|
@ -2083,8 +2102,9 @@ class JoinVals {
|
|||
/// entry to TaintedVals.
|
||||
///
|
||||
/// Returns false if the tainted lanes extend beyond the basic block.
|
||||
bool taintExtent(unsigned, LaneBitmask, JoinVals&,
|
||||
SmallVectorImpl<std::pair<SlotIndex, LaneBitmask> >&);
|
||||
bool
|
||||
taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
|
||||
SmallVectorImpl<std::pair<SlotIndex, LaneBitmask>> &TaintExtent);
|
||||
|
||||
/// Return true if MI uses any of the given Lanes from Reg.
|
||||
/// This does not include partial redefinitions of Reg.
|
||||
|
@ -2106,8 +2126,7 @@ public:
|
|||
: LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask),
|
||||
SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
|
||||
NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
|
||||
TRI(TRI), Assignments(LR.getNumValNums(), -1), Vals(LR.getNumValNums())
|
||||
{}
|
||||
TRI(TRI), Assignments(LR.getNumValNums(), -1), Vals(LR.getNumValNums()) {}
|
||||
|
||||
/// Analyze defs in LR and compute a value mapping in NewVNInfo.
|
||||
/// Returns false if any conflicts were impossible to resolve.
|
||||
|
@ -2151,6 +2170,7 @@ public:
|
|||
/// Get the value assignments suitable for passing to LiveInterval::join.
|
||||
const int *getAssignments() const { return Assignments.data(); }
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
|
||||
|
@ -2505,7 +2525,7 @@ bool JoinVals::mapValues(JoinVals &Other) {
|
|||
|
||||
bool JoinVals::
|
||||
taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
|
||||
SmallVectorImpl<std::pair<SlotIndex, LaneBitmask> > &TaintExtent) {
|
||||
SmallVectorImpl<std::pair<SlotIndex, LaneBitmask>> &TaintExtent) {
|
||||
VNInfo *VNI = LR.getValNumInfo(ValNo);
|
||||
MachineBasicBlock *MBB = Indexes->getMBBFromIndex(VNI->def);
|
||||
SlotIndex MBBEnd = Indexes->getMBBEndIdx(MBB);
|
||||
|
@ -2562,7 +2582,7 @@ bool JoinVals::usesLanes(const MachineInstr &MI, unsigned Reg, unsigned SubIdx,
|
|||
bool JoinVals::resolveConflicts(JoinVals &Other) {
|
||||
for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
|
||||
Val &V = Vals[i];
|
||||
assert (V.Resolution != CR_Impossible && "Unresolvable conflict");
|
||||
assert(V.Resolution != CR_Impossible && "Unresolvable conflict");
|
||||
if (V.Resolution != CR_Unresolved)
|
||||
continue;
|
||||
DEBUG(dbgs() << "\t\tconflict at " << PrintReg(Reg) << ':' << i
|
||||
|
@ -2600,7 +2620,7 @@ bool JoinVals::resolveConflicts(JoinVals &Other) {
|
|||
Indexes->getInstructionFromIndex(TaintExtent.front().first);
|
||||
assert(LastMI && "Range must end at a proper instruction");
|
||||
unsigned TaintNum = 0;
|
||||
for (;;) {
|
||||
while (true) {
|
||||
assert(MI != MBB->end() && "Bad LastMI");
|
||||
if (usesLanes(*MI, Other.Reg, Other.SubIdx, TaintedLanes)) {
|
||||
DEBUG(dbgs() << "\t\ttainted lanes used by: " << *MI);
|
||||
|
@ -3070,6 +3090,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// Information concerning MBB coalescing priority.
|
||||
struct MBBPriorityInfo {
|
||||
MachineBasicBlock *MBB;
|
||||
|
@ -3079,7 +3100,8 @@ struct MBBPriorityInfo {
|
|||
MBBPriorityInfo(MachineBasicBlock *mbb, unsigned depth, bool issplit)
|
||||
: MBB(mbb), Depth(depth), IsSplit(issplit) {}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// C-style comparator that sorts first based on the loop depth of the basic
|
||||
/// block (the unsigned), and then on the MBB number.
|
||||
|
@ -3283,7 +3305,7 @@ void RegisterCoalescer::joinAllIntervals() {
|
|||
array_pod_sort(MBBs.begin(), MBBs.end(), compareMBBPriority);
|
||||
|
||||
// Coalesce intervals in MBB priority order.
|
||||
unsigned CurrDepth = UINT_MAX;
|
||||
unsigned CurrDepth = std::numeric_limits<unsigned>::max();
|
||||
for (unsigned i = 0, e = MBBs.size(); i != e; ++i) {
|
||||
// Try coalescing the collected local copies for deeper loops.
|
||||
if (JoinGlobalCopies && MBBs[i].Depth < CurrDepth) {
|
||||
|
@ -3310,7 +3332,6 @@ void RegisterCoalescer::releaseMemory() {
|
|||
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
|
||||
MF = &fn;
|
||||
MRI = &fn.getRegInfo();
|
||||
TM = &fn.getTarget();
|
||||
const TargetSubtargetInfo &STI = fn.getSubtarget();
|
||||
TRI = STI.getRegisterInfo();
|
||||
TII = STI.getInstrInfo();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- RegisterCoalescer.h - Register Coalescing Interface -----*- C++ -*-===//
|
||||
//===- RegisterCoalescer.h - Register Coalescing Interface ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -17,10 +17,9 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class MachineInstr;
|
||||
class TargetRegisterInfo;
|
||||
class TargetRegisterClass;
|
||||
class TargetInstrInfo;
|
||||
class MachineInstr;
|
||||
class TargetRegisterClass;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
/// A helper class for register coalescers. When deciding if
|
||||
/// two registers can be coalesced, CoalescerPair can determine if a copy
|
||||
|
@ -30,43 +29,40 @@ namespace llvm {
|
|||
|
||||
/// The register that will be left after coalescing. It can be a
|
||||
/// virtual or physical register.
|
||||
unsigned DstReg;
|
||||
unsigned DstReg = 0;
|
||||
|
||||
/// The virtual register that will be coalesced into dstReg.
|
||||
unsigned SrcReg;
|
||||
unsigned SrcReg = 0;
|
||||
|
||||
/// The sub-register index of the old DstReg in the new coalesced register.
|
||||
unsigned DstIdx;
|
||||
unsigned DstIdx = 0;
|
||||
|
||||
/// The sub-register index of the old SrcReg in the new coalesced register.
|
||||
unsigned SrcIdx;
|
||||
unsigned SrcIdx = 0;
|
||||
|
||||
/// True when the original copy was a partial subregister copy.
|
||||
bool Partial;
|
||||
bool Partial = false;
|
||||
|
||||
/// True when both regs are virtual and newRC is constrained.
|
||||
bool CrossClass;
|
||||
bool CrossClass = false;
|
||||
|
||||
/// True when DstReg and SrcReg are reversed from the original
|
||||
/// copy instruction.
|
||||
bool Flipped;
|
||||
bool Flipped = false;
|
||||
|
||||
/// The register class of the coalesced register, or NULL if DstReg
|
||||
/// is a physreg. This register class may be a super-register of both
|
||||
/// SrcReg and DstReg.
|
||||
const TargetRegisterClass *NewRC;
|
||||
const TargetRegisterClass *NewRC = nullptr;
|
||||
|
||||
public:
|
||||
CoalescerPair(const TargetRegisterInfo &tri)
|
||||
: TRI(tri), DstReg(0), SrcReg(0), DstIdx(0), SrcIdx(0),
|
||||
Partial(false), CrossClass(false), Flipped(false), NewRC(nullptr) {}
|
||||
CoalescerPair(const TargetRegisterInfo &tri) : TRI(tri) {}
|
||||
|
||||
/// Create a CoalescerPair representing a virtreg-to-physreg copy.
|
||||
/// No need to call setRegisters().
|
||||
CoalescerPair(unsigned VirtReg, unsigned PhysReg,
|
||||
const TargetRegisterInfo &tri)
|
||||
: TRI(tri), DstReg(PhysReg), SrcReg(VirtReg), DstIdx(0), SrcIdx(0),
|
||||
Partial(false), CrossClass(false), Flipped(false), NewRC(nullptr) {}
|
||||
: TRI(tri), DstReg(PhysReg), SrcReg(VirtReg) {}
|
||||
|
||||
/// Set registers to match the copy instruction MI. Return
|
||||
/// false if MI is not a coalescable copy instruction.
|
||||
|
@ -111,6 +107,7 @@ namespace llvm {
|
|||
/// Return the register class of the coalesced register.
|
||||
const TargetRegisterClass *getNewRC() const { return NewRC; }
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_CODEGEN_REGISTERCOALESCER_H
|
||||
|
|
Loading…
Reference in New Issue