summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.cpp57
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.h4
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp11
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp17
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp40
-rw-r--r--lib/CodeGen/MachineLICM.cpp107
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp6
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp5
-rw-r--r--lib/CodeGen/SlotIndexes.cpp4
9 files changed, 164 insertions, 87 deletions
diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index ffb6315..86d051c 100644
--- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -491,8 +491,9 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) {
}
bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
- unsigned AntiDepGroupIndex,
- std::map<unsigned, unsigned> &RenameMap) {
+ unsigned AntiDepGroupIndex,
+ RenameOrderType& RenameOrder,
+ std::map<unsigned, unsigned> &RenameMap) {
unsigned *KillIndices = State->GetKillIndices();
unsigned *DefIndices = State->GetDefIndices();
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
@@ -547,22 +548,41 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
if (Regs.size() > 1)
return false;
- // Check each possible rename register for SuperReg. If that register
- // is available, and the corresponding registers are available for
- // the other group subregisters, then we can use those registers to
- // rename.
- DEBUG(errs() << "\tFind Register:");
+ // Check each possible rename register for SuperReg in round-robin
+ // order. If that register is available, and the corresponding
+ // registers are available for the other group subregisters, then we
+ // can use those registers to rename.
BitVector SuperBV = RenameRegisterMap[SuperReg];
- for (int r = SuperBV.find_first(); r != -1; r = SuperBV.find_next(r)) {
- const unsigned Reg = (unsigned)r;
+ const TargetRegisterClass *SuperRC =
+ TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);
+
+ const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);
+ const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);
+ if (RB == RE) {
+ DEBUG(errs() << "\tEmpty Regclass!!\n");
+ return false;
+ }
+
+ if (RenameOrder.count(SuperRC) == 0)
+ RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE));
+
+ DEBUG(errs() << "\tFind Register:");
+
+ const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC];
+ const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR);
+ TargetRegisterClass::iterator R = OrigR;
+ do {
+ if (R == RB) R = RE;
+ --R;
+ const unsigned Reg = *R;
// Don't replace a register with itself.
if (Reg == SuperReg) continue;
-
+
DEBUG(errs() << " " << TRI->getName(Reg));
-
+
// If Reg is dead and Reg's most recent def is not before
- // SuperRegs's kill, it's safe to replace SuperReg with
- // Reg. We must also check all subregisters of Reg.
+ // SuperRegs's kill, it's safe to replace SuperReg with Reg. We
+ // must also check all subregisters of Reg.
if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) {
DEBUG(errs() << "(live)");
continue;
@@ -580,13 +600,15 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
if (found)
continue;
}
-
+
if (Reg != 0) {
DEBUG(errs() << '\n');
+ RenameOrder.erase(SuperRC);
+ RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg));
return true;
}
- }
+ } while (R != EndR);
DEBUG(errs() << '\n');
@@ -627,6 +649,9 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
State = new AggressiveAntiDepState(*SavedState);
}
}
+
+ // For each regclass the next register to use for renaming.
+ RenameOrderType RenameOrder;
// ...need a map from MI to SUnit.
std::map<MachineInstr *, SUnit *> MISUnitMap;
@@ -738,7 +763,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
// Look for a suitable register to use to break the anti-dependence.
std::map<unsigned, unsigned> RenameMap;
- if (FindSuitableFreeRegisters(GroupIndex, RenameMap)) {
+ if (FindSuitableFreeRegisters(GroupIndex, RenameOrder, RenameMap)) {
DEBUG(errs() << "\tBreaking anti-dependence edge on "
<< TRI->getName(AntiDepReg) << ":");
diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.h b/lib/CodeGen/AggressiveAntiDepBreaker.h
index 5d9b40b..c512168 100644
--- a/lib/CodeGen/AggressiveAntiDepBreaker.h
+++ b/lib/CodeGen/AggressiveAntiDepBreaker.h
@@ -155,6 +155,9 @@ namespace llvm {
void FinishBlock();
private:
+ typedef std::map<const TargetRegisterClass *,
+ TargetRegisterClass::const_iterator> RenameOrderType;
+
/// IsImplicitDefUse - Return true if MO represents a register
/// that is both implicitly used and defined in MI
bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO);
@@ -169,6 +172,7 @@ namespace llvm {
void ScanInstruction(MachineInstr *MI, unsigned Count);
BitVector GetRenameRegisters(unsigned Reg);
bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex,
+ RenameOrderType& RenameOrder,
std::map<unsigned, unsigned> &RenameMap);
};
}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 58f3aa5..bb6bd95 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1590,6 +1590,17 @@ void AsmPrinter::printImplicitDef(const MachineInstr *MI) const {
<< TRI->getName(MI->getOperand(0).getReg());
}
+void AsmPrinter::printKill(const MachineInstr *MI) const {
+ if (!VerboseAsm) return;
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << " kill:";
+ for (unsigned n = 0, e = MI->getNumOperands(); n != e; ++n) {
+ const MachineOperand &op = MI->getOperand(n);
+ assert(op.isReg() && "KILL instruction must have only register operands");
+ O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "<def>" : "<kill>");
+ }
+}
+
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
void AsmPrinter::printLabel(const MachineInstr *MI) const {
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 23752c4..1372fc2 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1137,6 +1137,9 @@ DIE *DwarfDebug::CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
AddSourceLine(MemberDie, &DT);
+ DIEBlock *MemLocationDie = new DIEBlock();
+ AddUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+
uint64_t Size = DT.getSizeInBits();
uint64_t FieldSize = DT.getOriginalTypeSize();
@@ -1155,12 +1158,16 @@ DIE *DwarfDebug::CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
// Maybe we need to work from the other end.
if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size);
AddUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
- }
- DIEBlock *Block = new DIEBlock();
- AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
- AddUInt(Block, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
- AddBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, Block);
+ // Here WD_AT_data_member_location points to the anonymous
+ // field that includes this bit field.
+ AddUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
+
+ } else
+ // This is not a bitfield.
+ AddUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
+
+ AddBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
if (DT.isProtected())
AddUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 6300a52..0db459b 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -31,6 +31,22 @@ namespace llvm {
bool EnableFastISel;
}
+static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden,
+ cl::desc("Disable Post Regalloc"));
+static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
+ cl::desc("Disable branch folding"));
+static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden,
+ cl::desc("Disable code placement"));
+static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
+ cl::desc("Disable Stack Slot Coloring"));
+static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
+ cl::desc("Disable Machine LICM"));
+static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
+ cl::desc("Disable Machine Sinking"));
+static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
+ cl::desc("Disable Loop Strength Reduction Pass"));
+static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
+ cl::desc("Disable Codegen Prepare"));
static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
@@ -208,7 +224,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Standard LLVM-Level Passes.
// Run loop strength reduction before anything else.
- if (OptLevel != CodeGenOpt::None) {
+ if (OptLevel != CodeGenOpt::None && !DisableLSR) {
PM.add(createLoopStrengthReducePass(getTargetLowering()));
if (PrintLSR)
PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &errs()));
@@ -236,7 +252,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Make sure that no unreachable blocks are instruction selected.
PM.add(createUnreachableBlockEliminationPass());
- if (OptLevel != CodeGenOpt::None)
+ if (OptLevel != CodeGenOpt::None && !DisableCGP)
PM.add(createCodeGenPreparePass(getTargetLowering()));
PM.add(createStackProtectorPass(getTargetLowering()));
@@ -265,8 +281,10 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
/* allowDoubleDefs= */ true);
if (OptLevel != CodeGenOpt::None) {
- PM.add(createMachineLICMPass());
- PM.add(createMachineSinkingPass());
+ if (!DisableMachineLICM)
+ PM.add(createMachineLICMPass());
+ if (!DisableMachineSink)
+ PM.add(createMachineSinkingPass());
printAndVerify(PM, "After MachineLICM and MachineSinking",
/* allowDoubleDefs= */ true);
}
@@ -281,7 +299,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
printAndVerify(PM, "After Register Allocation");
// Perform stack slot coloring.
- if (OptLevel != CodeGenOpt::None) {
+ if (OptLevel != CodeGenOpt::None && !DisableSSC) {
// FIXME: Re-enable coloring with register when it's capable of adding
// kill markers.
PM.add(createStackSlotColoringPass(false));
@@ -304,13 +322,13 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
printAndVerify(PM, "After PreSched2 passes");
// Second pass scheduler.
- if (OptLevel != CodeGenOpt::None) {
+ if (OptLevel != CodeGenOpt::None && !DisablePostRA) {
PM.add(createPostRAScheduler(OptLevel));
printAndVerify(PM, "After PostRAScheduler");
}
// Branch folding must be run after regalloc and prolog/epilog insertion.
- if (OptLevel != CodeGenOpt::None) {
+ if (OptLevel != CodeGenOpt::None && !DisableBranchFold) {
PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
printAndVerify(PM, "After BranchFolding");
}
@@ -324,13 +342,13 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createDebugLabelFoldingPass());
printAndVerify(PM, "After DebugLabelFolding");
- if (addPreEmitPass(PM, OptLevel))
- printAndVerify(PM, "After PreEmit passes");
-
- if (OptLevel != CodeGenOpt::None) {
+ if (OptLevel != CodeGenOpt::None && !DisableCodePlace) {
PM.add(createCodePlacementOptPass());
printAndVerify(PM, "After CodePlacementOpt");
}
+ if (addPreEmitPass(PM, OptLevel))
+ printAndVerify(PM, "After PreEmit passes");
+
return false;
}
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index 1306aa6..de3ab27 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -111,6 +111,13 @@ namespace {
/// be hoistable.
MachineInstr *ExtractHoistableLoad(MachineInstr *MI);
+ /// EliminateCSE - Given a LICM'ed instruction, look for an instruction on
+ /// the preheader that compute the same value. If it's found, do a RAU on
+ /// with the definition of the existing instruction rather than hoisting
+ /// the instruction to the preheader.
+ bool EliminateCSE(MachineInstr *MI,
+ DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator &CI);
+
/// Hoist - When an instruction is found to only use loop invariant operands
/// that is safe to hoist, this instruction is called to do the dirty work.
///
@@ -349,37 +356,6 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
return true;
}
-static const MachineInstr *LookForDuplicate(const MachineInstr *MI,
- std::vector<const MachineInstr*> &PrevMIs,
- MachineRegisterInfo *RegInfo) {
- unsigned NumOps = MI->getNumOperands();
- for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) {
- const MachineInstr *PrevMI = PrevMIs[i];
- unsigned NumOps2 = PrevMI->getNumOperands();
- if (NumOps != NumOps2)
- continue;
- bool IsSame = true;
- for (unsigned j = 0; j != NumOps; ++j) {
- const MachineOperand &MO = MI->getOperand(j);
- if (MO.isReg() && MO.isDef()) {
- if (RegInfo->getRegClass(MO.getReg()) !=
- RegInfo->getRegClass(PrevMI->getOperand(j).getReg())) {
- IsSame = false;
- break;
- }
- continue;
- }
- if (!MO.isIdenticalTo(PrevMI->getOperand(j))) {
- IsSame = false;
- break;
- }
- }
- if (IsSame)
- return PrevMI;
- }
- return 0;
-}
-
MachineInstr *MachineLICM::ExtractHoistableLoad(MachineInstr *MI) {
// If not, we may be able to unfold a load and hoist that.
// First test whether the instruction is loading from an amenable
@@ -456,6 +432,55 @@ void MachineLICM::InitCSEMap(MachineBasicBlock *BB) {
}
}
+static const MachineInstr *LookForDuplicate(const MachineInstr *MI,
+ std::vector<const MachineInstr*> &PrevMIs,
+ MachineRegisterInfo *RegInfo) {
+ unsigned NumOps = MI->getNumOperands();
+ for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) {
+ const MachineInstr *PrevMI = PrevMIs[i];
+ unsigned NumOps2 = PrevMI->getNumOperands();
+ if (NumOps != NumOps2)
+ continue;
+ bool IsSame = true;
+ for (unsigned j = 0; j != NumOps; ++j) {
+ const MachineOperand &MO = MI->getOperand(j);
+ if (MO.isReg() && MO.isDef()) {
+ if (RegInfo->getRegClass(MO.getReg()) !=
+ RegInfo->getRegClass(PrevMI->getOperand(j).getReg())) {
+ IsSame = false;
+ break;
+ }
+ continue;
+ }
+ if (!MO.isIdenticalTo(PrevMI->getOperand(j))) {
+ IsSame = false;
+ break;
+ }
+ }
+ if (IsSame)
+ return PrevMI;
+ }
+ return 0;
+}
+
+bool MachineLICM::EliminateCSE(MachineInstr *MI,
+ DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator &CI) {
+ if (CI != CSEMap.end()) {
+ if (const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo)) {
+ DEBUG(errs() << "CSEing " << *MI << " with " << *Dup);
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isDef())
+ RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg());
+ }
+ MI->eraseFromParent();
+ ++NumCSEed;
+ return true;
+ }
+ }
+ return false;
+}
+
/// Hoist - When an instruction is found to use only loop invariant operands
/// that are safe to hoist, this instruction is called to do the dirty work.
///
@@ -488,24 +513,8 @@ void MachineLICM::Hoist(MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator
CI = CSEMap.find(Opcode);
- bool DoneCSE = false;
- if (CI != CSEMap.end()) {
- const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo);
- if (Dup) {
- DEBUG(errs() << "CSEing " << *MI << " with " << *Dup);
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef())
- RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg());
- }
- MI->eraseFromParent();
- DoneCSE = true;
- ++NumCSEed;
- }
- }
-
- // Otherwise, splice the instruction to the preheader.
- if (!DoneCSE) {
+ if (!EliminateCSE(MI, CI)) {
+ // Otherwise, splice the instruction to the preheader.
CurPreheader->splice(CurPreheader->getFirstTerminator(),MI->getParent(),MI);
// Add to the CSE map.
diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp
index d5edb36..3ed61a2 100644
--- a/lib/CodeGen/PostRASchedulerList.cpp
+++ b/lib/CodeGen/PostRASchedulerList.cpp
@@ -770,7 +770,8 @@ void SchedulePostRATDList::ListScheduleTopDown(
// just advance the current cycle and try again.
DEBUG(errs() << "*** Stall in cycle " << CurCycle << '\n');
HazardRec->AdvanceCycle();
- ++NumStalls;
+ if (!IgnoreAntiDep)
+ ++NumStalls;
} else {
// Otherwise, we have no instructions to issue and we have instructions
// that will fault if we don't do this right. This is the case for
@@ -778,7 +779,8 @@ void SchedulePostRATDList::ListScheduleTopDown(
DEBUG(errs() << "*** Emitting noop in cycle " << CurCycle << '\n');
HazardRec->EmitNoop();
Sequence.push_back(0); // NULL here means noop
- ++NumNoops;
+ if (!IgnoreAntiDep)
+ ++NumNoops;
}
++CurCycle;
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index 6070ff6..f8b219d 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -367,6 +367,7 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency));
I->second.clear();
+ I->second.push_back(SU);
}
// See if it is known to just have a single memory reference.
MachineInstr *ChainMI = Chain->getInstr();
@@ -413,7 +414,7 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
if (Chain)
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
}
- } else if (MayAlias) {
+ } else {
// Treat all other stores conservatively.
goto new_chain;
}
@@ -439,7 +440,7 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
// Treat volatile loads conservatively. Note that this includes
// cases where memoperand information is unavailable.
goto new_chain;
- } else if (MayAlias) {
+ } else {
// A "MayAlias" load. Depend on the general chain, as well as on
// all stores. In the absense of MachineMemOperand information,
// we can't even assume that the load doesn't alias well-behaved
diff --git a/lib/CodeGen/SlotIndexes.cpp b/lib/CodeGen/SlotIndexes.cpp
index 6b04029..f3ad0d1 100644
--- a/lib/CodeGen/SlotIndexes.cpp
+++ b/lib/CodeGen/SlotIndexes.cpp
@@ -16,8 +16,8 @@
using namespace llvm;
-std::auto_ptr<IndexListEntry> SlotIndex::emptyKeyPtr(0),
- SlotIndex::tombstoneKeyPtr(0);
+std::auto_ptr<IndexListEntry> IndexListEntry::emptyKeyEntry,
+ IndexListEntry::tombstoneKeyEntry;
char SlotIndexes::ID = 0;
static RegisterPass<SlotIndexes> X("slotindexes", "Slot index numbering");
OpenPOWER on IntegriCloud