[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:
Eugene Zelenko 2017-09-22 23:46:57 +00:00
parent 85317f23df
commit f193332994
10 changed files with 322 additions and 182 deletions

View File

@ -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();

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

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

View File

@ -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))

View File

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

View File

@ -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();

View File

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