aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPreston Gurd <preston.gurd@intel.com>2013-01-11 22:06:56 +0000
committerPreston Gurd <preston.gurd@intel.com>2013-01-11 22:06:56 +0000
commit1452d46e0bc5ca6bea77ca85abf9b694e3b6ab84 (patch)
tree7dbd6e92b413b566462bcf3c54406ad969fbf818
parent8ecd3be1f3687222bfed627219844557024fcec1 (diff)
downloadexternal_llvm-1452d46e0bc5ca6bea77ca85abf9b694e3b6ab84.zip
external_llvm-1452d46e0bc5ca6bea77ca85abf9b694e3b6ab84.tar.gz
external_llvm-1452d46e0bc5ca6bea77ca85abf9b694e3b6ab84.tar.bz2
Update patch for the pad short functions pass for Intel Atom (only).
Adds a check for -Oz, changes the code to not re-visit BBs, and skips over DBG_VALUE instrs. Patch by Andy Zhang. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172258 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86PadShortFunction.cpp77
-rw-r--r--test/CodeGen/X86/atom-pad-short-functions.ll25
2 files changed, 84 insertions, 18 deletions
diff --git a/lib/Target/X86/X86PadShortFunction.cpp b/lib/Target/X86/X86PadShortFunction.cpp
index c22872f..83e75ea 100644
--- a/lib/Target/X86/X86PadShortFunction.cpp
+++ b/lib/Target/X86/X86PadShortFunction.cpp
@@ -33,6 +33,19 @@ using namespace llvm;
STATISTIC(NumBBsPadded, "Number of basic blocks padded");
namespace {
+ struct VisitedBBInfo {
+ // HasReturn - Whether the BB contains a return instruction
+ bool HasReturn;
+
+ // Cycles - Number of cycles until return if HasReturn is true, otherwise
+ // number of cycles until end of the BB
+ unsigned int Cycles;
+
+ VisitedBBInfo() : HasReturn(false), Cycles(0) {}
+ VisitedBBInfo(bool HasReturn, unsigned int Cycles)
+ : HasReturn(HasReturn), Cycles(Cycles) {}
+ };
+
struct PadShortFunc : public MachineFunctionPass {
static char ID;
PadShortFunc() : MachineFunctionPass(ID)
@@ -49,16 +62,21 @@ namespace {
unsigned int Cycles = 0);
bool cyclesUntilReturn(MachineBasicBlock *MBB,
- unsigned int &Cycles,
- MachineBasicBlock::iterator *Location = 0);
+ unsigned int &Cycles);
void addPadding(MachineBasicBlock *MBB,
MachineBasicBlock::iterator &MBBI,
unsigned int NOOPsToAdd);
const unsigned int Threshold;
+
+ // ReturnBBs - Maps basic blocks that return to the minimum number of
+ // cycles until the return, starting from the entry block.
DenseMap<MachineBasicBlock*, unsigned int> ReturnBBs;
+ // VisitedBBs - Cache of previously visited BBs.
+ DenseMap<MachineBasicBlock*, VisitedBBInfo> VisitedBBs;
+
const TargetMachine *TM;
const TargetInstrInfo *TII;
};
@@ -73,25 +91,26 @@ FunctionPass *llvm::createX86PadShortFunctions() {
/// runOnMachineFunction - Loop over all of the basic blocks, inserting
/// NOOP instructions before early exits.
bool PadShortFunc::runOnMachineFunction(MachineFunction &MF) {
- bool OptForSize = MF.getFunction()->getAttributes().
- hasAttribute(AttributeSet::FunctionIndex, Attribute::OptimizeForSize);
-
- if (OptForSize)
+ const AttributeSet &FnAttrs = MF.getFunction()->getAttributes();
+ if (FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::OptimizeForSize) ||
+ FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::MinSize)) {
return false;
+ }
TM = &MF.getTarget();
TII = TM->getInstrInfo();
// Search through basic blocks and mark the ones that have early returns
ReturnBBs.clear();
+ VisitedBBs.clear();
findReturns(MF.begin());
bool MadeChange = false;
- MachineBasicBlock::iterator ReturnLoc;
MachineBasicBlock *MBB;
unsigned int Cycles = 0;
- unsigned int BBCycles;
// Pad the identified basic blocks with NOOPs
for (DenseMap<MachineBasicBlock*, unsigned int>::iterator I = ReturnBBs.begin();
@@ -100,8 +119,16 @@ bool PadShortFunc::runOnMachineFunction(MachineFunction &MF) {
Cycles = I->second;
if (Cycles < Threshold) {
- if (!cyclesUntilReturn(MBB, BBCycles, &ReturnLoc))
- continue;
+ // BB ends in a return. Skip over any DBG_VALUE instructions
+ // trailing the terminator.
+ assert(MBB->size() > 0 &&
+ "Basic block should contain at least a RET but is empty");
+ MachineBasicBlock::iterator ReturnLoc = --MBB->end();
+
+ while (ReturnLoc->isDebugValue())
+ --ReturnLoc;
+ assert(ReturnLoc->isReturn() && !ReturnLoc->isCall() &&
+ "Basic block does not end with RET");
addPadding(MBB, ReturnLoc, Threshold - Cycles);
NumBBsPadded++;
@@ -127,18 +154,30 @@ void PadShortFunc::findReturns(MachineBasicBlock *MBB, unsigned int Cycles) {
// Follow branches in BB and look for returns
for (MachineBasicBlock::succ_iterator I = MBB->succ_begin();
- I != MBB->succ_end(); ++I) {
+ I != MBB->succ_end(); ++I) {
+ if (*I == MBB)
+ continue;
findReturns(*I, Cycles);
}
}
-/// cyclesUntilReturn - if the MBB has a return instruction, set Location
-/// to the instruction and return true. Return false otherwise.
+/// cyclesUntilReturn - return true if the MBB has a return instruction,
+/// and return false otherwise.
/// Cycles will be incremented by the number of cycles taken to reach the
/// return or the end of the BB, whichever occurs first.
bool PadShortFunc::cyclesUntilReturn(MachineBasicBlock *MBB,
- unsigned int &Cycles,
- MachineBasicBlock::iterator *Location) {
+ unsigned int &Cycles) {
+ // Return cached result if BB was previously visited
+ DenseMap<MachineBasicBlock*, VisitedBBInfo>::iterator it
+ = VisitedBBs.find(MBB);
+ if (it != VisitedBBs.end()) {
+ VisitedBBInfo BBInfo = it->second;
+ Cycles += BBInfo.Cycles;
+ return BBInfo.HasReturn;
+ }
+
+ unsigned int CyclesToEnd = 0;
+
for (MachineBasicBlock::iterator MBBI = MBB->begin();
MBBI != MBB->end(); ++MBBI) {
MachineInstr *MI = MBBI;
@@ -146,14 +185,16 @@ bool PadShortFunc::cyclesUntilReturn(MachineBasicBlock *MBB,
// functions do not count because the called function will be padded,
// if necessary.
if (MI->isReturn() && !MI->isCall()) {
- if (Location)
- *Location = MBBI;
+ VisitedBBs[MBB] = VisitedBBInfo(true, CyclesToEnd);
+ Cycles += CyclesToEnd;
return true;
}
- Cycles += TII->getInstrLatency(TM->getInstrItineraryData(), MI);
+ CyclesToEnd += TII->getInstrLatency(TM->getInstrItineraryData(), MI);
}
+ VisitedBBs[MBB] = VisitedBBInfo(false, CyclesToEnd);
+ Cycles += CyclesToEnd;
return false;
}
diff --git a/test/CodeGen/X86/atom-pad-short-functions.ll b/test/CodeGen/X86/atom-pad-short-functions.ll
index 54af17d..b9a39e0 100644
--- a/test/CodeGen/X86/atom-pad-short-functions.ll
+++ b/test/CodeGen/X86/atom-pad-short-functions.ll
@@ -22,6 +22,13 @@ define i32 @test_optsize(i32 %a) nounwind optsize {
ret i32 %a
}
+define i32 @test_minsize(i32 %a) nounwind minsize {
+; CHECK: test_minsize
+; CHECK: movl
+; CHECK-NEXT: ret
+ ret i32 %a
+}
+
define i32 @test_add(i32 %a, i32 %b) nounwind {
; CHECK: test_add
; CHECK: addl
@@ -76,3 +83,21 @@ if.end:
ret void
}
+
+define void @test_branch_to_same_bb(i32 %x, i32 %y) nounwind {
+; CHECK: @test_branch_to_same_bb
+ %cmp = icmp sgt i32 %x, 0
+ br i1 %cmp, label %while.cond, label %while.end
+
+while.cond:
+ br label %while.cond
+
+; CHECK: nop
+; CHECK: nop
+; CHECK: nop
+; CHECK: nop
+; CHECK: ret
+while.end:
+ ret void
+}
+