[llvm-commits] [llvm] r126651 - in /llvm/trunk/lib/Target/CellSPU: SPUAsmPrinter.cpp SPUInstrFormats.td SPUInstrInfo.cpp SPUInstrInfo.td
Kalle Raiskila
kalle.raiskila at nokia.com
Mon Feb 28 06:08:24 PST 2011
Author: kraiskil
Date: Mon Feb 28 08:08:24 2011
New Revision: 126651
URL: http://llvm.org/viewvc/llvm-project?rev=126651&view=rev
Log:
Add branch hinting for SPU.
The implemented algorithm is overly simplistic (just speculate all branches are
taken)- this is work in progress.
Modified:
llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp
llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td
llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp
llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td
Modified: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp?rev=126651&r1=126650&r2=126651&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp Mon Feb 28 08:08:24 2011
@@ -182,6 +182,10 @@
printOp(MI->getOperand(OpNo), O);
}
+ void printHBROperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
+ printOp(MI->getOperand(OpNo), O);
+ }
+
void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// Used to generate a ".-<target>", but it turns out that the assembler
// really wants the target.
@@ -279,6 +283,9 @@
}
O << *Mang->getSymbol(MO.getGlobal());
return;
+ case MachineOperand::MO_MCSymbol:
+ O << *(MO.getMCSymbol());
+ return;
default:
O << "<unknown operand type: " << MO.getType() << ">";
return;
Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td?rev=126651&r1=126650&r2=126651&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td Mon Feb 28 08:08:24 2011
@@ -296,3 +296,25 @@
let Pattern = pattern;
let Inst{31-0} = 0;
}
+
+//===----------------------------------------------------------------------===//
+// Branch hint formats
+//===----------------------------------------------------------------------===//
+// For hbrr and hbra
+class HBI16Form<bits<7> opcode, dag IOL, string asmstr>
+ : Instruction {
+ field bits<32> Inst;
+ bits<16>i16;
+ bits<9>RO;
+
+ let Namespace = "SPU";
+ let InOperandList = IOL;
+ let OutOperandList = (outs); //no output
+ let AsmString = asmstr;
+ let Itinerary = BranchHints;
+
+ let Inst{0-6} = opcode;
+ let Inst{7-8} = RO{8-7};
+ let Inst{9-24} = i16;
+ let Inst{25-31} = RO{6-0};
+}
Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=126651&r1=126650&r2=126651&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Mon Feb 28 08:08:24 2011
@@ -21,6 +21,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/MC/MCContext.h"
using namespace llvm;
@@ -281,9 +282,20 @@
return true;
}
+// search MBB for branch hint labels and branch hit ops
+static void removeHBR( MachineBasicBlock &MBB) {
+ for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I){
+ if (I->getOpcode() == SPU::HBRA ||
+ I->getOpcode() == SPU::HBR_LABEL){
+ I=MBB.erase(I);
+ }
+ }
+}
+
unsigned
SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator I = MBB.end();
+ removeHBR(MBB);
if (I == MBB.begin())
return 0;
--I;
@@ -314,6 +326,23 @@
return 2;
}
+/** Find the optimal position for a hint branch instruction in a basic block.
+ * This should take into account:
+ * -the branch hint delays
+ * -congestion of the memory bus
+ * -dual-issue scheduling (i.e. avoid insertion of nops)
+ * Current implementation is rather simplistic.
+ */
+static MachineBasicBlock::iterator findHBRPosition(MachineBasicBlock &MBB)
+{
+ MachineBasicBlock::iterator J = MBB.end();
+ for( int i=0; i<8; i++) {
+ if( J == MBB.begin() ) return J;
+ J--;
+ }
+ return J;
+}
+
unsigned
SPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
@@ -324,32 +353,61 @@
assert((Cond.size() == 2 || Cond.size() == 0) &&
"SPU branch conditions have two components!");
+ MachineInstrBuilder MIB;
+ //TODO: make a more accurate algorithm.
+ bool haveHBR = MBB.size()>8;
+
+ removeHBR(MBB);
+ MCSymbol *branchLabel = MBB.getParent()->getContext().CreateTempSymbol();
+ // Add a label just before the branch
+ if (haveHBR)
+ MIB = BuildMI(&MBB, DL, get(SPU::HBR_LABEL)).addSym(branchLabel);
+
// One-way branch.
if (FBB == 0) {
if (Cond.empty()) {
// Unconditional branch
- MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(SPU::BR));
+ MIB = BuildMI(&MBB, DL, get(SPU::BR));
MIB.addMBB(TBB);
DEBUG(errs() << "Inserted one-way uncond branch: ");
DEBUG((*MIB).dump());
+
+ // basic blocks have just one branch so it is safe to add the hint a its
+ if (haveHBR) {
+ MIB = BuildMI( MBB, findHBRPosition(MBB), DL, get(SPU::HBRA));
+ MIB.addSym(branchLabel);
+ MIB.addMBB(TBB);
+ }
} else {
// Conditional branch
- MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
+ MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
MIB.addReg(Cond[1].getReg()).addMBB(TBB);
+ if (haveHBR) {
+ MIB = BuildMI(MBB, findHBRPosition(MBB), DL, get(SPU::HBRA));
+ MIB.addSym(branchLabel);
+ MIB.addMBB(TBB);
+ }
+
DEBUG(errs() << "Inserted one-way cond branch: ");
DEBUG((*MIB).dump());
}
return 1;
} else {
- MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
+ MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
MachineInstrBuilder MIB2 = BuildMI(&MBB, DL, get(SPU::BR));
// Two-way Conditional Branch.
MIB.addReg(Cond[1].getReg()).addMBB(TBB);
MIB2.addMBB(FBB);
+ if (haveHBR) {
+ MIB = BuildMI( MBB, findHBRPosition(MBB), DL, get(SPU::HBRA));
+ MIB.addSym(branchLabel);
+ MIB.addMBB(FBB);
+ }
+
DEBUG(errs() << "Inserted conditional branch: ");
DEBUG((*MIB).dump());
DEBUG(errs() << "part 2: ");
Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=126651&r1=126650&r2=126651&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Mon Feb 28 08:08:24 2011
@@ -28,6 +28,8 @@
def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm_i32:$amt),
"${:comment} ADJCALLSTACKUP",
[(callseq_end timm:$amt)]>;
+ def HBR_LABEL : Pseudo<(outs), (ins hbrtarget:$targ),
+ "$targ:\t${:comment}branch hint target",[ ]>;
}
//===----------------------------------------------------------------------===//
@@ -4208,8 +4210,8 @@
//===----------------------------------------------------------------------===//
// Hint for branch instructions:
//===----------------------------------------------------------------------===//
-
-/* def HBR : SPUInstr<(outs), (ins), "hbr\t" */
+def HBRA :
+ HBI16Form<0b0001001,(ins hbrtarget:$brinst, brtarget:$btarg), "hbra\t$brinst, $btarg">;
//===----------------------------------------------------------------------===//
// Execution, Load NOP (execute NOPs belong in even pipeline, load NOPs belong
More information about the llvm-commits
mailing list