Changes in directory llvm/lib/Target/PowerPC:
PPCAsmPrinter.cpp updated: 1.163 -> 1.164 PPCCodeEmitter.cpp updated: 1.52 -> 1.53 PPCISelDAGToDAG.cpp updated: 1.179 -> 1.180 PPCISelLowering.cpp updated: 1.167 -> 1.168 PPCInstrInfo.td updated: 1.217 -> 1.218 --- Log message: JumpTable support! What this represents is working asm and jit support for x86 and ppc for 100% dense switch statements when relocations are non-PIC. This support will be extended and enhanced in the coming days to support PIC, and less dense forms of jump tables. --- Diffs of the changes: (+79 -14) PPCAsmPrinter.cpp | 25 +++++++++++++++++++------ PPCCodeEmitter.cpp | 15 ++++++++++----- PPCISelDAGToDAG.cpp | 15 +++++++++++++-- PPCISelLowering.cpp | 32 ++++++++++++++++++++++++++++++++ PPCInstrInfo.td | 6 +++++- 5 files changed, 79 insertions(+), 14 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.163 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.164 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.163 Fri Apr 7 15:44:42 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Sat Apr 22 13:53:45 2006 @@ -233,6 +233,8 @@ printOperand(MI, OpNo+1); } + virtual void printBasicBlockLabel(const MachineBasicBlock *MBB) const; + virtual bool runOnMachineFunction(MachineFunction &F) = 0; virtual bool doFinalization(Module &M) = 0; @@ -277,6 +279,8 @@ Data64bitsDirective = 0; // we can't emit a 64-bit unit AlignmentIsInBytes = false; // Alignment is by power of 2. ConstantPoolSection = "\t.const\t"; + // FIXME: Conditionalize jump table section based on PIC + JumpTableSection = ".const"; LCOMMDirective = "\t.lcomm\t"; StaticCtorsSection = ".mod_init_func"; StaticDtorsSection = ".mod_term_func"; @@ -373,13 +377,14 @@ abort(); return; - case MachineOperand::MO_MachineBasicBlock: { - MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << "_" - << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName(); + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMachineBasicBlock()); + return; + case MachineOperand::MO_JumpTableIndex: + O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() + << '_' << MO.getJumpTableIndex(); + // FIXME: PIC relocation model return; - } - case MachineOperand::MO_ConstantPoolIndex: O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' << MO.getConstantPoolIndex(); @@ -500,6 +505,11 @@ return; } +void PPCAsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB) const { + O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << "_" + << MBB->getNumber() << '\t' << CommentString + << MBB->getBasicBlock()->getName(); +} /// runOnMachineFunction - This uses the printMachineInstruction() /// method to print assembly for each instruction. @@ -514,6 +524,9 @@ // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); + // Print out jump tables referenced by the function + EmitJumpTableInfo(MF.getJumpTableInfo()); + // Print out labels for the function. const Function *F = MF.getFunction(); switch (F->getLinkage()) { Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.52 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.53 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.52 Sat Apr 22 01:17:56 2006 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Sat Apr 22 13:53:45 2006 @@ -34,7 +34,7 @@ // Tracks which instruction references which BasicBlock std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs; // Tracks where each BasicBlock starts - std::map<MachineBasicBlock*, long> BBLocations; + std::map<MachineBasicBlock*, uint64_t> BBLocations; /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// @@ -91,8 +91,10 @@ "JIT relocation model must be set to static or default!"); MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); + MCE.initJumpTableInfo(MF.getJumpTableInfo()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) emitBasicBlock(*BB); + MCE.emitJumpTableInfo(MF.getJumpTableInfo(), BBLocations); MCE.finishFunction(MF); // Resolve branches to BasicBlocks for the entire function @@ -192,10 +194,13 @@ } else if (MO.isMachineBasicBlock()) { unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue(); BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC)); - } else if (MO.isConstantPoolIndex()) { - unsigned index = MO.getConstantPoolIndex(); + } else if (MO.isConstantPoolIndex() || MO.isJumpTableIndex()) { + if (MO.isConstantPoolIndex()) + rv = MCE.getConstantPoolEntryAddress(MO.getConstantPoolIndex()); + else + rv = MCE.getJumpTableEntryAddress(MO.getJumpTableIndex()); + unsigned Opcode = MI.getOpcode(); - rv = MCE.getConstantPoolEntryAddress(index); if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) { // lis wants hi16(addr) if ((short)rv < 0) rv += 1 << 16; @@ -206,7 +211,7 @@ // These load opcodes want lo16(addr) rv &= 0xffff; } else { - assert(0 && "Unknown constant pool using instruction!"); + assert(0 && "Unknown constant pool or jump table using instruction!"); } } else { std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.179 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.180 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.179 Sat Apr 8 17:45:08 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sat Apr 22 13:53:45 2006 @@ -520,7 +520,8 @@ && "Cannot handle constant offsets yet!"); Disp = N.getOperand(1).getOperand(0); // The global address. assert(Disp.getOpcode() == ISD::TargetGlobalAddress || - Disp.getOpcode() == ISD::TargetConstantPool); + Disp.getOpcode() == ISD::TargetConstantPool || + Disp.getOpcode() == ISD::TargetJumpTable); Base = N.getOperand(0); return true; // [&g+r] } @@ -661,7 +662,8 @@ && "Cannot handle constant offsets yet!"); Disp = N.getOperand(1).getOperand(0); // The global address. assert(Disp.getOpcode() == ISD::TargetGlobalAddress || - Disp.getOpcode() == ISD::TargetConstantPool); + Disp.getOpcode() == ISD::TargetConstantPool || + Disp.getOpcode() == ISD::TargetJumpTable); Base = N.getOperand(0); return true; // [&g+r] } @@ -1241,6 +1243,15 @@ N->getOperand(4), Chain); return; } + case ISD::BRIND: { + SDOperand Chain, Target; + Select(Chain, N->getOperand(0)); + Select(Target,N->getOperand(1)); + Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Target, + Chain), 0); + Result = CurDAG->SelectNodeTo(N, PPC::BCTR, MVT::Other, Chain); + return; + } } SelectCode(Result, Op); Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.167 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.168 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.167 Tue Apr 18 13:28:22 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Sat Apr 22 13:53:45 2006 @@ -123,6 +123,7 @@ // appropriate instructions to materialize the address. setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + setOperationAction(ISD::JumpTable, MVT::i32, Custom); // RET must be custom lowered, to meet ABI requirements setOperationAction(ISD::RET , MVT::Other, Custom); @@ -605,6 +606,36 @@ return Lo; } +static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { + JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); + SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32); + SDOperand Zero = DAG.getConstant(0, MVT::i32); + + const TargetMachine &TM = DAG.getTarget(); + + // If this is a non-darwin platform, we don't support non-static relo models + // yet. + if (TM.getRelocationModel() == Reloc::Static || + !TM.getSubtarget<PPCSubtarget>().isDarwin()) { + // Generate non-pic code that has direct accesses to the constant pool. + // The address of the global is just (hi(&g)+lo(&g)). + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero); + return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + } + + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero); + if (TM.getRelocationModel() == Reloc::PIC) { + // With PIC, the first instruction is actually "GR+hi(&G)". + Hi = DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + } + + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero); + Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + return Lo; +} + static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); GlobalValue *GV = GSDN->getGlobal(); @@ -1652,6 +1683,7 @@ default: assert(0 && "Wasn't expecting to be able to lower this!"); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); case ISD::RET: return LowerRET(Op, DAG); Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.217 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.218 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.217 Tue Apr 18 14:03:38 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sat Apr 22 13:53:45 2006 @@ -702,7 +702,7 @@ def MTLR : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; -def MFLR : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT", SprMFSPR>, +def MFLR : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT", SprMFSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; // Move to/from VRSAVE: despite being a SPR, the VRSAVE register is renamed like @@ -1015,10 +1015,14 @@ def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>; def : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>; def : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>; +def : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>; +def : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>; def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)), (ADDIS GPRC:$in, tconstpool:$g)>; +def : Pat<(add GPRC:$in, (PPChi tjumptable:$g, 0)), + (ADDIS GPRC:$in, tjumptable:$g)>; // Fused negative multiply subtract, alternate pattern def : Pat<(fsub F8RC:$B, (fmul F8RC:$A, F8RC:$C)), _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits