From lattner at cs.uiuc.edu Mon May 8 00:59:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 00:59:48 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Use.h User.h Message-ID: <200605080559.AAA13661@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Use.h updated: 1.14 -> 1.15 User.h updated: 1.35 -> 1.36 --- Log message: Move the definition of value_use_iterator::getOperandNo to User.h where the definition of the User class is available, this fixes the build with some compiler versions. --- Diffs of the changes: (+10 -4) Use.h | 7 +++---- User.h | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) Index: llvm/include/llvm/Use.h diff -u llvm/include/llvm/Use.h:1.14 llvm/include/llvm/Use.h:1.15 --- llvm/include/llvm/Use.h:1.14 Thu May 4 19:51:42 2006 +++ llvm/include/llvm/Use.h Mon May 8 00:59:36 2006 @@ -141,11 +141,10 @@ Use &getUse() const { return *U; } - /// getOperandNo - Return the operand # of this use in its User. + /// getOperandNo - Return the operand # of this use in its User. Defined in + /// User.h /// - unsigned getOperandNo() const { - return U - U->getUser()->op_begin(); - } + unsigned getOperandNo() const; }; Index: llvm/include/llvm/User.h diff -u llvm/include/llvm/User.h:1.35 llvm/include/llvm/User.h:1.36 --- llvm/include/llvm/User.h:1.35 Thu Apr 21 15:11:51 2005 +++ llvm/include/llvm/User.h Mon May 8 00:59:36 2006 @@ -112,6 +112,13 @@ template<> struct simplify_type : public simplify_type {}; + +// value_use_iterator::getOperandNo - Requires the definition of the User class. +template +unsigned value_use_iterator::getOperandNo() const { + return U - U->getUser()->op_begin(); +} + } // End llvm namespace #endif From evan.cheng at apple.com Mon May 8 03:01:40 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 8 May 2006 03:01:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86ISelDAGToDAG.cpp X86InstrInfo.cpp X86InstrInfo.td X86IntelAsmPrinter.cpp X86RegisterInfo.cpp X86RegisterInfo.td Message-ID: <200605080801.DAA24765@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.43 -> 1.44 X86ISelDAGToDAG.cpp updated: 1.58 -> 1.59 X86InstrInfo.cpp updated: 1.49 -> 1.50 X86InstrInfo.td updated: 1.265 -> 1.266 X86IntelAsmPrinter.cpp updated: 1.43 -> 1.44 X86RegisterInfo.cpp updated: 1.150 -> 1.151 X86RegisterInfo.td updated: 1.33 -> 1.34 --- Log message: Fixing truncate. Previously we were emitting truncate from r16 to r8 as movw. That is we promote the destination operand to r16. So %CH = TRUNC_R16_R8 %BP is emitted as movw %bp, %cx. This is incorrect. If %cl is live, it would be clobbered. Ideally we want to do the opposite, that is emitted it as movb ??, %ch But this is not possible since %bp does not have a r8 sub-register. We are now defining a new register class R16_ which is a subclass of R16 containing only those 16-bit registers that have r8 sub-registers (i.e. AX - DX). We isel the truncate to two instructions, a MOV16to16_ to copy the value to the R16_ class, followed by a TRUNC_R16_R8. Due to bug 770: http://llvm.cs.uiuc.edu/PR770 , the register colaescer is not going to coalesce between R16 and R16_. That will be fixed later so we can eliminate the MOV16to16_. Right now, it can only be eliminated if we are lucky that source and destination registers are the same. --- Diffs of the changes: (+100 -25) X86ATTAsmPrinter.cpp | 13 +++++++------ X86ISelDAGToDAG.cpp | 38 ++++++++++++++++++++++++++++++++++++++ X86InstrInfo.cpp | 1 + X86InstrInfo.td | 32 +++++++++++++++++++++++++------- X86IntelAsmPrinter.cpp | 13 +++++++------ X86RegisterInfo.cpp | 24 ++++++++++++++++++------ X86RegisterInfo.td | 4 ++++ 7 files changed, 100 insertions(+), 25 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.43 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.44 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.43 Fri May 5 00:40:20 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Mon May 8 03:01:26 2006 @@ -115,7 +115,7 @@ unsigned Reg = MO.getReg(); if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) { MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0) - ? MVT::i16 : MVT::i32; + ? MVT::i16 : MVT::i8; Reg = getX86SubSuperRegister(Reg, VT); } for (const char *Name = RI.get(Reg).Name; *Name; ++Name) @@ -366,12 +366,13 @@ const MachineOperand &MO1 = MI->getOperand(1); unsigned Reg0 = MO0.getReg(); unsigned Reg1 = MO1.getReg(); - if (MI->getOpcode() == X86::TRUNC_R16_R8) - Reg0 = getX86SubSuperRegister(Reg0, MVT::i16); + if (MI->getOpcode() == X86::TRUNC_R32_R16) + Reg1 = getX86SubSuperRegister(Reg1, MVT::i16); else - Reg0 = getX86SubSuperRegister(Reg0, MVT::i32); - if (Reg0 == Reg1) - O << CommentString << " TRUNCATE "; + Reg1 = getX86SubSuperRegister(Reg1, MVT::i8); + O << CommentString << " TRUNCATE "; + if (Reg0 != Reg1) + O << "\n\t"; break; } } Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.58 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.59 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.58 Fri May 5 00:40:20 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Mon May 8 03:01:26 2006 @@ -791,6 +791,44 @@ #endif return; } + + case ISD::TRUNCATE: { + if (NVT == MVT::i8) { + unsigned Opc2; + MVT::ValueType VT; + switch (Node->getOperand(0).getValueType()) { + default: assert(0 && "Unknown truncate!"); + case MVT::i16: + Opc = X86::MOV16to16_; + VT = MVT::i16; + Opc2 = X86::TRUNC_R16_R8; + break; + case MVT::i32: + Opc = X86::MOV32to32_; + VT = MVT::i32; + if (NVT == MVT::i16) + Opc2 = X86::TRUNC_R32_R16; + else + Opc2 = X86::TRUNC_R32_R8; + break; + } + + SDOperand Tmp0, Tmp1; + Select(Tmp0, Node->getOperand(0)); + Tmp1 = SDOperand(CurDAG->getTargetNode(Opc, VT, Tmp0), 0); + Result = CodeGenMap[N] = + SDOperand(CurDAG->getTargetNode(Opc2, NVT, Tmp1), 0); + +#ifndef NDEBUG + DEBUG(std::cerr << std::string(Indent-2, ' ')); + DEBUG(std::cerr << "== "); + DEBUG(Result.Val->dump(CurDAG)); + DEBUG(std::cerr << "\n"); + Indent -= 2; +#endif + return; + } + } } SelectCode(Result, N); Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.49 llvm/lib/Target/X86/X86InstrInfo.cpp:1.50 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.49 Tue Apr 18 11:44:51 2006 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Mon May 8 03:01:26 2006 @@ -28,6 +28,7 @@ unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); if (oc == X86::MOV8rr || oc == X86::MOV16rr || oc == X86::MOV32rr || + oc == X86::MOV16to16_ || oc == X86::MOV32to32_ || oc == X86::FpMOV || oc == X86::MOVSSrr || oc == X86::MOVSDrr || oc == X86::FsMOVAPSrr || oc == X86::FsMOVAPDrr || oc == X86::MOVAPSrr || oc == X86::MOVAPDrr || Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.265 llvm/lib/Target/X86/X86InstrInfo.td:1.266 --- llvm/lib/Target/X86/X86InstrInfo.td:1.265 Fri May 5 03:23:07 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon May 8 03:01:26 2006 @@ -357,15 +357,13 @@ def NOOP : I<0x90, RawFrm, (ops), "nop", []>; // Truncate -def TRUNC_R32_R8 : I<0x89, MRMDestReg, (ops R8:$dst, R32:$src), - "mov{l} {$src, ${dst:trunc32}|${dst:trunc32}, $src}", - [(set R8:$dst, (trunc R32:$src))]>; +def TRUNC_R32_R8 : I<0x88, MRMDestReg, (ops R8:$dst, R32_:$src), + "mov{b} {${src:trunc8}, $dst|$dst, ${src:trunc8}", []>; +def TRUNC_R16_R8 : I<0x88, MRMDestReg, (ops R8:$dst, R16_:$src), + "mov{b} {${src:trunc8}, $dst|$dst, ${src:trunc8}}", []>; def TRUNC_R32_R16 : I<0x89, MRMDestReg, (ops R16:$dst, R32:$src), - "mov{l} {$src, ${dst:trunc32}|${dst:trunc32}, $src}", + "mov{w} {${src:trunc16}, $dst|$dst, ${src:trunc16}}", [(set R16:$dst, (trunc R32:$src))]>; -def TRUNC_R16_R8 : I<0x89, MRMDestReg, (ops R8:$dst, R16:$src), - "mov{w} {$src, ${dst:trunc16}|${dst:trunc16}, $src}", - [(set R8:$dst, (trunc R16:$src))]>; //===----------------------------------------------------------------------===// // Control Flow Instructions... @@ -2310,6 +2308,26 @@ "xor{l} $dst, $dst", [(set R32:$dst, 0)]>; +// Basic operations on R16 / R32 subclasses R16_ and R32_ which contains only +// those registers that have R8 sub-registers (i.e. AX - DX, EAX - EDX). +def MOV16to16_ : I<0x89, MRMDestReg, (ops R16_:$dst, R16:$src), + "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; +def MOV32to32_ : I<0x89, MRMDestReg, (ops R32_:$dst, R32:$src), + "mov{l} {$src, $dst|$dst, $src}", []>; + +def MOV16_rr : I<0x89, MRMDestReg, (ops R16_:$dst, R16_:$src), + "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; +def MOV32_rr : I<0x89, MRMDestReg, (ops R32_:$dst, R32_:$src), + "mov{l} {$src, $dst|$dst, $src}", []>; +def MOV16_rm : I<0x8B, MRMSrcMem, (ops R16_:$dst, i16mem:$src), + "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; +def MOV32_rm : I<0x8B, MRMSrcMem, (ops R32_:$dst, i32mem:$src), + "mov{l} {$src, $dst|$dst, $src}", []>; +def MOV16_mr : I<0x89, MRMDestMem, (ops i16mem:$dst, R16_:$src), + "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; +def MOV32_mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32_:$src), + "mov{l} {$src, $dst|$dst, $src}", []>; + //===----------------------------------------------------------------------===// // DWARF Pseudo Instructions // Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.43 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.44 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.43 Sat May 6 16:27:14 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Mon May 8 03:01:26 2006 @@ -89,7 +89,7 @@ unsigned Reg = MO.getReg(); if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) { MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0) - ? MVT::i16 : MVT::i32; + ? MVT::i16 : MVT::i8; Reg = getX86SubSuperRegister(Reg, VT); } O << RI.get(Reg).Name; @@ -268,12 +268,13 @@ const MachineOperand &MO1 = MI->getOperand(1); unsigned Reg0 = MO0.getReg(); unsigned Reg1 = MO1.getReg(); - if (MI->getOpcode() == X86::TRUNC_R16_R8) - Reg0 = getX86SubSuperRegister(Reg0, MVT::i16); + if (MI->getOpcode() == X86::TRUNC_R32_R16) + Reg1 = getX86SubSuperRegister(Reg1, MVT::i16); else - Reg0 = getX86SubSuperRegister(Reg0, MVT::i32); - if (Reg0 == Reg1) - O << CommentString << " TRUNCATE "; + Reg1 = getX86SubSuperRegister(Reg1, MVT::i8); + O << CommentString << " TRUNCATE "; + if (Reg0 != Reg1) + O << "\n\t"; break; } } Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.150 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.151 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.150 Fri May 5 00:40:20 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Mon May 8 03:01:26 2006 @@ -52,10 +52,14 @@ unsigned Opc; if (RC == &X86::R32RegClass) { Opc = X86::MOV32mr; - } else if (RC == &X86::R8RegClass) { - Opc = X86::MOV8mr; } else if (RC == &X86::R16RegClass) { Opc = X86::MOV16mr; + } else if (RC == &X86::R8RegClass) { + Opc = X86::MOV8mr; + } else if (RC == &X86::R32_RegClass) { + Opc = X86::MOV32_mr; + } else if (RC == &X86::R16_RegClass) { + Opc = X86::MOV16_mr; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FpST64m; } else if (RC == &X86::FR32RegClass) { @@ -78,10 +82,14 @@ unsigned Opc; if (RC == &X86::R32RegClass) { Opc = X86::MOV32rm; - } else if (RC == &X86::R8RegClass) { - Opc = X86::MOV8rm; } else if (RC == &X86::R16RegClass) { Opc = X86::MOV16rm; + } else if (RC == &X86::R8RegClass) { + Opc = X86::MOV8rm; + } else if (RC == &X86::R32_RegClass) { + Opc = X86::MOV32_rm; + } else if (RC == &X86::R16_RegClass) { + Opc = X86::MOV16_rm; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FpLD64m; } else if (RC == &X86::FR32RegClass) { @@ -104,10 +112,14 @@ unsigned Opc; if (RC == &X86::R32RegClass) { Opc = X86::MOV32rr; - } else if (RC == &X86::R8RegClass) { - Opc = X86::MOV8rr; } else if (RC == &X86::R16RegClass) { Opc = X86::MOV16rr; + } else if (RC == &X86::R8RegClass) { + Opc = X86::MOV8rr; + } else if (RC == &X86::R32_RegClass) { + Opc = X86::MOV32_rr; + } else if (RC == &X86::R16_RegClass) { + Opc = X86::MOV16_rr; } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) { Opc = X86::FpMOV; } else if (RC == &X86::FR32RegClass) { Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.33 llvm/lib/Target/X86/X86RegisterInfo.td:1.34 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.33 Sun May 7 05:10:20 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.td Mon May 8 03:01:26 2006 @@ -136,6 +136,10 @@ }]; } +// R16, R32 subclasses which contain registers that have R8 sub-registers. +def R16_ : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]>; +def R32_ : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]>; + // Scalar SSE2 floating point registers. def FR32 : RegisterClass<"X86", [f32], 32, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; From natebegeman at mac.com Mon May 8 11:51:49 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 May 2006 11:51:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605081651.LAA29780@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.236 -> 1.237 --- Log message: Make emission of jump tables a bit less conservative; they are now required to be only 31.25% dense, rather than 75% dense. --- Diffs of the changes: (+4 -4) SelectionDAGISel.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.236 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.237 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.236 Sat May 6 04:10:37 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon May 8 11:51:36 2006 @@ -880,9 +880,9 @@ const BasicBlock *LLVMBB = CurMBB->getBasicBlock(); Reloc::Model Relocs = TLI.getTargetMachine().getRelocationModel(); - // If the switch has more than 5 blocks, and at least 75% dense, then emit a - // jump table rather than lowering the switch to a binary tree of conditional - // branches. + // If the switch has more than 5 blocks, and at least 31.25% dense, and the + // target supports indirect branches, then emit a jump table rather than + // lowering the switch to a binary tree of conditional branches. // FIXME: Make this work with PIC code if (TLI.isOperationLegal(ISD::BRIND, TLI.getPointerTy()) && (Relocs == Reloc::Static || Relocs == Reloc::DynamicNoPIC) && @@ -891,7 +891,7 @@ uint64_t Last = cast(Cases.back().first)->getRawValue(); double Density = (double)Cases.size() / (double)((Last - First) + 1ULL); - if (Density >= 0.75) { + if (Density >= 0.3125) { // Create a new basic block to hold the code for loading the address // of the jump table, and jumping to it. Update successor information; // we will either branch to the default case for the switch, or the jump From lattner at cs.uiuc.edu Mon May 8 12:23:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 12:23:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200605081723.MAA30048@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.60 -> 1.61 --- Log message: When tracking demanded bits, if any bits from the sext of an SRA are demanded, then so is the input sign bit. This fixes mediabench/g721 on X86. --- Diffs of the changes: (+8 -2) TargetLowering.cpp | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.60 llvm/lib/Target/TargetLowering.cpp:1.61 --- llvm/lib/Target/TargetLowering.cpp:1.60 Sat May 6 18:48:13 2006 +++ llvm/lib/Target/TargetLowering.cpp Mon May 8 12:22:53 2006 @@ -467,8 +467,14 @@ HighBits <<= MVT::getSizeInBits(VT) - ShAmt; uint64_t TypeMask = MVT::getIntVTBitMask(VT); - if (SimplifyDemandedBits(Op.getOperand(0), - (DemandedMask << ShAmt) & TypeMask, + uint64_t InDemandedMask = (DemandedMask << ShAmt) & TypeMask; + + // If any of the demanded bits are produced by the sign extension, we also + // demand the input sign bit. + if (HighBits & DemandedMask) + InDemandedMask |= MVT::getIntVTSignBit(VT); + + if (SimplifyDemandedBits(Op.getOperand(0), InDemandedMask, KnownZero, KnownOne, TLO, Depth+1)) return true; assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); From lattner at cs.uiuc.edu Mon May 8 12:30:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 12:30:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200605081730.MAA30169@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.304 -> 1.305 --- Log message: Fold shifts with undef operands. --- Diffs of the changes: (+7 -0) SelectionDAG.cpp | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.304 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.305 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.304 Sat May 6 18:05:41 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon May 8 12:29:49 2006 @@ -1439,11 +1439,14 @@ case ISD::FSUB: case ISD::FDIV: case ISD::FREM: + case ISD::SRA: return N1; // fold op(undef, arg2) -> undef case ISD::UDIV: case ISD::SDIV: case ISD::UREM: case ISD::SREM: + case ISD::SRL: + case ISD::SHL: return getConstant(0, VT); // fold op(undef, arg2) -> 0 } } @@ -1467,9 +1470,13 @@ return N2; // fold op(arg1, undef) -> undef case ISD::MUL: case ISD::AND: + case ISD::SRL: + case ISD::SHL: return getConstant(0, VT); // fold op(arg1, undef) -> 0 case ISD::OR: return getConstant(MVT::getIntVTBitMask(VT), VT); + case ISD::SRA: + return N1; } } From natebegeman at mac.com Mon May 8 12:38:44 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 May 2006 12:38:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp README.txt Message-ID: <200605081738.MAA30372@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.182 -> 1.183 README.txt updated: 1.87 -> 1.88 --- Log message: Fold more shifts into inserts, and update the README --- Diffs of the changes: (+34 -20) PPCISelDAGToDAG.cpp | 39 +++++++++++++++++++++++---------------- README.txt | 15 +++++++++++---- 2 files changed, 34 insertions(+), 20 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.182 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.183 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.182 Sun May 7 21:52:37 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon May 8 12:38:32 2006 @@ -392,25 +392,25 @@ /// SelectBitfieldInsert - turn an or of two masked values into /// the rotate left word immediate then mask insert (rlwimi) instruction. SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { - unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, SH = 0; - unsigned Value; - SDOperand Op0 = N->getOperand(0); SDOperand Op1 = N->getOperand(1); - unsigned Op0Opc = Op0.getOpcode(); - unsigned Op1Opc = Op1.getOpcode(); - uint64_t LKZ, LKO, RKZ, RKO; - TLI.ComputeMaskedBits(Op0, TgtMask, LKZ, LKO); - TLI.ComputeMaskedBits(Op1, TgtMask, RKZ, RKO); + TLI.ComputeMaskedBits(Op0, 0xFFFFFFFFULL, LKZ, LKO); + TLI.ComputeMaskedBits(Op1, 0xFFFFFFFFULL, RKZ, RKO); - if ((LKZ | RKZ) == 0x00000000FFFFFFFFULL) { - unsigned PInsMask = ~RKZ; - unsigned PTgtMask = ~LKZ; + unsigned TargetMask = LKZ; + unsigned InsertMask = RKZ; + + if ((TargetMask | InsertMask) == 0xFFFFFFFF) { + unsigned Op0Opc = Op0.getOpcode(); + unsigned Op1Opc = Op1.getOpcode(); + unsigned Value, SH = 0; + TargetMask = ~TargetMask; + InsertMask = ~InsertMask; - // If the LHS has a foldable shift, then swap it to the RHS so that we can - // fold the shift into the insert. + // If the LHS has a foldable shift and the RHS does not, then swap it to the + // RHS so that we can fold the shift into the insert. if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) { if (Op0.getOperand(0).getOpcode() == ISD::SHL || Op0.getOperand(0).getOpcode() == ISD::SRL) { @@ -418,15 +418,22 @@ Op1.getOperand(0).getOpcode() != ISD::SRL) { std::swap(Op0, Op1); std::swap(Op0Opc, Op1Opc); - std::swap(PInsMask, PTgtMask); + std::swap(TargetMask, InsertMask); } } + } else if (Op0Opc == ISD::SHL || Op0Opc == ISD::SRL) { + if (Op1Opc == ISD::AND && Op1.getOperand(0).getOpcode() != ISD::SHL && + Op1.getOperand(0).getOpcode() != ISD::SRL) { + std::swap(Op0, Op1); + std::swap(Op0Opc, Op1Opc); + std::swap(TargetMask, InsertMask); + } } unsigned MB, ME; - if (isRunOfOnes(PInsMask, MB, ME)) { + if (isRunOfOnes(InsertMask, MB, ME)) { SDOperand Tmp1, Tmp2, Tmp3; - bool DisjointMask = (PTgtMask ^ PInsMask) == 0xFFFFFFFF; + bool DisjointMask = (TargetMask ^ InsertMask) == 0xFFFFFFFF; if ((Op1Opc == ISD::SHL || Op1Opc == ISD::SRL) && isIntImmediate(Op1.getOperand(1), Value)) { Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.87 llvm/lib/Target/PowerPC/README.txt:1.88 --- llvm/lib/Target/PowerPC/README.txt:1.87 Sun May 7 21:52:38 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon May 8 12:38:32 2006 @@ -516,10 +516,17 @@ srwi r4, r2, 30 srwi r5, r2, 31 or r4, r4, r5 - slwi r4, r4, 31 - rlwimi r4, r2, 0, 1, 31 - stw r4, 0(r3) + rlwimi r2, r4, 31, 0, 0 + stw r2, 0(r3) blr -I *think* that could use another rlwimi. +What this code is really doing is ORing bit 0 with bit 1. We could codegen this +as: +_foo: + lwz r2, 0(r3) + slwi r4, r2, 1 + rlwinm r4, r4, 0, 0, 0 + or r2, r2, r4 + stw r2, 0(r3) + blr From natebegeman at mac.com Mon May 8 14:09:36 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 May 2006 14:09:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200605081909.OAA31257@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.88 -> 1.89 --- Log message: Proving once again that I am not as smart as the compiler --- Diffs of the changes: (+1 -2) README.txt | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.88 llvm/lib/Target/PowerPC/README.txt:1.89 --- llvm/lib/Target/PowerPC/README.txt:1.88 Mon May 8 12:38:32 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon May 8 14:09:24 2006 @@ -525,8 +525,7 @@ _foo: lwz r2, 0(r3) - slwi r4, r2, 1 - rlwinm r4, r4, 0, 0, 0 + rlwinm r4, r2, 1, 0, 0 or r2, r2, r4 stw r2, 0(r3) blr From natebegeman at mac.com Mon May 8 15:08:41 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 May 2006 15:08:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200605082008.PAA31438@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.89 -> 1.90 --- Log message: New note about something bad happening in target independent optimizers --- Diffs of the changes: (+18 -2) README.txt | 20 ++++++++++++++++++-- 1 files changed, 18 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.89 llvm/lib/Target/PowerPC/README.txt:1.90 --- llvm/lib/Target/PowerPC/README.txt:1.89 Mon May 8 14:09:24 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon May 8 15:08:28 2006 @@ -492,8 +492,6 @@ ===-------------------------------------------------------------------------=== -Another missed rlwimi case: - void %foo(uint *%tmp) { %tmp = load uint* %tmp ; [#uses=3] %tmp1 = shr uint %tmp, ubyte 31 ; [#uses=1] @@ -529,3 +527,21 @@ or r2, r2, r4 stw r2, 0(r3) blr + +===-------------------------------------------------------------------------=== + +Distilled from the code above, something wacky is going in the optimizers before +code generation time... + +unsigned foo(unsigned x) { + return (unsigned)((unsigned char)(x >> 30) | (unsigned char)(x >> 31)) << 31; +} + +unsigned bar(unsigned x) { + return ((x >> 30) | (x >> 31)) << 31; +} + +generate different code when -O is passed to llvm-gcc. However, when no +optimization is specified and the output is passed into opt with just -mem2reg +and -instcombine, the good code comes out of both. Something is happening before +instcombine to confuse it, and not delete the no-op casts. From lattner at cs.uiuc.edu Mon May 8 15:52:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 15:52:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605082052.PAA31904@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.163 -> 1.164 --- Log message: Compile this: short test4(unsigned X) { return (X >> 16); } to: _test4: movl 4(%esp), %eax sarl $16, %eax ret instead of: _test4: movl $-65536, %eax andl 4(%esp), %eax sarl $16, %eax ret --- Diffs of the changes: (+5 -0) DAGCombiner.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.163 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.164 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.163 Sun May 7 20:35:01 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon May 8 15:51:54 2006 @@ -1575,6 +1575,11 @@ } } + // Simplify, based on bits shifted out of the LHS. + if (N1C && SimplifyDemandedBits(SDOperand(N, 0))) + return SDOperand(N, 0); + + // If the sign bit is known to be zero, switch this to a SRL. if (TLI.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT))) return DAG.getNode(ISD::SRL, VT, N0, N1); From natebegeman at mac.com Mon May 8 15:54:15 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 8 May 2006 15:54:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200605082054.PAA31924@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.90 -> 1.91 --- Log message: Yet more readme updating --- Diffs of the changes: (+22 -36) README.txt | 58 ++++++++++++++++++++++------------------------------------ 1 files changed, 22 insertions(+), 36 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.90 llvm/lib/Target/PowerPC/README.txt:1.91 --- llvm/lib/Target/PowerPC/README.txt:1.90 Mon May 8 15:08:28 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon May 8 15:54:02 2006 @@ -492,18 +492,23 @@ ===-------------------------------------------------------------------------=== -void %foo(uint *%tmp) { - %tmp = load uint* %tmp ; [#uses=3] - %tmp1 = shr uint %tmp, ubyte 31 ; [#uses=1] - %tmp1 = cast uint %tmp1 to ubyte ; [#uses=1] - %tmp4.mask = shr uint %tmp, ubyte 30 ; [#uses=1] - %tmp4.mask = cast uint %tmp4.mask to ubyte ; [#uses=1] - %tmp = or ubyte %tmp4.mask, %tmp1 ; [#uses=1] - %tmp10 = cast ubyte %tmp to uint ; [#uses=1] - %tmp11 = shl uint %tmp10, ubyte 31 ; [#uses=1] - %tmp12 = and uint %tmp, 2147483647 ; [#uses=1] - %tmp13 = or uint %tmp11, %tmp12 ; [#uses=1] - store uint %tmp13, uint* %tmp +%struct.B = type { ubyte, [3 x ubyte] } + +void %foo(%struct.B* %b) { +entry: + %tmp = cast %struct.B* %b to uint* ; [#uses=1] + %tmp = load uint* %tmp ; [#uses=1] + %tmp3 = cast %struct.B* %b to uint* ; [#uses=1] + %tmp4 = load uint* %tmp3 ; [#uses=1] + %tmp8 = cast %struct.B* %b to uint* ; [#uses=2] + %tmp9 = load uint* %tmp8 ; [#uses=1] + %tmp4.mask17 = shl uint %tmp4, ubyte 1 ; [#uses=1] + %tmp1415 = and uint %tmp4.mask17, 2147483648 ; [#uses=1] + %tmp.masked = and uint %tmp, 2147483648 ; [#uses=1] + %tmp11 = or uint %tmp1415, %tmp.masked ; [#uses=1] + %tmp12 = and uint %tmp9, 2147483647 ; [#uses=1] + %tmp13 = or uint %tmp12, %tmp11 ; [#uses=1] + store uint %tmp13, uint* %tmp8 ret void } @@ -511,15 +516,14 @@ _foo: lwz r2, 0(r3) - srwi r4, r2, 30 - srwi r5, r2, 31 - or r4, r4, r5 - rlwimi r2, r4, 31, 0, 0 + slwi r4, r2, 1 + or r4, r4, r2 + rlwimi r2, r4, 0, 0, 0 stw r2, 0(r3) blr -What this code is really doing is ORing bit 0 with bit 1. We could codegen this -as: +We could collapse a bunch of those ORs and ANDs and generate the following +equivalent code: _foo: lwz r2, 0(r3) @@ -527,21 +531,3 @@ or r2, r2, r4 stw r2, 0(r3) blr - -===-------------------------------------------------------------------------=== - -Distilled from the code above, something wacky is going in the optimizers before -code generation time... - -unsigned foo(unsigned x) { - return (unsigned)((unsigned char)(x >> 30) | (unsigned char)(x >> 31)) << 31; -} - -unsigned bar(unsigned x) { - return ((x >> 30) | (x >> 31)) << 31; -} - -generate different code when -O is passed to llvm-gcc. However, when no -optimization is specified and the output is passed into opt with just -mem2reg -and -instcombine, the good code comes out of both. Something is happening before -instcombine to confuse it, and not delete the no-op casts. From lattner at cs.uiuc.edu Mon May 8 15:59:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 15:59:11 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/and_sext.ll Message-ID: <200605082059.PAA32131@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: and_sext.ll updated: 1.2 -> 1.3 --- Log message: new testcase --- Diffs of the changes: (+6 -0) and_sext.ll | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/and_sext.ll diff -u llvm/test/Regression/CodeGen/PowerPC/and_sext.ll:1.2 llvm/test/Regression/CodeGen/PowerPC/and_sext.ll:1.3 --- llvm/test/Regression/CodeGen/PowerPC/and_sext.ll:1.2 Sat May 6 13:15:50 2006 +++ llvm/test/Regression/CodeGen/PowerPC/and_sext.ll Mon May 8 15:58:58 2006 @@ -21,3 +21,9 @@ ret short %retval } +short %test3(uint %X) { + %tmp1 = shr uint %X, ubyte 16 + %tmp1 = cast uint %tmp1 to short + ret short %tmp1 +} + From lattner at cs.uiuc.edu Mon May 8 15:59:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 15:59:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605082059.PAA32142@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.164 -> 1.165 --- Log message: Implement and_sext.ll:test3, generating: _test4: srawi r3, r3, 16 blr instead of: _test4: srwi r2, r3, 16 extsh r3, r2 blr for: short test4(unsigned X) { return (X >> 16); } --- Diffs of the changes: (+8 -1) DAGCombiner.cpp | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.164 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.165 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.164 Mon May 8 15:51:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon May 8 15:59:41 2006 @@ -1936,7 +1936,7 @@ unsigned EVTBits = MVT::getSizeInBits(EVT); // fold (sext_in_reg c1) -> c1 - if (isa(N0)) + if (isa(N0) || N0.getOpcode() == ISD::UNDEF) return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0, N1); // If the input is already sign extended, just drop the extension. @@ -1949,6 +1949,13 @@ return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1); } + // fold (sext_in_reg (srl X, 24), i8) -> sra X, 24 + if (N0.getOpcode() == ISD::SRL) { + if (ConstantSDNode *ShAmt = dyn_cast(N0.getOperand(1))) + if (ShAmt->getValue()+EVTBits == MVT::getSizeInBits(VT)) + return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1)); + } + // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1))) return DAG.getZeroExtendInReg(N0, EVT); From lattner at cs.uiuc.edu Mon May 8 16:19:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 16:19:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605082119.QAA32618@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.165 -> 1.166 --- Log message: Make the case I just checked in stronger. Now we compile this: short test2(short X, short x) { int Y = (short)(X+x); return Y >> 1; } to: _test2: add r2, r3, r4 extsh r2, r2 srawi r3, r2, 1 blr instead of: _test2: add r2, r3, r4 extsh r2, r2 srwi r2, r2, 1 extsh r3, r2 blr --- Diffs of the changes: (+13 -5) DAGCombiner.cpp | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.165 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.166 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.165 Mon May 8 15:59:41 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon May 8 16:18:59 2006 @@ -1948,17 +1948,25 @@ EVT < cast(N0.getOperand(1))->getVT()) { return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1); } + + // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero + if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1))) + return DAG.getZeroExtendInReg(N0, EVT); // fold (sext_in_reg (srl X, 24), i8) -> sra X, 24 + // fold (sext_in_reg (srl X, 23), i8) -> sra X, 23 iff possible. + // We already fold "(sext_in_reg (srl X, 25), i8) -> srl X, 25" above. if (N0.getOpcode() == ISD::SRL) { if (ConstantSDNode *ShAmt = dyn_cast(N0.getOperand(1))) - if (ShAmt->getValue()+EVTBits == MVT::getSizeInBits(VT)) - return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1)); + if (ShAmt->getValue()+EVTBits <= MVT::getSizeInBits(VT)) { + // We can turn this into an SRA iff the input to the SRL is already sign + // extended enough. + unsigned InSignBits = TLI.ComputeNumSignBits(N0.getOperand(0)); + if (MVT::getSizeInBits(VT)-(ShAmt->getValue()+EVTBits) < InSignBits) + return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1)); + } } - // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero - if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1))) - return DAG.getZeroExtendInReg(N0, EVT); // fold (sext_inreg (extload x)) -> (sextload x) if (N0.getOpcode() == ISD::EXTLOAD && EVT == cast(N0.getOperand(3))->getVT() && From lattner at cs.uiuc.edu Mon May 8 16:24:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 16:24:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200605082124.QAA32687@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.101 -> 1.102 --- Log message: add a note --- Diffs of the changes: (+9 -0) README.txt | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.101 llvm/lib/Target/X86/README.txt:1.102 --- llvm/lib/Target/X86/README.txt:1.101 Tue May 2 17:43:31 2006 +++ llvm/lib/Target/X86/README.txt Mon May 8 16:24:21 2006 @@ -1166,4 +1166,13 @@ The 2) marked instructions are the lowered form of the 1,undef,3,4 shufflevector. It seems that there should be a better way to do it :) +//===---------------------------------------------------------------------===// + +If shorter, we should use things like: +movzwl %ax, %eax +instead of: +andl $65535, %EAX + +The former can also be used when the two-addressy nature of the 'and' would +require a copy to be inserted (in X86InstrInfo::convertToThreeAddress). From lattner at cs.uiuc.edu Mon May 8 16:39:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 16:39:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200605082139.QAA00455@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.102 -> 1.103 --- Log message: Another bad case I noticed --- Diffs of the changes: (+37 -0) README.txt | 37 +++++++++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.102 llvm/lib/Target/X86/README.txt:1.103 --- llvm/lib/Target/X86/README.txt:1.102 Mon May 8 16:24:21 2006 +++ llvm/lib/Target/X86/README.txt Mon May 8 16:39:45 2006 @@ -1176,3 +1176,40 @@ The former can also be used when the two-addressy nature of the 'and' would require a copy to be inserted (in X86InstrInfo::convertToThreeAddress). +//===---------------------------------------------------------------------===// + +This code generates ugly code, probably due to costs being off or something: + +void %test(float* %P, <4 x float>* %P2 ) { + %xFloat0.688 = load float* %P + %loadVector37.712 = load <4 x float>* %P2 + %inFloat3.713 = insertelement <4 x float> %loadVector37.712, float 0.000000e+00, uint 3 + store <4 x float> %inFloat3.713, <4 x float>* %P2 + ret void +} + +Generates: + +_test: + pxor %xmm0, %xmm0 + movd %xmm0, %eax ;; EAX = 0! + movl 8(%esp), %ecx + movaps (%ecx), %xmm0 + pinsrw $6, %eax, %xmm0 + shrl $16, %eax ;; EAX = 0 again! + pinsrw $7, %eax, %xmm0 + movaps %xmm0, (%ecx) + ret + +It would be better to generate: + +_test: + movl 8(%esp), %ecx + movaps (%ecx), %xmm0 + xor %eax, %eax + pinsrw $6, %eax, %xmm0 + pinsrw $7, %eax, %xmm0 + movaps %xmm0, (%ecx) + ret + +or use pxor (to make a zero vector) and shuffle (to insert it). From lattner at cs.uiuc.edu Mon May 8 17:00:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 17:00:39 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Message-ID: <200605082200.RAA00885@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ExecutionEngine: ExecutionEngine.h updated: 1.37 -> 1.38 --- Log message: Move methods out of line so that MutexGuard.h isn't required in the header. --- Diffs of the changes: (+18 -48) ExecutionEngine.h | 66 ++++++++++++++---------------------------------------- 1 files changed, 18 insertions(+), 48 deletions(-) Index: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h diff -u llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.37 llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.38 --- llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.37 Tue May 2 20:29:56 2006 +++ llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Mon May 8 17:00:26 2006 @@ -19,7 +19,7 @@ #include #include #include -#include "llvm/Support/MutexGuard.h" +#include "llvm/System/Mutex.h" namespace llvm { @@ -32,6 +32,7 @@ class ModuleProvider; class TargetData; class Type; +class MutexGuard; class ExecutionEngineState { private: @@ -114,58 +115,27 @@ const char * const * envp); - void addGlobalMapping(const GlobalValue *GV, void *Addr) { - MutexGuard locked(lock); - - void *&CurVal = state.getGlobalAddressMap(locked)[GV]; - assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); - CurVal = Addr; - - // If we are using the reverse mapping, add it too - if (!state.getGlobalAddressReverseMap(locked).empty()) { - const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; - assert((V == 0 || GV == 0) && "GlobalMapping already established!"); - V = GV; - } - } - + /// addGlobalMapping - Tell the execution engine that the specified global is + /// at the specified location. This is used internally as functions are JIT'd + /// and as global variables are laid out in memory. It can and should also be + /// used by clients of the EE that want to have an LLVM global overlay + /// existing data in memory. + void addGlobalMapping(const GlobalValue *GV, void *Addr); + /// clearAllGlobalMappings - Clear all global mappings and start over again /// use in dynamic compilation scenarios when you want to move globals - void clearAllGlobalMappings() { - MutexGuard locked(lock); - - state.getGlobalAddressMap(locked).clear(); - state.getGlobalAddressReverseMap(locked).clear(); - } - + void clearAllGlobalMappings(); + /// updateGlobalMapping - Replace an existing mapping for GV with a new - /// address. This updates both maps as required. - void updateGlobalMapping(const GlobalValue *GV, void *Addr) { - MutexGuard locked(lock); - - void *&CurVal = state.getGlobalAddressMap(locked)[GV]; - if (CurVal && !state.getGlobalAddressReverseMap(locked).empty()) - state.getGlobalAddressReverseMap(locked).erase(CurVal); - CurVal = Addr; - - // If we are using the reverse mapping, add it too - if (!state.getGlobalAddressReverseMap(locked).empty()) { - const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; - assert((V == 0 || GV == 0) && "GlobalMapping already established!"); - V = GV; - } - } - + /// address. This updates both maps as required. If "Addr" is null, the + /// entry for the global is removed from the mappings. + void updateGlobalMapping(const GlobalValue *GV, void *Addr); + /// getPointerToGlobalIfAvailable - This returns the address of the specified - /// global value if it is available, otherwise it returns null. + /// global value if it is has already been codegen'd, otherwise it returns + /// null. /// - void *getPointerToGlobalIfAvailable(const GlobalValue *GV) { - MutexGuard locked(lock); - - std::map::iterator I = - state.getGlobalAddressMap(locked).find(GV); - return I != state.getGlobalAddressMap(locked).end() ? I->second : 0; - } + void *getPointerToGlobalIfAvailable(const GlobalValue *GV); /// getPointerToGlobal - This returns the address of the specified global /// value. This may involve code generation if it's a function. From lattner at cs.uiuc.edu Mon May 8 17:01:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 17:01:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JIT.cpp JITEmitter.cpp Message-ID: <200605082201.RAA00970@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JIT.cpp updated: 1.64 -> 1.65 JITEmitter.cpp updated: 1.96 -> 1.97 --- Log message: Move some methods out of line so that MutexGuard.h isn't needed in a public header. --- Diffs of the changes: (+10 -6) JIT.cpp | 6 +----- JITEmitter.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 6 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/JIT.cpp diff -u llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.64 llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.65 --- llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.64 Thu May 4 16:18:40 2006 +++ llvm/lib/ExecutionEngine/JIT/JIT.cpp Mon May 8 17:00:52 2006 @@ -22,6 +22,7 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/System/DynamicLibrary.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetJITInfo.h" @@ -349,8 +350,3 @@ return Addr; } -/// freeMachineCodeForFunction - release machine code memory for given Function -/// -void JIT::freeMachineCodeForFunction(Function *F) { - // currently a no-op -} Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.96 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.97 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.96 Wed May 3 13:55:56 2006 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Mon May 8 17:00:52 2006 @@ -26,6 +26,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetJITInfo.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/ADT/Statistic.h" #include "llvm/System/Memory.h" #include @@ -336,7 +337,14 @@ return getJITResolver(MCE).getFunctionStub(F); } - +/// freeMachineCodeForFunction - release machine code memory for given Function. +/// +void JIT::freeMachineCodeForFunction(Function *F) { + // Delete translation for this from the ExecutionEngine, so it will get + // retranslated next time it is used. + updateGlobalMapping(F, 0); + +} //===----------------------------------------------------------------------===// // JITEmitter code. From lattner at cs.uiuc.edu Mon May 8 17:01:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 17:01:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200605082201.RAA00964@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.81 -> 1.82 --- Log message: Move some methods out of line so that MutexGuard.h isn't needed in a public header. --- Diffs of the changes: (+73 -3) ExecutionEngine.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 73 insertions(+), 3 deletions(-) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.81 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.82 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.81 Tue May 2 20:29:56 2006 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Mon May 8 17:00:52 2006 @@ -21,6 +21,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/System/DynamicLibrary.h" #include "llvm/Target/TargetData.h" #include @@ -47,6 +48,73 @@ delete MP; } +/// addGlobalMapping - Tell the execution engine that the specified global is +/// at the specified location. This is used internally as functions are JIT'd +/// and as global variables are laid out in memory. It can and should also be +/// used by clients of the EE that want to have an LLVM global overlay +/// existing data in memory. +void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) { + MutexGuard locked(lock); + + void *&CurVal = state.getGlobalAddressMap(locked)[GV]; + assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); + CurVal = Addr; + + // If we are using the reverse mapping, add it too + if (!state.getGlobalAddressReverseMap(locked).empty()) { + const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; + assert((V == 0 || GV == 0) && "GlobalMapping already established!"); + V = GV; + } +} + +/// clearAllGlobalMappings - Clear all global mappings and start over again +/// use in dynamic compilation scenarios when you want to move globals +void ExecutionEngine::clearAllGlobalMappings() { + MutexGuard locked(lock); + + state.getGlobalAddressMap(locked).clear(); + state.getGlobalAddressReverseMap(locked).clear(); +} + +/// updateGlobalMapping - Replace an existing mapping for GV with a new +/// address. This updates both maps as required. If "Addr" is null, the +/// entry for the global is removed from the mappings. +void ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) { + MutexGuard locked(lock); + + // Deleting from the mapping? + if (Addr == 0) { + state.getGlobalAddressMap(locked).erase(GV); + if (!state.getGlobalAddressReverseMap(locked).empty()) + state.getGlobalAddressReverseMap(locked).erase(Addr); + return; + } + + void *&CurVal = state.getGlobalAddressMap(locked)[GV]; + if (CurVal && !state.getGlobalAddressReverseMap(locked).empty()) + state.getGlobalAddressReverseMap(locked).erase(CurVal); + CurVal = Addr; + + // If we are using the reverse mapping, add it too + if (!state.getGlobalAddressReverseMap(locked).empty()) { + const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; + assert((V == 0 || GV == 0) && "GlobalMapping already established!"); + V = GV; + } +} + +/// getPointerToGlobalIfAvailable - This returns the address of the specified +/// global value if it is has already been codegen'd, otherwise it returns null. +/// +void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) { + MutexGuard locked(lock); + + std::map::iterator I = + state.getGlobalAddressMap(locked).find(GV); + return I != state.getGlobalAddressMap(locked).end() ? I->second : 0; +} + /// getGlobalValueAtAddress - Return the LLVM global value object that starts /// at the specified address. /// @@ -55,9 +123,11 @@ // If we haven't computed the reverse mapping yet, do so first. if (state.getGlobalAddressReverseMap(locked).empty()) { - for (std::map::iterator I = - state.getGlobalAddressMap(locked).begin(), E = state.getGlobalAddressMap(locked).end(); I != E; ++I) - state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second, I->first)); + for (std::map::iterator + I = state.getGlobalAddressMap(locked).begin(), + E = state.getGlobalAddressMap(locked).end(); I != E; ++I) + state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second, + I->first)); } std::map::iterator I = From reid at x10sys.com Mon May 8 19:31:14 2006 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 May 2006 19:31:14 -0500 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200605090031.TAA01776@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.223 -> 1.224 --- Log message: Use the -dumpversion option to llvm-gcc which gives us just the version # and is unlikely to change in future releases. This also simplifies the parsing of the full and major llvm-gcc version numbers in the script. --- Diffs of the changes: (+1 -1) configure.ac | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.223 llvm/autoconf/configure.ac:1.224 --- llvm/autoconf/configure.ac:1.223 Thu Apr 27 02:49:24 2006 +++ llvm/autoconf/configure.ac Mon May 8 19:31:01 2006 @@ -619,7 +619,7 @@ AC_SUBST(LLVMCC1PLUS,$llvmcc1pluspath) llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'` AC_SUBST(LLVMGCCDIR,$llvmgccdir) - llvmgccversion=[`"$LLVMGCC" -v 2>&1 | grep '^gcc version' | sed 's/^gcc version \([0-9.]*\).*/\1/'`] + llvmgccversion=[`"$LLVMGCC" -dumpversion 2>&1 | sed 's/^\([0-9.]*\).*/\1/'`] llvmgccmajvers=[`echo $llvmgccversion | sed 's/^\([0-9]\).*/\1/'`] AC_SUBST(LLVMGCC_VERSION,$llvmgccversion) AC_SUBST(LLVMGCC_MAJVERS,$llvmgccmajvers) From reid at x10sys.com Mon May 8 19:31:14 2006 From: reid at x10sys.com (Reid Spencer) Date: Mon, 8 May 2006 19:31:14 -0500 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200605090031.TAA01778@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.226 -> 1.227 --- Log message: Use the -dumpversion option to llvm-gcc which gives us just the version # and is unlikely to change in future releases. This also simplifies the parsing of the full and major llvm-gcc version numbers in the script. --- Diffs of the changes: (+1 -1) configure | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/configure diff -u llvm/configure:1.226 llvm/configure:1.227 --- llvm/configure:1.226 Thu Apr 27 02:49:18 2006 +++ llvm/configure Mon May 8 19:31:00 2006 @@ -30725,7 +30725,7 @@ llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'` LLVMGCCDIR=$llvmgccdir - llvmgccversion=`"$LLVMGCC" -v 2>&1 | grep '^gcc version' | sed 's/^gcc version \([0-9.]*\).*/\1/'` + llvmgccversion=`"$LLVMGCC" -dumpversion 2>&1 | sed 's/^\([0-9.]*\).*/\1/'` llvmgccmajvers=`echo $llvmgccversion | sed 's/^\([0-9]\).*/\1/'` LLVMGCC_VERSION=$llvmgccversion From lattner at cs.uiuc.edu Mon May 8 23:13:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 23:13:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerAllocations.cpp LowerSelect.cpp LowerSwitch.cpp Mem2Reg.cpp Message-ID: <200605090413.XAA02906@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerAllocations.cpp updated: 1.56 -> 1.57 LowerSelect.cpp updated: 1.4 -> 1.5 LowerSwitch.cpp updated: 1.19 -> 1.20 Mem2Reg.cpp updated: 1.15 -> 1.16 --- Log message: Patch to make some xforms preserve each other. Patch contributed by Domagoj Babic! --- Diffs of the changes: (+28 -2) LowerAllocations.cpp | 7 +++++++ LowerSelect.cpp | 7 ++++++- LowerSwitch.cpp | 11 ++++++++++- Mem2Reg.cpp | 5 +++++ 4 files changed, 28 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/LowerAllocations.cpp diff -u llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.56 llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.57 --- llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.56 Mon May 1 23:24:36 2006 +++ llvm/lib/Transforms/Scalar/LowerAllocations.cpp Mon May 8 23:13:41 2006 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" @@ -39,6 +40,12 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.setPreservesCFG(); + + // This is a cluster of orthogonal Transforms: + AU.addPreserved(); + AU.addPreservedID(PromoteMemoryToRegisterID); + AU.addPreservedID(LowerSelectID); + AU.addPreservedID(LowerSwitchID); } /// doPassInitialization - For the lower allocations pass, this ensures that Index: llvm/lib/Transforms/Scalar/LowerSelect.cpp diff -u llvm/lib/Transforms/Scalar/LowerSelect.cpp:1.4 llvm/lib/Transforms/Scalar/LowerSelect.cpp:1.5 --- llvm/lib/Transforms/Scalar/LowerSelect.cpp:1.4 Mon May 1 23:24:36 2006 +++ llvm/lib/Transforms/Scalar/LowerSelect.cpp Mon May 8 23:13:41 2006 @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" @@ -37,7 +38,11 @@ LowerSelect(bool onlyfp = false) : OnlyFP(onlyfp) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { - // Doesn't really preserve anything. It can certainly destroy the CFG. + // This certainly destroys the CFG. + // This is a cluster of orthogonal Transforms: + AU.addPreserved(); + AU.addPreservedID(PromoteMemoryToRegisterID); + AU.addPreservedID(LowerSwitchID); } bool runOnFunction(Function &F); Index: llvm/lib/Transforms/Scalar/LowerSwitch.cpp diff -u llvm/lib/Transforms/Scalar/LowerSwitch.cpp:1.19 llvm/lib/Transforms/Scalar/LowerSwitch.cpp:1.20 --- llvm/lib/Transforms/Scalar/LowerSwitch.cpp:1.19 Mon May 1 23:24:36 2006 +++ llvm/lib/Transforms/Scalar/LowerSwitch.cpp Mon May 8 23:13:41 2006 @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" @@ -32,7 +33,15 @@ /// modifies the CFG! class LowerSwitch : public FunctionPass { public: - bool runOnFunction(Function &F); + virtual bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + // This is a cluster of orthogonal Transforms + AU.addPreserved(); + AU.addPreservedID(PromoteMemoryToRegisterID); + AU.addPreservedID(LowerSelectID); + } + typedef std::pair Case; typedef std::vector::iterator CaseItr; private: Index: llvm/lib/Transforms/Scalar/Mem2Reg.cpp diff -u llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.15 llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.16 --- llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.15 Mon May 1 23:24:36 2006 +++ llvm/lib/Transforms/Scalar/Mem2Reg.cpp Mon May 8 23:13:41 2006 @@ -14,6 +14,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" +#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Instructions.h" #include "llvm/Function.h" @@ -37,6 +38,10 @@ AU.addRequired(); AU.addRequired(); AU.setPreservesCFG(); + // This is a cluster of orthogonal Transforms + AU.addPreserved(); + AU.addPreservedID(LowerSelectID); + AU.addPreservedID(LowerSwitchID); } }; From lattner at cs.uiuc.edu Mon May 8 23:13:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 23:13:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Message-ID: <200605090413.XAA02910@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: UnifyFunctionExitNodes.cpp updated: 1.33 -> 1.34 --- Log message: Patch to make some xforms preserve each other. Patch contributed by Domagoj Babic! --- Diffs of the changes: (+4 -0) UnifyFunctionExitNodes.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp diff -u llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp:1.33 llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp:1.34 --- llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp:1.33 Thu Apr 21 18:45:34 2005 +++ llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Mon May 8 23:13:41 2006 @@ -32,6 +32,10 @@ void UnifyFunctionExitNodes::getAnalysisUsage(AnalysisUsage &AU) const{ // We preserve the non-critical-edgeness property AU.addPreservedID(BreakCriticalEdgesID); + // This is a cluster of orthogonal Transforms + AU.addPreservedID(PromoteMemoryToRegisterID); + AU.addPreservedID(LowerSelectID); + AU.addPreservedID(LowerSwitchID); } // UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new From lattner at cs.uiuc.edu Mon May 8 23:59:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 23:59:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.td Message-ID: <200605090459.XAA03308@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrInfo.td updated: 1.123 -> 1.124 --- Log message: Some notes and thoughts to myself --- Diffs of the changes: (+7 -7) SparcInstrInfo.td | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) Index: llvm/lib/Target/Sparc/SparcInstrInfo.td diff -u llvm/lib/Target/Sparc/SparcInstrInfo.td:1.123 llvm/lib/Target/Sparc/SparcInstrInfo.td:1.124 --- llvm/lib/Target/Sparc/SparcInstrInfo.td:1.123 Tue Feb 21 12:04:32 2006 +++ llvm/lib/Target/Sparc/SparcInstrInfo.td Mon May 8 23:58:46 2006 @@ -516,24 +516,24 @@ /* //===------------------------- // Sparc Example -defm intinst { +defm intinst{OPC1, OPC2} { def OPC1 : F3_1<2, Opc, asmstr, (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c), [(set IntRegs:$dst, (code IntRegs:$b, IntRegs:$c))]>; def OPC2 : F3_2<2, Opc, asmstr, (ops IntRegs:$dst, IntRegs:$b, i32imm:$c), [(set IntRegs:$dst, (code IntRegs:$b, simm13:$c))]>; } -defm intinst_np { +defm intinst_np{OPC1, OPC2} { def OPC1 : F3_1<2, Opc, asmstr, (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c), []>; def OPC2 : F3_2<2, Opc, asmstr, (ops IntRegs:$dst, IntRegs:$b, i32imm:$c), []>; } -def intinstnp< ADDXrr, ADDXri, 0b001000, "addx $b, $c, $dst">; -def intinst < SUBrr, SUBri, 0b000100, "sub $b, $c, $dst", sub>; -def intinstnp< SUBXrr, SUBXri, 0b001100, "subx $b, $c, $dst">; -def intinst ; -def intinst < SMULrr, SMULri, 0b001011, "smul $b, $c, $dst", mul>; +def { ADDXrr, ADDXri} : intinstnp<0b001000, "addx $b, $c, $dst">; +def { SUBrr, SUBri} : intinst <0b000100, "sub $b, $c, $dst", sub>; +def intinstnp{ SUBXrr, SUBXri}<0b001100, "subx $b, $c, $dst">; +def intinst {SUBCCrr, SUBCCri}<0b010100, "subcc $b, $c, $dst", SPcmpicc>; +def intinst { SMULrr, SMULri}<0b001011, "smul $b, $c, $dst", mul>; //===------------------------- // X86 Example From lattner at cs.uiuc.edu Mon May 8 23:59:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 8 May 2006 23:59:42 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h Message-ID: <200605090459.XAA03371@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.37 -> 1.38 --- Log message: Split SwitchSection into the SwitchTo{Text|Data}Section functions, to better support assemblers that distinguish the two. --- Diffs of the changes: (+19 -3) AsmPrinter.h | 22 +++++++++++++++++++--- 1 files changed, 19 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.37 llvm/include/llvm/CodeGen/AsmPrinter.h:1.38 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.37 Tue May 2 00:37:32 2006 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Mon May 8 23:59:30 2006 @@ -179,16 +179,32 @@ AsmPrinter(std::ostream &o, TargetMachine &TM); public: - /// SwitchSection - Switch to the specified section of the executable if we - /// are not already in it! If GV is non-null and if the global has an + /// SwitchToTextSection - Switch to the specified section of the executable + /// if we are not already in it! If GV is non-null and if the global has an /// explicitly requested section, we switch to the section indicated for the /// global instead of NewSection. /// /// If the new section is an empty string, this method forgets what the /// current section is, but does not emit a .section directive. /// - void SwitchSection(const char *NewSection, const GlobalValue *GV); + /// This method is used when about to emit executable code. + /// + void SwitchToTextSection(const char *NewSection, const GlobalValue *GV); + /// SwitchToDataSection - Switch to the specified section of the executable + /// if we are not already in it! If GV is non-null and if the global has an + /// explicitly requested section, we switch to the section indicated for the + /// global instead of NewSection. + /// + /// If the new section is an empty string, this method forgets what the + /// current section is, but does not emit a .section directive. + /// + /// This method is used when about to emit data. For most assemblers, this + /// is the same as the SwitchToTextSection method, but not all assemblers + /// are the same. + /// + void SwitchToDataSection(const char *NewSection, const GlobalValue *GV); + /// getPreferredAlignmentLog - Return the preferred alignment of the /// specified global, returned in log form. This includes an explicitly /// requested alignment (if the global has one). From lattner at cs.uiuc.edu Tue May 9 00:00:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:00:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Message-ID: <200605090500.AAA03436@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaAsmPrinter.cpp updated: 1.41 -> 1.42 --- Log message: Split SwitchSection into SwitchTo{Text|Data}Section methods. --- Diffs of the changes: (+5 -5) AlphaAsmPrinter.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp diff -u llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.41 llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.42 --- llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.41 Thu May 4 13:05:43 2006 +++ llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -151,7 +151,7 @@ // Print out labels for the function. const Function *F = MF.getFunction(); - SwitchSection(".text", F); + SwitchToTextSection(".text", F); EmitAlignment(4, F); switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); @@ -221,7 +221,7 @@ if (C->isNullValue() && (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection("\t.section .data", I); + SwitchToDataSection("\t.section .data", I); if (I->hasInternalLinkage()) O << "\t.local " << name << "\n"; @@ -235,7 +235,7 @@ // Nonnull linkonce -> weak O << "\t.weak " << name << "\n"; O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; - SwitchSection("", I); + SwitchToDataSection("", I); break; case GlobalValue::AppendingLinkage: // FIXME: appending linkage variables should go into a section of @@ -245,8 +245,8 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(C->isNullValue() ? "\t.section .bss" : - "\t.section .data", I); + SwitchToDataSection(C->isNullValue() ? "\t.section .bss" : + "\t.section .data", I); break; case GlobalValue::GhostLinkage: std::cerr << "GhostLinkage cannot appear in AlphaAsmPrinter!\n"; From lattner at cs.uiuc.edu Tue May 9 00:00:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:00:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Message-ID: <200605090500.AAA03438@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcAsmPrinter.cpp updated: 1.64 -> 1.65 --- Log message: Split SwitchSection into SwitchTo{Text|Data}Section methods. --- Diffs of the changes: (+6 -6) SparcAsmPrinter.cpp | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp diff -u llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.64 llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.65 --- llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.64 Thu May 4 13:05:43 2006 +++ llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -98,8 +98,8 @@ CurrentFnName = Mang->getValueName(MF.getFunction()); // Print out labels for the function. - O << "\t.text\n"; - O << "\t.align 16\n"; + SwitchToTextSection(".text", MF.getFunction()); + EmitAlignment(4, MF.getFunction()); O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.type\t" << CurrentFnName << ", #function\n"; O << CurrentFnName << ":\n"; @@ -238,7 +238,7 @@ if (C->isNullValue() && (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection(".data", I); + SwitchToDataSection(".data", I); if (I->hasInternalLinkage()) O << "\t.local " << name << "\n"; @@ -253,7 +253,7 @@ case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. // Nonnull linkonce -> weak O << "\t.weak " << name << "\n"; - SwitchSection("", I); + SwitchToDataSection("", I); O << "\t.section\t\".llvm.linkonce.d." << name << "\",\"aw\", at progbits\n"; break; @@ -267,9 +267,9 @@ // FALL THROUGH case GlobalValue::InternalLinkage: if (C->isNullValue()) - SwitchSection(".bss", I); + SwitchToDataSection(".bss", I); else - SwitchSection(".data", I); + SwitchToDataSection(".data", I); break; case GlobalValue::GhostLinkage: std::cerr << "Should not have any unmaterialized functions!\n"; From lattner at cs.uiuc.edu Tue May 9 00:00:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:00:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64AsmPrinter.cpp Message-ID: <200605090500.AAA03460@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64AsmPrinter.cpp updated: 1.32 -> 1.33 --- Log message: Split SwitchSection into SwitchTo{Text|Data}Section methods. --- Diffs of the changes: (+5 -4) IA64AsmPrinter.cpp | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) Index: llvm/lib/Target/IA64/IA64AsmPrinter.cpp diff -u llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.32 llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.33 --- llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.32 Thu May 4 13:05:43 2006 +++ llvm/lib/Target/IA64/IA64AsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -142,7 +142,8 @@ EmitConstantPool(MF.getConstantPool()); // Print out labels for the function. - SwitchSection("\n\t.section .text, \"ax\", \"progbits\"\n", MF.getFunction()); + SwitchToTextSection("\n\t.section .text, \"ax\", \"progbits\"\n", + MF.getFunction()); // ^^ means "Allocated instruXions in mem, initialized" EmitAlignment(5); O << "\t.global\t" << CurrentFnName << "\n"; @@ -282,7 +283,7 @@ if (C->isNullValue() && (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection(".data", I); + SwitchToDataSection(".data", I); if (I->hasInternalLinkage()) { O << "\t.lcomm " << name << "#," << TD->getTypeSize(C->getType()) << "," << (1 << Align); @@ -302,7 +303,7 @@ O << "\t.weak " << name << "\n"; O << "\t.section\t.llvm.linkonce.d." << name << ", \"aw\", \"progbits\"\n"; - SwitchSection("", I); + SwitchToDataSection("", I); break; case GlobalValue::AppendingLinkage: // FIXME: appending linkage variables should go into a section of @@ -312,7 +313,7 @@ O << "\t.global " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(C->isNullValue() ? ".bss" : ".data", I); + SwitchToDataSection(C->isNullValue() ? ".bss" : ".data", I); break; case GlobalValue::GhostLinkage: std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n"; From lattner at cs.uiuc.edu Tue May 9 00:00:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:00:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86IntelAsmPrinter.cpp Message-ID: <200605090500.AAA03452@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.44 -> 1.45 X86AsmPrinter.cpp updated: 1.179 -> 1.180 X86IntelAsmPrinter.cpp updated: 1.44 -> 1.45 --- Log message: Split SwitchSection into SwitchTo{Text|Data}Section methods. --- Diffs of the changes: (+18 -16) X86ATTAsmPrinter.cpp | 9 +++++---- X86AsmPrinter.cpp | 15 ++++++++------- X86IntelAsmPrinter.cpp | 10 +++++----- 3 files changed, 18 insertions(+), 16 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.44 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.45 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.44 Mon May 8 03:01:26 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -46,25 +46,26 @@ switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); case Function::InternalLinkage: // Symbols default to internal. - SwitchSection(".text", F); + SwitchToTextSection(".text", F); EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. break; case Function::ExternalLinkage: - SwitchSection(".text", F); + SwitchToTextSection(".text", F); EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. O << "\t.globl\t" << CurrentFnName << "\n"; break; case Function::WeakLinkage: case Function::LinkOnceLinkage: if (forDarwin) { - SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions", - F); + SwitchToTextSection( + ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.weak_definition\t" << CurrentFnName << "\n"; } else { EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. O << "\t.section\t.llvm.linkonce.t." << CurrentFnName << ",\"ax\", at progbits\n"; + SwitchToTextSection("", F); O << "\t.weak " << CurrentFnName << "\n"; } break; Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.179 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.180 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.179 Sat May 6 16:27:14 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -119,7 +119,7 @@ O << "\t.zerofill __DATA__, __common, " << name << ", " << Size << ", " << Align; } else { - SwitchSection(".data", I); + SwitchToDataSection(".data", I); if (LCOMMDirective != NULL) { if (I->hasInternalLinkage()) { O << LCOMMDirective << name << "," << Size; @@ -143,7 +143,7 @@ if (forDarwin) { O << "\t.globl " << name << "\n" << "\t.weak_definition " << name << "\n"; - SwitchSection(".section __DATA,__datacoal_nt,coalesced", I); + SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); } else { O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; O << "\t.weak " << name << "\n"; @@ -157,7 +157,7 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(".data", I); + SwitchToDataSection(".data", I); break; default: assert(0 && "Unknown linkage type!"); @@ -175,14 +175,14 @@ } if (forDarwin) { - SwitchSection("", 0); + SwitchToDataSection("", 0); // Output stubs for dynamically-linked functions unsigned j = 1; for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i, ++j) { - SwitchSection(".section __IMPORT,__jump_table,symbol_stubs," - "self_modifying_code+pure_instructions,5", 0); + SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs," + "self_modifying_code+pure_instructions,5", 0); O << "L" << *i << "$stub:\n"; O << "\t.indirect_symbol " << *i << "\n"; O << "\thlt ; hlt ; hlt ; hlt ; hlt\n"; @@ -192,7 +192,8 @@ // Output stubs for external and common global variables. if (GVStubs.begin() != GVStubs.end()) - SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0); + SwitchToDataSection( + ".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0); for (std::set::iterator i = GVStubs.begin(), e = GVStubs.end(); i != e; ++i) { O << "L" << *i << "$non_lazy_ptr:\n"; Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.44 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.45 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.44 Mon May 8 03:01:26 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -37,7 +37,7 @@ EmitConstantPool(MF.getConstantPool()); // Print out labels for the function. - SwitchSection(".code", MF.getFunction()); + SwitchToTextSection(".code", MF.getFunction()); EmitAlignment(4); if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage) O << "\tpublic " << CurrentFnName << "\n"; @@ -342,14 +342,14 @@ switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: case GlobalValue::WeakLinkage: - SwitchSection("", 0); + SwitchToDataSection("", 0); O << name << "?\tsegment common 'COMMON'\n"; bCustomSegment = true; // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 // are also available. break; case GlobalValue::AppendingLinkage: - SwitchSection("", 0); + SwitchToDataSection("", 0); O << name << "?\tsegment public 'DATA'\n"; bCustomSegment = true; // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 @@ -359,7 +359,7 @@ O << "\tpublic " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(".data", I); + SwitchToDataSection(".data", I); break; default: assert(0 && "Unknown linkage type!"); @@ -378,7 +378,7 @@ // Bypass X86SharedAsmPrinter::doFinalization(). AsmPrinter::doFinalization(M); - SwitchSection("", 0); + SwitchToDataSection("", 0); O << "\tend\n"; return false; // success } From lattner at cs.uiuc.edu Tue May 9 00:00:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:00:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp DwarfWriter.cpp Message-ID: <200605090500.AAA03446@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.68 -> 1.69 DwarfWriter.cpp updated: 1.58 -> 1.59 --- Log message: Split SwitchSection into SwitchTo{Text|Data}Section methods. --- Diffs of the changes: (+81 -39) AsmPrinter.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++------------ DwarfWriter.cpp | 50 ++++++++++++++++++++-------------------- 2 files changed, 81 insertions(+), 39 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.68 llvm/lib/CodeGen/AsmPrinter.cpp:1.69 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.68 Sat May 6 16:27:14 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -59,10 +59,11 @@ } -/// SwitchSection - Switch to the specified section of the executable if we -/// are not already in it! +/// SwitchToTextSection - Switch to the specified text section of the executable +/// if we are not already in it! /// -void AsmPrinter::SwitchSection(const char *NewSection, const GlobalValue *GV) { +void AsmPrinter::SwitchToTextSection(const char *NewSection, + const GlobalValue *GV) { std::string NS; // Microsoft ML/MASM has a fundamentally different approach to handling @@ -78,12 +79,8 @@ return; } - bool isData = strcmp(NewSection , ".data") == 0; - if (GV && GV->hasSection()) NS = GV->getSection(); - else if (isData) - NS = "_data"; else NS = "_text"; @@ -91,8 +88,7 @@ if (!CurrentSection.empty()) O << CurrentSection << "\tends\n\n"; CurrentSection = NS; - O << CurrentSection << (isData ? "\tsegment 'DATA'\n" - : "\tsegment 'CODE'\n"); + O << CurrentSection << "\tsegment 'CODE'\n"; } } else { if (GV && GV->hasSection()) @@ -108,6 +104,52 @@ } } +/// SwitchToTextSection - Switch to the specified text section of the executable +/// if we are not already in it! +/// +void AsmPrinter::SwitchToDataSection(const char *NewSection, + const GlobalValue *GV) { + std::string NS; + + // Microsoft ML/MASM has a fundamentally different approach to handling + // sections. + + if (MLSections) { + if (*NewSection == 0) { + // Simply end the current section, if any. + if (!CurrentSection.empty()) { + O << CurrentSection << "\tends\n\n"; + CurrentSection.clear(); + } + return; + } + + if (GV && GV->hasSection()) + NS = GV->getSection(); + else + NS = "_data"; + + if (CurrentSection != NS) { + if (!CurrentSection.empty()) + O << CurrentSection << "\tends\n\n"; + CurrentSection = NS; + O << CurrentSection << "\tsegment 'DATA'\n"; + } + } else { + if (GV && GV->hasSection()) + NS = SwitchToSectionDirective + GV->getSection(); + else + NS = std::string("\t")+NewSection; + + if (CurrentSection != NS) { + CurrentSection = NS; + if (!CurrentSection.empty()) + O << CurrentSection << '\n'; + } + } +} + + bool AsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M, GlobalPrefix); @@ -116,7 +158,7 @@ << M.getModuleInlineAsm() << "\n" << CommentString << " End of file scope inline assembly\n"; - SwitchSection("", 0); // Reset back to no section. + SwitchToDataSection("", 0); // Reset back to no section. if (MachineDebugInfo *DebugInfo = getAnalysisToUpdate()) { DebugInfo->AnalyzeModule(M); @@ -146,7 +188,7 @@ if (CP.empty()) return; const TargetData *TD = TM.getTargetData(); - SwitchSection(ConstantPoolSection, 0); + SwitchToDataSection(ConstantPoolSection, 0); EmitAlignment(MCP->getConstantPoolAlignment()); for (unsigned i = 0, e = CP.size(); i != e; ++i) { O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' << i @@ -175,7 +217,7 @@ TM.getRelocationModel() == Reloc::DynamicNoPIC) && "Unhandled relocation model emitting jump table information!"); - SwitchSection(JumpTableSection, 0); + SwitchToDataSection(JumpTableSection, 0); EmitAlignment(Log2_32(TD->getPointerAlignment())); for (unsigned i = 0, e = JT.size(); i != e; ++i) { O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i @@ -204,14 +246,14 @@ return true; // No need to emit this at all. if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) { - SwitchSection(StaticCtorsSection, 0); + SwitchToDataSection(StaticCtorsSection, 0); EmitAlignment(2, 0); EmitXXStructorList(GV->getInitializer()); return true; } if (GV->getName() == "llvm.global_dtors" && GV->use_empty()) { - SwitchSection(StaticDtorsSection, 0); + SwitchToDataSection(StaticDtorsSection, 0); EmitAlignment(2, 0); EmitXXStructorList(GV->getInitializer()); return true; Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.58 llvm/lib/CodeGen/DwarfWriter.cpp:1.59 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.58 Tue May 2 20:29:56 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Mon May 8 23:59:56 2006 @@ -1647,33 +1647,33 @@ /// void DwarfWriter::EmitInitial() const { // Dwarf sections base addresses. - Asm->SwitchSection(DwarfFrameSection, 0); + Asm->SwitchToDataSection(DwarfFrameSection, 0); EmitLabel("section_frame", 0); - Asm->SwitchSection(DwarfInfoSection, 0); + Asm->SwitchToDataSection(DwarfInfoSection, 0); EmitLabel("section_info", 0); EmitLabel("info", 0); - Asm->SwitchSection(DwarfAbbrevSection, 0); + Asm->SwitchToDataSection(DwarfAbbrevSection, 0); EmitLabel("section_abbrev", 0); EmitLabel("abbrev", 0); - Asm->SwitchSection(DwarfARangesSection, 0); + Asm->SwitchToDataSection(DwarfARangesSection, 0); EmitLabel("section_aranges", 0); - Asm->SwitchSection(DwarfMacInfoSection, 0); + Asm->SwitchToDataSection(DwarfMacInfoSection, 0); EmitLabel("section_macinfo", 0); - Asm->SwitchSection(DwarfLineSection, 0); + Asm->SwitchToDataSection(DwarfLineSection, 0); EmitLabel("section_line", 0); EmitLabel("line", 0); - Asm->SwitchSection(DwarfLocSection, 0); + Asm->SwitchToDataSection(DwarfLocSection, 0); EmitLabel("section_loc", 0); - Asm->SwitchSection(DwarfPubNamesSection, 0); + Asm->SwitchToDataSection(DwarfPubNamesSection, 0); EmitLabel("section_pubnames", 0); - Asm->SwitchSection(DwarfStrSection, 0); + Asm->SwitchToDataSection(DwarfStrSection, 0); EmitLabel("section_str", 0); - Asm->SwitchSection(DwarfRangesSection, 0); + Asm->SwitchToDataSection(DwarfRangesSection, 0); EmitLabel("section_ranges", 0); - Asm->SwitchSection(TextSection, 0); + Asm->SwitchToDataSection(TextSection, 0); EmitLabel("text_begin", 0); - Asm->SwitchSection(DataSection, 0); + Asm->SwitchToDataSection(DataSection, 0); EmitLabel("data_begin", 0); } @@ -1849,7 +1849,7 @@ /// void DwarfWriter::EmitDebugInfo() const { // Start debug info section. - Asm->SwitchSection(DwarfInfoSection, 0); + Asm->SwitchToDataSection(DwarfInfoSection, 0); // Process each compile unit. for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { @@ -1884,7 +1884,7 @@ // Check to see if it is worth the effort. if (!Abbreviations.empty()) { // Start the debug abbrev section. - Asm->SwitchSection(DwarfAbbrevSection, 0); + Asm->SwitchToDataSection(DwarfAbbrevSection, 0); EmitLabel("abbrev_begin", 0); @@ -1918,7 +1918,7 @@ const int MaxLineDelta = 255 + MinLineDelta; // Start the dwarf line section. - Asm->SwitchSection(DwarfLineSection, 0); + Asm->SwitchToDataSection(DwarfLineSection, 0); // Construct the section header. @@ -2061,7 +2061,7 @@ AddressSize : -AddressSize; // Start the dwarf frame section. - Asm->SwitchSection(DwarfFrameSection, 0); + Asm->SwitchToDataSection(DwarfFrameSection, 0); EmitDifference("frame_common_end", 0, "frame_common_begin", 0); @@ -2090,7 +2090,7 @@ /// section. void DwarfWriter::EmitFunctionDebugFrame() { // Start the dwarf frame section. - Asm->SwitchSection(DwarfFrameSection, 0); + Asm->SwitchToDataSection(DwarfFrameSection, 0); EmitDifference("frame_end", SubprogramCount, "frame_begin", SubprogramCount); @@ -2119,7 +2119,7 @@ /// void DwarfWriter::EmitDebugPubNames() { // Start the dwarf pubnames section. - Asm->SwitchSection(DwarfPubNamesSection, 0); + Asm->SwitchToDataSection(DwarfPubNamesSection, 0); // Process each compile unit. for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { @@ -2166,7 +2166,7 @@ // Check to see if it is worth the effort. if (!StringPool.empty()) { // Start the dwarf str section. - Asm->SwitchSection(DwarfStrSection, 0); + Asm->SwitchToDataSection(DwarfStrSection, 0); // For each of strings in the string pool. for (unsigned StringID = 1, N = StringPool.size(); @@ -2186,7 +2186,7 @@ /// void DwarfWriter::EmitDebugLoc() { // Start the dwarf loc section. - Asm->SwitchSection(DwarfLocSection, 0); + Asm->SwitchToDataSection(DwarfLocSection, 0); O << "\n"; } @@ -2195,7 +2195,7 @@ /// void DwarfWriter::EmitDebugARanges() { // Start the dwarf aranges section. - Asm->SwitchSection(DwarfARangesSection, 0); + Asm->SwitchToDataSection(DwarfARangesSection, 0); // FIXME - Mock up #if 0 @@ -2236,7 +2236,7 @@ /// void DwarfWriter::EmitDebugRanges() { // Start the dwarf ranges section. - Asm->SwitchSection(DwarfRangesSection, 0); + Asm->SwitchToDataSection(DwarfRangesSection, 0); O << "\n"; } @@ -2245,7 +2245,7 @@ /// void DwarfWriter::EmitDebugMacInfo() { // Start the dwarf macinfo section. - Asm->SwitchSection(DwarfMacInfoSection, 0); + Asm->SwitchToDataSection(DwarfMacInfoSection, 0); O << "\n"; } @@ -2381,9 +2381,9 @@ EOL("Dwarf End Module"); // Standard sections final addresses. - Asm->SwitchSection(TextSection, 0); + Asm->SwitchToTextSection(TextSection, 0); EmitLabel("text_end", 0); - Asm->SwitchSection(DataSection, 0); + Asm->SwitchToDataSection(DataSection, 0); EmitLabel("data_end", 0); // Compute DIE offsets and sizes. From lattner at cs.uiuc.edu Tue May 9 00:00:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:00:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200605090500.AAA03458@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.172 -> 1.173 --- Log message: Split SwitchSection into SwitchTo{Text|Data}Section methods. --- Diffs of the changes: (+16 -16) PPCAsmPrinter.cpp | 32 ++++++++++++++++---------------- 1 files changed, 16 insertions(+), 16 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.172 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.173 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.172 Fri May 5 16:50:04 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Mon May 8 23:59:56 2006 @@ -511,16 +511,16 @@ switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); case Function::InternalLinkage: // Symbols default to internal. - SwitchSection(".text", F); + SwitchToTextSection(".text", F); break; case Function::ExternalLinkage: - SwitchSection(".text", F); + SwitchToTextSection(".text", F); O << "\t.globl\t" << CurrentFnName << "\n"; break; case Function::WeakLinkage: case Function::LinkOnceLinkage: - SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions", - F); + SwitchToTextSection( + ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.weak_definition\t" << CurrentFnName << "\n"; break; @@ -595,10 +595,10 @@ O << "\t.zerofill __DATA, __common, " << name << ", " << Size << ", " << Align; } else if (I->hasInternalLinkage()) { - SwitchSection(".data", I); + SwitchToDataSection(".data", I); O << LCOMMDirective << name << "," << Size << "," << Align; } else { - SwitchSection(".data", I); + SwitchToDataSection(".data", I); O << ".comm " << name << "," << Size; } O << "\t\t; '" << I->getName() << "'\n"; @@ -608,7 +608,7 @@ case GlobalValue::WeakLinkage: O << "\t.globl " << name << '\n' << "\t.weak_definition " << name << '\n'; - SwitchSection(".section __DATA,__datacoal_nt,coalesced", I); + SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); break; case GlobalValue::AppendingLinkage: // FIXME: appending linkage variables should go into a section of @@ -618,7 +618,7 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(".data", I); + SwitchToDataSection(".data", I); break; default: std::cerr << "Unknown linkage type!"; @@ -636,8 +636,8 @@ if (TM.getRelocationModel() == Reloc::PIC) { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { - SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs," - "pure_instructions,32", 0); + SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," + "pure_instructions,32", 0); EmitAlignment(2); O << "L" << *i << "$stub:\n"; O << "\t.indirect_symbol " << *i << "\n"; @@ -650,7 +650,7 @@ O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; - SwitchSection(".lazy_symbol_pointer", 0); + SwitchToDataSection(".lazy_symbol_pointer", 0); O << "L" << *i << "$lazy_ptr:\n"; O << "\t.indirect_symbol " << *i << "\n"; O << "\t.long dyld_stub_binding_helper\n"; @@ -658,8 +658,8 @@ } else { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { - SwitchSection(".section __TEXT,__symbol_stub1,symbol_stubs," - "pure_instructions,16", 0); + SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," + "pure_instructions,16", 0); EmitAlignment(4); O << "L" << *i << "$stub:\n"; O << "\t.indirect_symbol " << *i << "\n"; @@ -667,7 +667,7 @@ O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; - SwitchSection(".lazy_symbol_pointer", 0); + SwitchToDataSection(".lazy_symbol_pointer", 0); O << "L" << *i << "$lazy_ptr:\n"; O << "\t.indirect_symbol " << *i << "\n"; O << "\t.long dyld_stub_binding_helper\n"; @@ -678,7 +678,7 @@ // Output stubs for external and common global variables. if (GVStubs.begin() != GVStubs.end()) { - SwitchSection(".non_lazy_symbol_pointer", 0); + SwitchToDataSection(".non_lazy_symbol_pointer", 0); for (std::set::iterator I = GVStubs.begin(), E = GVStubs.end(); I != E; ++I) { O << "L" << *I << "$non_lazy_ptr:\n"; @@ -747,7 +747,7 @@ } bool AIXAsmPrinter::doInitialization(Module &M) { - SwitchSection("", 0); + SwitchToDataSection("", 0); const TargetData *TD = TM.getTargetData(); O << "\t.machine \"ppc64\"\n" From lattner at cs.uiuc.edu Tue May 9 00:13:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:13:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86AsmPrinter.h X86IntelAsmPrinter.cpp Message-ID: <200605090513.AAA03563@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.45 -> 1.46 X86AsmPrinter.cpp updated: 1.180 -> 1.181 X86AsmPrinter.h updated: 1.17 -> 1.18 X86IntelAsmPrinter.cpp updated: 1.45 -> 1.46 --- Log message: Fix the MASM asmprinter's lies. It does not want to emit code to .text/.data it wants it emitted to _text/_data. --- Diffs of the changes: (+17 -7) X86ATTAsmPrinter.cpp | 4 ++-- X86AsmPrinter.cpp | 6 ++++-- X86AsmPrinter.h | 4 ++++ X86IntelAsmPrinter.cpp | 10 +++++++--- 4 files changed, 17 insertions(+), 7 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.45 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.46 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.45 Mon May 8 23:59:56 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Tue May 9 00:12:53 2006 @@ -46,11 +46,11 @@ switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); case Function::InternalLinkage: // Symbols default to internal. - SwitchToTextSection(".text", F); + SwitchToTextSection(DefaultTextSection, F); EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. break; case Function::ExternalLinkage: - SwitchToTextSection(".text", F); + SwitchToTextSection(DefaultTextSection, F); EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. O << "\t.globl\t" << CurrentFnName << "\n"; break; Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.180 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.181 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.180 Mon May 8 23:59:56 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Tue May 9 00:12:53 2006 @@ -50,6 +50,8 @@ forDarwin = false; PrivateGlobalPrefix = ".L"; + DefaultTextSection = ".text"; + DefaultDataSection = ".data"; switch (Subtarget->TargetType) { case X86Subtarget::isDarwin: @@ -119,7 +121,7 @@ O << "\t.zerofill __DATA__, __common, " << name << ", " << Size << ", " << Align; } else { - SwitchToDataSection(".data", I); + SwitchToDataSection(DefaultDataSection, I); if (LCOMMDirective != NULL) { if (I->hasInternalLinkage()) { O << LCOMMDirective << name << "," << Size; @@ -157,7 +159,7 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchToDataSection(".data", I); + SwitchToDataSection(DefaultDataSection, I); break; default: assert(0 && "Unknown linkage type!"); Index: llvm/lib/Target/X86/X86AsmPrinter.h diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.17 llvm/lib/Target/X86/X86AsmPrinter.h:1.18 --- llvm/lib/Target/X86/X86AsmPrinter.h:1.17 Tue May 2 12:34:51 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.h Tue May 9 00:12:53 2006 @@ -69,6 +69,10 @@ } bool forDarwin; // FIXME: eliminate. + + const char *DefaultTextSection; // "_text" for MASM, ".text" for others. + const char *DefaultDataSection; // "_data" for MASM, ".data" for others. + // Necessary for Darwin to print out the apprioriate types of linker stubs std::set FnStubs, GVStubs, LinkOnceStubs; Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.45 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.46 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.45 Mon May 8 23:59:56 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Tue May 9 00:12:53 2006 @@ -37,7 +37,7 @@ EmitConstantPool(MF.getConstantPool()); // Print out labels for the function. - SwitchToTextSection(".code", MF.getFunction()); + SwitchToTextSection("_text", MF.getFunction()); EmitAlignment(4); if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage) O << "\tpublic " << CurrentFnName << "\n"; @@ -302,6 +302,9 @@ Data64bitsDirective = "\tdq\t"; HasDotTypeDotSizeDirective = false; Mang->markCharUnacceptable('.'); + + DefaultTextSection = "_text"; + DefaultDataSection = "_data"; O << "\t.686\n\t.model flat\n\n"; @@ -359,7 +362,7 @@ O << "\tpublic " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchToDataSection(".data", I); + SwitchToDataSection(DefaultDataSection, I); break; default: assert(0 && "Unknown linkage type!"); @@ -378,7 +381,8 @@ // Bypass X86SharedAsmPrinter::doFinalization(). AsmPrinter::doFinalization(M); - SwitchToDataSection("", 0); + SwitchToDataSection("_data", 0); + O << "_data\tends\n"; O << "\tend\n"; return false; // success } From lattner at cs.uiuc.edu Tue May 9 00:13:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:13:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605090513.AAA03620@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.69 -> 1.70 --- Log message: The MASM asmprinter has been fixed, these hacks are no longer needed. --- Diffs of the changes: (+2 -20) AsmPrinter.cpp | 22 ++-------------------- 1 files changed, 2 insertions(+), 20 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.69 llvm/lib/CodeGen/AsmPrinter.cpp:1.70 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.69 Mon May 8 23:59:56 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 00:13:34 2006 @@ -70,19 +70,10 @@ // sections. if (MLSections) { - if (*NewSection == 0) { - // Simply end the current section, if any. - if (!CurrentSection.empty()) { - O << CurrentSection << "\tends\n\n"; - CurrentSection.clear(); - } - return; - } - if (GV && GV->hasSection()) NS = GV->getSection(); else - NS = "_text"; + NS = NewSection; if (CurrentSection != NS) { if (!CurrentSection.empty()) @@ -115,19 +106,10 @@ // sections. if (MLSections) { - if (*NewSection == 0) { - // Simply end the current section, if any. - if (!CurrentSection.empty()) { - O << CurrentSection << "\tends\n\n"; - CurrentSection.clear(); - } - return; - } - if (GV && GV->hasSection()) NS = GV->getSection(); else - NS = "_data"; + NS = NewSection; if (CurrentSection != NS) { if (!CurrentSection.empty()) From lattner at cs.uiuc.edu Tue May 9 00:15:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:15:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Message-ID: <200605090515.AAA03662@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86IntelAsmPrinter.cpp updated: 1.46 -> 1.47 --- Log message: Preserve prior behavior --- Diffs of the changes: (+1 -2) X86IntelAsmPrinter.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.46 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.47 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.46 Tue May 9 00:12:53 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Tue May 9 00:15:24 2006 @@ -381,8 +381,7 @@ // Bypass X86SharedAsmPrinter::doFinalization(). AsmPrinter::doFinalization(M); - SwitchToDataSection("_data", 0); - O << "_data\tends\n"; + SwitchToDataSection("", 0); O << "\tend\n"; return false; // success } From lattner at cs.uiuc.edu Tue May 9 00:16:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:16:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605090516.AAA03719@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.70 -> 1.71 --- Log message: Make the masm codepath work like the normal code path. --- Diffs of the changes: (+4 -2) AsmPrinter.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.70 llvm/lib/CodeGen/AsmPrinter.cpp:1.71 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.70 Tue May 9 00:13:34 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 00:15:58 2006 @@ -79,7 +79,8 @@ if (!CurrentSection.empty()) O << CurrentSection << "\tends\n\n"; CurrentSection = NS; - O << CurrentSection << "\tsegment 'CODE'\n"; + if (!CurrentSection.empty()) + O << CurrentSection << "\tsegment 'CODE'\n"; } } else { if (GV && GV->hasSection()) @@ -115,7 +116,8 @@ if (!CurrentSection.empty()) O << CurrentSection << "\tends\n\n"; CurrentSection = NS; - O << CurrentSection << "\tsegment 'DATA'\n"; + if (!CurrentSection.empty()) + O << CurrentSection << "\tsegment 'DATA'\n"; } } else { if (GV && GV->hasSection()) From lattner at cs.uiuc.edu Tue May 9 00:20:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:20:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605090520.AAA03827@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.71 -> 1.72 --- Log message: Don't prefix section directives with a tab. Doing so causes blank lines to be emitted to the .s file. --- Diffs of the changes: (+1 -1) AsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.71 llvm/lib/CodeGen/AsmPrinter.cpp:1.72 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.71 Tue May 9 00:15:58 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 00:19:59 2006 @@ -123,7 +123,7 @@ if (GV && GV->hasSection()) NS = SwitchToSectionDirective + GV->getSection(); else - NS = std::string("\t")+NewSection; + NS = NewSection; if (CurrentSection != NS) { CurrentSection = NS; From lattner at cs.uiuc.edu Tue May 9 00:22:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:22:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Message-ID: <200605090522.AAA03887@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86IntelAsmPrinter.cpp updated: 1.47 -> 1.48 --- Log message: MASM doesn't have one of these. --- Diffs of the changes: (+1 -0) X86IntelAsmPrinter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.47 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.48 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.47 Tue May 9 00:15:24 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Tue May 9 00:21:47 2006 @@ -305,6 +305,7 @@ DefaultTextSection = "_text"; DefaultDataSection = "_data"; + SwitchToSectionDirective = ""; O << "\t.686\n\t.model flat\n\n"; From lattner at cs.uiuc.edu Tue May 9 00:23:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:23:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605090523.AAA03947@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.72 -> 1.73 --- Log message: Setting SwitchToSectionDirective properly in the MASM backend permits a bunch of code to be unified. --- Diffs of the changes: (+15 -22) AsmPrinter.cpp | 37 +++++++++++++++---------------------- 1 files changed, 15 insertions(+), 22 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.72 llvm/lib/CodeGen/AsmPrinter.cpp:1.73 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.72 Tue May 9 00:19:59 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 00:23:12 2006 @@ -102,34 +102,27 @@ void AsmPrinter::SwitchToDataSection(const char *NewSection, const GlobalValue *GV) { std::string NS; + if (GV && GV->hasSection()) + NS = SwitchToSectionDirective + GV->getSection(); + else + NS = NewSection; + // If we're already in this section, we're done. + if (CurrentSection == NS) return; + // Microsoft ML/MASM has a fundamentally different approach to handling // sections. if (MLSections) { - if (GV && GV->hasSection()) - NS = GV->getSection(); - else - NS = NewSection; - - if (CurrentSection != NS) { - if (!CurrentSection.empty()) - O << CurrentSection << "\tends\n\n"; - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << "\tsegment 'DATA'\n"; - } + if (!CurrentSection.empty()) + O << CurrentSection << "\tends\n\n"; + CurrentSection = NS; + if (!CurrentSection.empty()) + O << CurrentSection << "\tsegment 'DATA'\n"; } else { - if (GV && GV->hasSection()) - NS = SwitchToSectionDirective + GV->getSection(); - else - NS = NewSection; - - if (CurrentSection != NS) { - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << '\n'; - } + CurrentSection = NS; + if (!CurrentSection.empty()) + O << CurrentSection << '\n'; } } From lattner at cs.uiuc.edu Tue May 9 00:25:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:25:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605090525.AAA04011@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.73 -> 1.74 --- Log message: Oh yeah, there are two of these now, unify both. --- Diffs of the changes: (+15 -22) AsmPrinter.cpp | 37 +++++++++++++++---------------------- 1 files changed, 15 insertions(+), 22 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.73 llvm/lib/CodeGen/AsmPrinter.cpp:1.74 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.73 Tue May 9 00:23:12 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 00:24:50 2006 @@ -65,34 +65,27 @@ void AsmPrinter::SwitchToTextSection(const char *NewSection, const GlobalValue *GV) { std::string NS; + if (GV && GV->hasSection()) + NS = GV->getSection(); + else + NS = NewSection; + + // If we're already in this section, we're done. + if (CurrentSection == NS) return; // Microsoft ML/MASM has a fundamentally different approach to handling // sections. if (MLSections) { - if (GV && GV->hasSection()) - NS = GV->getSection(); - else - NS = NewSection; - - if (CurrentSection != NS) { - if (!CurrentSection.empty()) - O << CurrentSection << "\tends\n\n"; - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << "\tsegment 'CODE'\n"; - } + if (!CurrentSection.empty()) + O << CurrentSection << "\tends\n\n"; + CurrentSection = NS; + if (!CurrentSection.empty()) + O << CurrentSection << "\tsegment 'CODE'\n"; } else { - if (GV && GV->hasSection()) - NS = SwitchToSectionDirective + GV->getSection(); - else - NS = std::string("\t")+NewSection; - - if (CurrentSection != NS) { - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << '\n'; - } + CurrentSection = NS; + if (!CurrentSection.empty()) + O << CurrentSection << '\n'; } } From lattner at cs.uiuc.edu Tue May 9 00:33:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:33:41 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h Message-ID: <200605090533.AAA04136@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.38 -> 1.39 --- Log message: Implement MASM sections correctly, without a "has masm sections flag" and a bunch of special case code. --- Diffs of the changes: (+12 -1) AsmPrinter.h | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.38 llvm/include/llvm/CodeGen/AsmPrinter.h:1.39 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.38 Mon May 8 23:59:30 2006 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Tue May 9 00:33:28 2006 @@ -137,7 +137,18 @@ /// emit a global to an arbitrary section. The section name is emited after /// this. const char *SwitchToSectionDirective; // Defaults to "\t.section\t" - bool MLSections; // True if Microsoft ML assembler is targetted + + /// TextSectionStartSuffix - This is printed after each start of section + /// directive for text sections. + const char *TextSectionStartSuffix; // Defaults to "". + + /// DataSectionStartSuffix - This is printed after each start of section + /// directive for data sections. + const char *DataSectionStartSuffix; // Defaults to "". + + /// SectionEndDirectiveSuffix - If non-null, the asm printer will close each + /// section with the section name and this suffix printed. + const char *SectionEndDirectiveSuffix; // Defaults to null. /// ConstantPoolSection - This is the section that we SwitchToSection right /// before emitting the constant pool for a function. From lattner at cs.uiuc.edu Tue May 9 00:34:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:34:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Message-ID: <200605090534.AAA04174@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86IntelAsmPrinter.cpp updated: 1.48 -> 1.49 --- Log message: Implement MASM sections correctly, without a "has masm sections flag" and a bunch of special case code. --- Diffs of the changes: (+3 -1) X86IntelAsmPrinter.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.48 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.49 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.48 Tue May 9 00:21:47 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Tue May 9 00:33:48 2006 @@ -284,7 +284,6 @@ } bool X86IntelAsmPrinter::doInitialization(Module &M) { - MLSections = true; GlobalPrefix = "_"; CommentString = ";"; @@ -306,6 +305,9 @@ DefaultTextSection = "_text"; DefaultDataSection = "_data"; SwitchToSectionDirective = ""; + TextSectionStartSuffix = "\tsegment 'CODE'"; + DataSectionStartSuffix = "\tsegment 'DATA'"; + SectionEndDirectiveSuffix = "\tends\n"; O << "\t.686\n\t.model flat\n\n"; From lattner at cs.uiuc.edu Tue May 9 00:34:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 00:34:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605090534.AAA04176@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.74 -> 1.75 --- Log message: Implement MASM sections correctly, without a "has masm sections flag" and a bunch of special case code. --- Diffs of the changes: (+17 -27) AsmPrinter.cpp | 44 +++++++++++++++++--------------------------- 1 files changed, 17 insertions(+), 27 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.74 llvm/lib/CodeGen/AsmPrinter.cpp:1.75 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.74 Tue May 9 00:24:50 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 00:33:48 2006 @@ -47,7 +47,9 @@ AlignDirective("\t.align\t"), AlignmentIsInBytes(true), SwitchToSectionDirective("\t.section\t"), - MLSections(false), + TextSectionStartSuffix(""), + DataSectionStartSuffix(""), + SectionEndDirectiveSuffix(0), ConstantPoolSection("\t.section .rodata\n"), JumpTableSection("\t.section .rodata\n"), StaticCtorsSection("\t.section .ctors,\"aw\", at progbits"), @@ -73,20 +75,14 @@ // If we're already in this section, we're done. if (CurrentSection == NS) return; - // Microsoft ML/MASM has a fundamentally different approach to handling - // sections. + // Close the current section, if applicable. + if (SectionEndDirectiveSuffix && !CurrentSection.empty()) + O << CurrentSection << SectionEndDirectiveSuffix << "\n"; - if (MLSections) { - if (!CurrentSection.empty()) - O << CurrentSection << "\tends\n\n"; - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << "\tsegment 'CODE'\n"; - } else { - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << '\n'; - } + CurrentSection = NS; + + if (!CurrentSection.empty()) + O << CurrentSection << TextSectionStartSuffix << '\n'; } /// SwitchToTextSection - Switch to the specified text section of the executable @@ -103,20 +99,14 @@ // If we're already in this section, we're done. if (CurrentSection == NS) return; - // Microsoft ML/MASM has a fundamentally different approach to handling - // sections. + // Close the current section, if applicable. + if (SectionEndDirectiveSuffix && !CurrentSection.empty()) + O << CurrentSection << SectionEndDirectiveSuffix << "\n"; + + CurrentSection = NS; - if (MLSections) { - if (!CurrentSection.empty()) - O << CurrentSection << "\tends\n\n"; - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << "\tsegment 'DATA'\n"; - } else { - CurrentSection = NS; - if (!CurrentSection.empty()) - O << CurrentSection << '\n'; - } + if (!CurrentSection.empty()) + O << CurrentSection << DataSectionStartSuffix << '\n'; } From evan.cheng at apple.com Tue May 9 01:34:39 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:34:39 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200605090634.BAA04360@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.40 -> 1.41 --- Log message: Add sub-register class information. --- Diffs of the changes: (+49 -3) RegisterInfoEmitter.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 49 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.40 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.41 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.40 Fri Mar 24 15:15:58 2006 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Tue May 9 01:34:26 2006 @@ -89,6 +89,16 @@ OS << "} // End llvm namespace \n"; } +bool isSubRegisterClass(const CodeGenRegisterClass &RC, + std::set &RegSet) { + for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { + Record *Reg = RC.Elements[i]; + if (!RegSet.count(Reg)) + return false; + } + return true; +} + // RegisterInfoEmitter::run - Main register file description emitter. // void RegisterInfoEmitter::run(std::ostream &OS) { @@ -130,7 +140,7 @@ } OS << "\n };\n\n"; } - + // Emit the ValueType arrays for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; @@ -155,12 +165,48 @@ for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) OS << " " << RegisterClasses[i].getName() << "Class\t" << RegisterClasses[i].getName() << "RegClass;\n"; - + + OS << "\n"; + // Emit the sub-classes array for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + std::set RegSet; + for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { + Record *Reg = RC.Elements[i]; + RegSet.insert(Reg); + } + + OS << " // " << Name + << " Register Class sub-classes...\n const TargetRegisterClass* " + << Name << "Subclasses [] = {\n "; + + bool Empty = true; + for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (rc == rc2 || RC2.Elements.size() > RC.Elements.size() || + RC.SpillSize != RC2.SpillSize || !isSubRegisterClass(RC2, RegSet)) + continue; + + if (!Empty) OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RegisterClasses[i]; OS << RC.MethodBodies << "\n"; OS << RC.getName() << "Class::" << RC.getName() - << "Class() : TargetRegisterClass(" << RC.getName() + "VTs" << ", " + << "Class() : TargetRegisterClass(" + << RC.getName() + "VTs" << ", " + << RC.getName() + "Subclasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; From evan.cheng at apple.com Tue May 9 01:35:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:35:42 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200605090635.BAA04400@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.75 -> 1.76 --- Log message: Added sub- register classes information. --- Diffs of the changes: (+29 -7) MRegisterInfo.h | 36 +++++++++++++++++++++++++++++------- 1 files changed, 29 insertions(+), 7 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.75 llvm/include/llvm/Target/MRegisterInfo.h:1.76 --- llvm/include/llvm/Target/MRegisterInfo.h:1.75 Mon Apr 10 18:09:19 2006 +++ llvm/include/llvm/Target/MRegisterInfo.h Tue May 9 01:35:30 2006 @@ -47,14 +47,18 @@ typedef const unsigned* const_iterator; typedef const MVT::ValueType* vt_iterator; + typedef const TargetRegisterClass** sc_iterator; private: const vt_iterator VTs; + const sc_iterator SubClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: - TargetRegisterClass(const MVT::ValueType *vts, unsigned RS, unsigned Al, - iterator RB, iterator RE) - : VTs(vts), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} + TargetRegisterClass(const MVT::ValueType *vts, + const TargetRegisterClass **scs, + unsigned RS, unsigned Al, iterator RB, iterator RE) + : VTs(vts), SubClasses(scs), + RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses // begin/end - Return all of the registers in this class. @@ -87,20 +91,38 @@ return false; } - /// vt_begin - Loop over all of the value types that can be represented by - /// values in this register class. + /// vt_begin / vt_end - Loop over all of the value types that can be + /// represented by values in this register class. vt_iterator vt_begin() const { return VTs; } - /// vt_begin - Loop over all of the value types that can be represented by - /// values in this register class. vt_iterator vt_end() const { vt_iterator I = VTs; while (*I != MVT::Other) ++I; return I; } + + /// hasSubRegClass - return true if the specified TargetRegisterClass is a + /// sub-register class of this TargetRegisterClass. + bool hasSubRegClass(const TargetRegisterClass *cs) const { + for (int i = 0; SubClasses[i] != NULL; ++i) + if (SubClasses[i] == cs) + return true; + return false; + } + + /// subclasses_begin / subclasses_end - Loop over all of the sub-classes of + /// this register class. + sc_iterator subclasses_begin() const { + return SubClasses; + } + sc_iterator subclasses_end() const { + sc_iterator I = SubClasses; + while (*I != NULL) ++I; + return I; + } /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register From evan.cheng at apple.com Tue May 9 01:38:01 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:38:01 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Message-ID: <200605090638.BAA04429@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveIntervalAnalysis.h updated: 1.51 -> 1.52 --- Log message: PR 770: http://llvm.cs.uiuc.edu/PR770 - permit coallescing of registers in subset register classes. --- Diffs of the changes: (+5 -3) LiveIntervalAnalysis.h | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h diff -u llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.51 llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.52 --- llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.51 Wed Feb 22 10:23:43 2006 +++ llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Tue May 9 01:37:48 2006 @@ -167,9 +167,11 @@ unsigned SrcReg, unsigned DestReg, bool isLiveIn = false); - /// Return true if the two specified registers belong to different - /// register classes. The registers may be either phys or virt regs. - bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; + /// Return true if the two specified registers belong to the same or + /// compatible register classes. The registers may be either phys or + /// virt regs. + bool compatibleRegisterClasses(unsigned RegA, unsigned RegB, + bool &Swap) const; bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, LiveInterval &IntB, From evan.cheng at apple.com Tue May 9 01:38:01 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:38:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200605090638.BAA04433@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.157 -> 1.158 --- Log message: PR 770: http://llvm.cs.uiuc.edu/PR770 - permit coallescing of registers in subset register classes. --- Diffs of the changes: (+25 -13) LiveIntervalAnalysis.cpp | 38 +++++++++++++++++++++++++------------- 1 files changed, 25 insertions(+), 13 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.157 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.158 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.157 Thu May 4 12:52:23 2006 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Tue May 9 01:37:47 2006 @@ -705,9 +705,12 @@ MRegisterInfo::isPhysicalRegister(DestReg)) continue; - // If they are not of the same register class, we cannot join them. - if (differingRegisterClasses(SrcReg, DestReg)) + // If they are not of compatible register classes, we cannot join them. + bool Swap = false; + if (!compatibleRegisterClasses(SrcReg, DestReg, Swap)) { + DEBUG(std::cerr << "Register classes aren't compatible!\n"); continue; + } LiveInterval &SrcInt = getInterval(SrcReg); LiveInterval &DestInt = getInterval(DestReg); @@ -741,7 +744,7 @@ DestInt.join(SrcInt, MIDefIdx); DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n"); - if (!MRegisterInfo::isPhysicalRegister(SrcReg)) { + if (!Swap && !MRegisterInfo::isPhysicalRegister(SrcReg)) { r2iMap_.erase(SrcReg); r2rMap_[SrcReg] = DestReg; } else { @@ -803,24 +806,33 @@ std::cerr << " reg " << i << " -> reg " << r2rMap_[i] << "\n"); } -/// Return true if the two specified registers belong to different register -/// classes. The registers may be either phys or virt regs. -bool LiveIntervals::differingRegisterClasses(unsigned RegA, - unsigned RegB) const { +/// Return true if the two specified registers belong to same or compatible +/// register classes. The registers may be either phys or virt regs. +bool LiveIntervals::compatibleRegisterClasses(unsigned RegA, unsigned RegB, + bool &Swap) const { // Get the register classes for the first reg. if (MRegisterInfo::isPhysicalRegister(RegA)) { assert(MRegisterInfo::isVirtualRegister(RegB) && "Shouldn't consider two physregs!"); - return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); + return mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); } // Compare against the regclass for the second reg. - const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA); - if (MRegisterInfo::isVirtualRegister(RegB)) - return RegClass != mf_->getSSARegMap()->getRegClass(RegB); - else - return !RegClass->contains(RegB); + const TargetRegisterClass *RegClassA = mf_->getSSARegMap()->getRegClass(RegA); + if (MRegisterInfo::isVirtualRegister(RegB)) { + const TargetRegisterClass *RegClassB=mf_->getSSARegMap()->getRegClass(RegB); + if (RegClassA == RegClassB) + return true; + else { + if (RegClassB->hasSubRegClass(RegClassA)) { + Swap = true; + return true; + } + return RegClassA->hasSubRegClass(RegClassB); + } + } else + return RegClassA->contains(RegB); } bool LiveIntervals::overlapsAliases(const LiveInterval *LHS, From evan.cheng at apple.com Tue May 9 01:48:24 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:48:24 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-08-CoalesceSubRegClass.ll Message-ID: <200605090648.BAA04490@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-08-CoalesceSubRegClass.ll added (r1.1) --- Log message: Test case for PR770: http://llvm.cs.uiuc.edu/PR770 --- Diffs of the changes: (+22 -0) 2006-05-08-CoalesceSubRegClass.ll | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-05-08-CoalesceSubRegClass.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-05-08-CoalesceSubRegClass.ll:1.1 *** /dev/null Tue May 9 01:48:22 2006 --- llvm/test/Regression/CodeGen/X86/2006-05-08-CoalesceSubRegClass.ll Tue May 9 01:48:12 2006 *************** *** 0 **** --- 1,22 ---- + ; Coalescing from R32 to a subset R32_. Once another register coalescer bug is + ; fixed, the movb should go away as well. + + ; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static | grep 'movl' | wc -l + + %B = external global uint + %C = external global ushort* + + void %test(uint %A) { + %A = cast uint %A to ubyte + %tmp2 = load uint* %B + %tmp3 = and ubyte %A, 16 + %tmp4 = shl uint %tmp2, ubyte %tmp3 + store uint %tmp4, uint* %B + %tmp6 = shr uint %A, ubyte 3 + %tmp = load ushort** %C + %tmp8 = cast ushort* %tmp to uint + %tmp9 = add uint %tmp8, %tmp6 + %tmp9 = cast uint %tmp9 to ushort* + store ushort* %tmp9, ushort** %C + ret void + } From evan.cheng at apple.com Tue May 9 01:54:18 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:54:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200605090654.BAA04537@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.103 -> 1.104 --- Log message: Remove a completed entry. --- Diffs of the changes: (+0 -42) README.txt | 42 ------------------------------------------ 1 files changed, 42 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.103 llvm/lib/Target/X86/README.txt:1.104 --- llvm/lib/Target/X86/README.txt:1.103 Mon May 8 16:39:45 2006 +++ llvm/lib/Target/X86/README.txt Tue May 9 01:54:05 2006 @@ -1126,48 +1126,6 @@ //===---------------------------------------------------------------------===// -This testcase: - -%G1 = weak global <4 x float> zeroinitializer ; <<4 x float>*> [#uses=1] -%G2 = weak global <4 x float> zeroinitializer ; <<4 x float>*> [#uses=1] -%G3 = weak global <4 x float> zeroinitializer ; <<4 x float>*> [#uses=1] -%G4 = weak global <4 x float> zeroinitializer ; <<4 x float>*> [#uses=1] - -implementation ; Functions: - -void %test() { - %tmp = load <4 x float>* %G1 ; <<4 x float>> [#uses=2] - %tmp2 = load <4 x float>* %G2 ; <<4 x float>> [#uses=2] - %tmp135 = shufflevector <4 x float> %tmp, <4 x float> %tmp2, <4 x uint> < uint 0, uint 4, uint 1, uint 5 > ; <<4 x float>> [#uses=1] - store <4 x float> %tmp135, <4 x float>* %G3 - %tmp293 = shufflevector <4 x float> %tmp, <4 x float> %tmp2, <4 x uint> < uint 1, uint undef, uint 3, uint 4 > ; <<4 x float>> [#uses=1] - store <4 x float> %tmp293, <4 x float>* %G4 - ret void -} - -Compiles (llc -march=x86 -mcpu=yonah -relocation-model=static) to: - -_test: - movaps _G2, %xmm0 - movaps _G1, %xmm1 - movaps %xmm1, %xmm2 -2) shufps $3, %xmm0, %xmm2 - movaps %xmm1, %xmm3 -2) shufps $1, %xmm0, %xmm3 -1) unpcklps %xmm0, %xmm1 -2) shufps $128, %xmm2, %xmm3 -1) movaps %xmm1, _G3 - movaps %xmm3, _G4 - ret - -The 1) marked instructions could be scheduled better for reduced register -pressure. The scheduling issue is more pronounced without -static. - -The 2) marked instructions are the lowered form of the 1,undef,3,4 -shufflevector. It seems that there should be a better way to do it :) - -//===---------------------------------------------------------------------===// - If shorter, we should use things like: movzwl %ax, %eax instead of: From evan.cheng at apple.com Tue May 9 01:55:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 01:55:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605090655.BAA04567@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.166 -> 1.167 --- Log message: Debugging info --- Diffs of the changes: (+3 -3) DAGCombiner.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.166 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.167 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.166 Mon May 8 16:18:59 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue May 9 01:55:15 2006 @@ -76,7 +76,7 @@ SDOperand CombineTo(SDNode *N, const std::vector &To) { ++NodesCombined; DEBUG(std::cerr << "\nReplacing "; N->dump(); - std::cerr << "\nWith: "; To[0].Val->dump(); + std::cerr << "\nWith: "; To[0].Val->dump(&DAG); std::cerr << " and " << To.size()-1 << " other values\n"); std::vector NowDead; DAG.ReplaceAllUsesWith(N, To, &NowDead); @@ -128,7 +128,7 @@ // Replace the old value with the new one. ++NodesCombined; DEBUG(std::cerr << "\nReplacing "; TLO.Old.Val->dump(); - std::cerr << "\nWith: "; TLO.New.Val->dump()); + std::cerr << "\nWith: "; TLO.New.Val->dump(&DAG)); std::vector NowDead; DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, NowDead); @@ -577,7 +577,7 @@ // mechanics for us, we have no work to do in this case. if (RV.Val != N) { DEBUG(std::cerr << "\nReplacing "; N->dump(); - std::cerr << "\nWith: "; RV.Val->dump(); + std::cerr << "\nWith: "; RV.Val->dump(&DAG); std::cerr << '\n'); std::vector NowDead; DAG.ReplaceAllUsesWith(N, std::vector(1, RV), &NowDead); From evan.cheng at apple.com Tue May 9 02:13:47 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 02:13:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200605090713.CAA07383@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.55 -> 1.56 --- Log message: Add pseudo dependency to force a def&use operand to be scheduled last (unless the distance between the def and another use is much longer). This is under option control for now "-sched-lower-defnuse". --- Diffs of the changes: (+108 -17) ScheduleDAGList.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 108 insertions(+), 17 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.55 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.56 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.55 Thu May 4 20:47:05 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue May 9 02:13:34 2006 @@ -35,8 +35,8 @@ using namespace llvm; namespace { - cl::opt - SchedVertically("sched-vertically", cl::Hidden); + cl::opt SchedVertically("sched-vertically", cl::Hidden); + cl::opt SchedLowerDefNUse("sched-lower-defnuse", cl::Hidden); } namespace { @@ -198,6 +198,8 @@ /// of scheduled nodes which are not themselves scheduled. std::map > OpenNodes; + /// RegPressureLimits - Keep track of upper limit of register pressure for + /// each register class that allows the scheduler to go into vertical mode. std::map RegPressureLimits; public: @@ -418,7 +420,7 @@ // Build scheduling units. BuildSchedUnits(); - + AvailableQueue->initNodes(SUnits); // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. @@ -917,6 +919,9 @@ void initNodes(const std::vector &sunits) { SUnits = &sunits; + // Add pseudo dependency edges for two-address nodes. + if (SchedLowerDefNUse) + AddPseudoTwoAddrDeps(); // Calculate node priorities. CalculatePriorities(); } @@ -968,6 +973,7 @@ } private: + void AddPseudoTwoAddrDeps(); void CalculatePriorities(); int CalcNodePriority(const SUnit *SU); }; @@ -993,18 +999,20 @@ if (RIsFloater) RBonus += 2; - // Special tie breaker: if two nodes share a operand, the one that use it - // as a def&use operand is preferred. - if (LIsTarget && RIsTarget) { - if (left->isTwoAddress && !right->isTwoAddress) { - SDNode *DUNode = left->Node->getOperand(0).Val; - if (DUNode->isOperand(right->Node)) - LBonus += 2; - } - if (!left->isTwoAddress && right->isTwoAddress) { - SDNode *DUNode = right->Node->getOperand(0).Val; - if (DUNode->isOperand(left->Node)) - RBonus += 2; + if (!SchedLowerDefNUse) { + // Special tie breaker: if two nodes share a operand, the one that use it + // as a def&use operand is preferred. + if (LIsTarget && RIsTarget) { + if (left->isTwoAddress && !right->isTwoAddress) { + SDNode *DUNode = left->Node->getOperand(0).Val; + if (DUNode->isOperand(right->Node)) + LBonus += 2; + } + if (!left->isTwoAddress && right->isTwoAddress) { + SDNode *DUNode = right->Node->getOperand(0).Val; + if (DUNode->isOperand(left->Node)) + RBonus += 2; + } } } @@ -1019,6 +1027,88 @@ return false; } +static inline bool isCopyFromLiveIn(const SUnit *SU) { + SDNode *N = SU->Node; + return N->getOpcode() == ISD::CopyFromReg && + N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag; +} + +// FIXME: This is probably too slow! +static void isReachable(SUnit *SU, SUnit *TargetSU, + std::set &Visited, bool &Reached) { + if (Reached) return; + if (SU == TargetSU) { + Reached = true; + return; + } + if (!Visited.insert(SU).second) return; + + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) + isReachable(I->first, TargetSU, Visited, Reached); +} + +static bool isReachable(SUnit *SU, SUnit *TargetSU) { + std::set Visited; + bool Reached = false; + isReachable(SU, TargetSU, Visited, Reached); + return Reached; +} + +static SUnit *getDefUsePredecessor(SUnit *SU) { + SDNode *DU = SU->Node->getOperand(0).Val; + for (std::set >::iterator + I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (I->second) continue; // ignore chain preds + SUnit *PredSU = I->first; + if (PredSU->Node == DU) + return PredSU; + } + + // Must be flagged. + return NULL; +} + +static bool canClobber(SUnit *SU, SUnit *Op) { + if (SU->isTwoAddress) + return Op == getDefUsePredecessor(SU); + return false; +} + +/// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses +/// it as a def&use operand. Add a pseudo control edge from it to the other +/// node (if it won't create a cycle) so the two-address one will be scheduled +/// first (lower in the schedule). +void RegReductionPriorityQueue::AddPseudoTwoAddrDeps() { + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { + SUnit *SU = (SUnit *)&((*SUnits)[i]); + SDNode *Node = SU->Node; + if (!Node->isTargetOpcode()) + continue; + + if (SU->isTwoAddress) { + unsigned Depth = SU->Node->getNodeDepth(); + SUnit *DUSU = getDefUsePredecessor(SU); + if (!DUSU) continue; + + for (std::set >::iterator I = DUSU->Succs.begin(), + E = DUSU->Succs.end(); I != E; ++I) { + SUnit *SuccSU = I->first; + if (SuccSU != SU && !canClobber(SuccSU, DUSU)) { + if (SuccSU->Node->getNodeDepth() <= Depth+2 && + !isReachable(SuccSU, SU)) { + DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum + << " to SU #" << SuccSU->NodeNum << "\n"); + if (SU->Preds.insert(std::make_pair(SuccSU, true)).second) + SU->NumChainPredsLeft++; + if (SuccSU->Succs.insert(std::make_pair(SU, true)).second) + SuccSU->NumChainSuccsLeft++; + } + } + } + } + } +} /// CalcNodePriority - Priority is the Sethi Ullman number. /// Smaller number is the higher priority. @@ -1036,7 +1126,8 @@ // Give it a small SethiUllman number so it will be scheduled right before its // predecessors that it doesn't lengthen their live ranges. SethiUllmanNumber = INT_MIN + 10; - else if (SU->NumPredsLeft == 0 && Opc != ISD::CopyFromReg) + else if (SU->NumPredsLeft == 0 && + (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU))) SethiUllmanNumber = 1; else { int Extra = 0; @@ -1143,7 +1234,7 @@ Queue.pop(); return V; } - + /// RemoveFromPriorityQueue - This is a really inefficient way to remove a /// node from a priority queue. We should roll our own heap to make this /// better or something. From evan.cheng at apple.com Tue May 9 02:14:12 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 02:14:12 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200605090714.CAA07464@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.210 -> 1.211 --- Log message: Set x86 llcbeta to -sched-lower-defnuse --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.210 llvm-test/Makefile.programs:1.211 --- llvm-test/Makefile.programs:1.210 Thu May 4 14:18:53 2006 +++ llvm-test/Makefile.programs Tue May 9 02:13:59 2006 @@ -197,7 +197,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -sched-vertically +LLCBETAOPTION := -sched-lower-defnuse endif ifeq ($(ARCH),Sparc) LLCBETAOPTION := -enable-sparc-v9-insts From evan.cheng at apple.com Tue May 9 02:20:36 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 02:20:36 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll Message-ID: <200605090720.CAA09995@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-08-InstrSched.ll added (r1.1) --- Log message: Another instruction scheduling test case --- Diffs of the changes: (+22 -0) 2006-05-08-InstrSched.ll | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.1 *** /dev/null Tue May 9 02:20:34 2006 --- llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll Tue May 9 02:20:24 2006 *************** *** 0 **** --- 1,22 ---- + ; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static -sched-lower-defnuse | not grep 'xorb $16, %cl' + + %A = external global ushort* + %B = external global uint + %C = external global uint + + void %test() { + %tmp = load ushort** %A + %tmp1 = getelementptr ushort* %tmp, int 1 + %tmp = load ushort* %tmp1 + %tmp3 = cast ushort %tmp to uint + %tmp = load uint* %B + %tmp4 = and uint %tmp, 16 + %tmp5 = load uint* %C + %tmp6 = cast uint %tmp4 to ubyte + %tmp7 = shl uint %tmp5, ubyte %tmp6 + %tmp9 = xor ubyte %tmp6, 16 + %tmp11 = shr uint %tmp3, ubyte %tmp9 + %tmp12 = or uint %tmp11, %tmp7 + store uint %tmp12, uint* %C + ret void + } From lattner at cs.uiuc.edu Tue May 9 11:15:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 11:15:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200605091615.LAA16723@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.173 -> 1.174 --- Log message: Indent .data/.text in the .s file --- Diffs of the changes: (+5 -5) PPCAsmPrinter.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.173 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.174 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.173 Mon May 8 23:59:56 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue May 9 11:15:00 2006 @@ -511,10 +511,10 @@ switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); case Function::InternalLinkage: // Symbols default to internal. - SwitchToTextSection(".text", F); + SwitchToTextSection("\t.text", F); break; case Function::ExternalLinkage: - SwitchToTextSection(".text", F); + SwitchToTextSection("\t.text", F); O << "\t.globl\t" << CurrentFnName << "\n"; break; case Function::WeakLinkage: @@ -595,10 +595,10 @@ O << "\t.zerofill __DATA, __common, " << name << ", " << Size << ", " << Align; } else if (I->hasInternalLinkage()) { - SwitchToDataSection(".data", I); + SwitchToDataSection("\t.data", I); O << LCOMMDirective << name << "," << Size << "," << Align; } else { - SwitchToDataSection(".data", I); + SwitchToDataSection("\t.data", I); O << ".comm " << name << "," << Size; } O << "\t\t; '" << I->getName() << "'\n"; @@ -618,7 +618,7 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchToDataSection(".data", I); + SwitchToDataSection("\t.data", I); break; default: std::cerr << "Unknown linkage type!"; From lattner at cs.uiuc.edu Tue May 9 11:42:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 11:42:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605091642.LAA16864@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.75 -> 1.76 --- Log message: Fix a regression in my patch from last night that broke the llvmgcc4 build on ppc --- Diffs of the changes: (+1 -1) AsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.75 llvm/lib/CodeGen/AsmPrinter.cpp:1.76 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.75 Tue May 9 00:33:48 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue May 9 11:41:59 2006 @@ -68,7 +68,7 @@ const GlobalValue *GV) { std::string NS; if (GV && GV->hasSection()) - NS = GV->getSection(); + NS = SwitchToSectionDirective + GV->getSection(); else NS = NewSection; From lattner at cs.uiuc.edu Tue May 9 12:29:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 12:29:29 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Instruction.h Message-ID: <200605091729.MAA17295@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Instruction.h updated: 1.70 -> 1.71 --- Log message: This method doesn't need to be virtual, thanks to Reid for pointing this out. --- Diffs of the changes: (+1 -1) Instruction.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Instruction.h diff -u llvm/include/llvm/Instruction.h:1.70 llvm/include/llvm/Instruction.h:1.71 --- llvm/include/llvm/Instruction.h:1.70 Fri Dec 16 18:19:22 2005 +++ llvm/include/llvm/Instruction.h Tue May 9 12:29:17 2006 @@ -106,7 +106,7 @@ /// one of the enums that is coming soon (down below)... /// unsigned getOpcode() const { return getValueType() - InstructionVal; } - virtual const char *getOpcodeName() const { + const char *getOpcodeName() const { return getOpcodeName(getOpcode()); } static const char* getOpcodeName(unsigned OpCode); From natebegeman at mac.com Tue May 9 13:21:05 2006 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 9 May 2006 13:21:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200605091821.NAA17934@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.371 -> 1.372 --- Log message: Fix PR773: http://llvm.cs.uiuc.edu/PR773 --- Diffs of the changes: (+20 -2) LegalizeDAG.cpp | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.371 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.372 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.371 Tue May 2 20:29:56 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue May 9 13:20:51 2006 @@ -3071,8 +3071,26 @@ case ISD::FREM: case ISD::FCOPYSIGN: // These operators require that their input be fp extended. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = PromoteOp(Node->getOperand(1)); + switch (getTypeAction(Node->getOperand(0).getValueType())) { + case Legal: + Tmp1 = LegalizeOp(Node->getOperand(0)); + break; + case Promote: + Tmp1 = PromoteOp(Node->getOperand(0)); + break; + case Expand: + assert(0 && "not implemented"); + } + switch (getTypeAction(Node->getOperand(1).getValueType())) { + case Legal: + Tmp2 = LegalizeOp(Node->getOperand(1)); + break; + case Promote: + Tmp2 = PromoteOp(Node->getOperand(1)); + break; + case Expand: + assert(0 && "not implemented"); + } Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); // Perform FP_ROUND: this is probably overly pessimistic. From evan.cheng at apple.com Tue May 9 19:05:59 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 19:05:59 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200605100005.TAA20724@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.199 -> 1.200 --- Log message: Fix a load folding bug. It is exposed by a multi- resulting instructions def : Pat<> pattern. --- Diffs of the changes: (+62 -58) DAGISelEmitter.cpp | 120 +++++++++++++++++++++++++++-------------------------- 1 files changed, 62 insertions(+), 58 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.199 llvm/utils/TableGen/DAGISelEmitter.cpp:1.200 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.199 Fri Apr 28 13:54:11 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue May 9 19:05:46 2006 @@ -2445,22 +2445,27 @@ const CodeGenTarget &CGT = ISE.getTargetInfo(); CodeGenInstruction &II = CGT.getInstruction(Op->getName()); const DAGInstruction &Inst = ISE.getInstruction(Op); - bool HasImpInputs = Inst.getNumImpOperands() > 0; - bool HasImpResults = Inst.getNumImpResults() > 0; - bool HasOptInFlag = isRoot && + TreePattern *InstPat = Inst.getPattern(); + TreePatternNode *InstPatNode = + isRoot ? (InstPat ? InstPat->getOnlyTree() : Pattern) + : (InstPat ? InstPat->getOnlyTree() : NULL); + if (InstPatNode && InstPatNode->getOperator()->getName() == "set") { + InstPatNode = InstPatNode->getChild(1); + } + bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0; + bool HasImpResults = isRoot && Inst.getNumImpResults() > 0; + bool NodeHasOptInFlag = isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPOptInFlag, ISE); - bool HasInFlag = isRoot && + bool NodeHasInFlag = isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPInFlag, ISE); - bool NodeHasOutFlag = HasImpResults || - (isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE)); - bool NodeHasChain = - NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE); - bool HasChain = II.hasCtrlDep || - (isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE)); + bool NodeHasOutFlag = HasImpResults || (isRoot && + PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE)); + bool NodeHasChain = InstPatNode && + PatternHasProperty(InstPatNode, SDNodeInfo::SDNPHasChain, ISE); - if (HasInFlag || NodeHasOutFlag || HasOptInFlag || HasImpInputs) + if (NodeHasInFlag || NodeHasOutFlag || NodeHasOptInFlag || HasImpInputs) emitDecl("InFlag"); - if (HasOptInFlag) + if (NodeHasOptInFlag) emitCode("bool HasOptInFlag = false;"); // How many results is this pattern expected to produce? @@ -2518,41 +2523,23 @@ } // Emit all the chain and CopyToReg stuff. - bool ChainEmitted = HasChain; - if (HasChain) + bool ChainEmitted = NodeHasChain; + if (NodeHasChain) emitCode("Select(" + ChainName + ", " + ChainName + ");"); - if (HasInFlag || HasOptInFlag || HasImpInputs) + if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs) EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true); - // The operands have been selected. Remove them from InFlightSet. - for (std::vector::iterator AI = InflightNodes.begin(), - AE = InflightNodes.end(); AI != AE; ++AI) - emitCode("InFlightSet.erase(" + *AI + ".Val);"); + if (isRoot) { + // The operands have been selected. Remove them from InFlightSet. + for (std::vector::iterator AI = InflightNodes.begin(), + AE = InflightNodes.end(); AI != AE; ++AI) + emitCode("InFlightSet.erase(" + *AI + ".Val);"); + } + unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; - if (!isRoot) { - emitDecl("Tmp" + utostr(ResNo)); - std::string Code = - "Tmp" + utostr(ResNo) + " = SDOperand(CurDAG->getTargetNode(" + - II.Namespace + "::" + II.TheDef->getName(); - if (N->getTypeNum(0) != MVT::isVoid) - Code += ", MVT::" + getEnumName(N->getTypeNum(0)); - if (NodeHasOutFlag) - Code += ", MVT::Flag"; - - unsigned LastOp = 0; - for (unsigned i = 0, e = Ops.size(); i != e; ++i) { - LastOp = Ops[i]; - Code += ", Tmp" + utostr(LastOp); - } - emitCode(Code + "), 0);"); - if (HasChain) { - // Must have at least one result - emitCode(ChainName + " = Tmp" + utostr(LastOp) + ".getValue(" + - utostr(NumResults) + ");"); - } - } else if (HasChain || NodeHasOutFlag) { - if (HasOptInFlag) { + if (!isRoot || NodeHasChain || NodeHasOutFlag || NodeHasOptInFlag) { + if (NodeHasOptInFlag) { unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren(); emitDecl("ResNode", true); emitCode("if (HasOptInFlag)"); @@ -2565,7 +2552,7 @@ if (N->getTypeNum(0) != MVT::isVoid) Code += ", MVT::" + getEnumName(N->getTypeNum(0)); } - if (HasChain) + if (NodeHasChain) Code += ", MVT::Other"; if (NodeHasOutFlag) Code += ", MVT::Flag"; @@ -2573,7 +2560,7 @@ // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasChain) Code += ", " + ChainName; + if (NodeHasChain) Code += ", " + ChainName; emitCode(Code + ", InFlag);"); emitCode("else"); @@ -2584,7 +2571,7 @@ // Result types. if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) Code += ", MVT::" + getEnumName(N->getTypeNum(0)); - if (HasChain) + if (NodeHasChain) Code += ", MVT::Other"; if (NodeHasOutFlag) Code += ", MVT::Flag"; @@ -2592,18 +2579,27 @@ // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasChain) Code += ", " + ChainName + ");"; + if (NodeHasChain) Code += ", " + ChainName + ");"; emitCode(Code); } else { - emitDecl("ResNode", true); - std::string Code = "ResNode = CurDAG->getTargetNode(" + + std::string Code; + if (!isRoot) { + std::string NodeName = "Tmp" + utostr(ResNo); + emitDecl(NodeName); + Code = NodeName + " = SDOperand("; + } else { + std::string NodeName = "ResNode"; + emitDecl(NodeName, true); + Code = NodeName + " = "; + } + Code += "CurDAG->getTargetNode(" + II.Namespace + "::" + II.TheDef->getName(); // Output order: results, chain, flags // Result types. if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) Code += ", MVT::" + getEnumName(N->getTypeNum(0)); - if (HasChain) + if (NodeHasChain) Code += ", MVT::Other"; if (NodeHasOutFlag) Code += ", MVT::Flag"; @@ -2611,11 +2607,17 @@ // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasChain) Code += ", " + ChainName; - if (HasInFlag || HasImpInputs) Code += ", InFlag"; - emitCode(Code + ");"); + if (NodeHasChain) Code += ", " + ChainName; + if (NodeHasInFlag || HasImpInputs) Code += ", InFlag"; + if (!isRoot) + emitCode(Code + "), 0);"); + else + emitCode(Code + ");"); } + if (!isRoot) + return std::make_pair(1, ResNo); + if (NewTF) emitCode("if (OldTF) " "SelectionDAG::InsertISelMapEntry(CodeGenMap, OldTF, 0, " + @@ -2627,7 +2629,7 @@ if (NodeHasOutFlag) emitCode("InFlag = SDOperand(ResNode, " + - utostr(NumResults + (unsigned)HasChain) + ");"); + utostr(NumResults + (unsigned)NodeHasChain) + ");"); if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) { emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " @@ -2635,7 +2637,9 @@ NumResults = 1; } - if (NodeHasChain) { + bool InputHasChain = + NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE); + if (InputHasChain) { emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + utostr(PatResults) + ", ResNode, " + utostr(NumResults) + ");"); @@ -2664,11 +2668,11 @@ if (NodeHasOutFlag) emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(PatResults + (unsigned)NodeHasChain) + + utostr(PatResults + (unsigned)InputHasChain) + ", InFlag.Val, InFlag.ResNo);"); // User does not expect the instruction would produce a chain! - bool AddedChain = HasChain && !NodeHasChain; + bool AddedChain = NodeHasChain && !InputHasChain; if (AddedChain && NodeHasOutFlag) { if (PatResults == 0) { emitCode("Result = SDOperand(ResNode, N.ResNo+1);"); @@ -2693,7 +2697,7 @@ Code += ", MVT::Flag"; for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasInFlag || HasImpInputs) + if (NodeHasInFlag || HasImpInputs) Code += ", InFlag"; emitCode(Code + ");"); emitCode("} else {"); @@ -2706,7 +2710,7 @@ Code += ", MVT::Flag"; for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasInFlag || HasImpInputs) + if (NodeHasInFlag || HasImpInputs) Code += ", InFlag"; emitCode(Code + ");"); emitCode(" SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, " From evan.cheng at apple.com Tue May 9 21:48:10 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 9 May 2006 21:48:10 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200605100248.VAA21312@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.200 -> 1.201 --- Log message: Watch out for the following case: 1. Use expects a chain output. 2. Node is expanded into multiple target ops. 3. One of the inner node produces a chain, the outer most one doesn't. --- Diffs of the changes: (+37 -11) DAGISelEmitter.cpp | 48 +++++++++++++++++++++++++++++++++++++----------- 1 files changed, 37 insertions(+), 11 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.200 llvm/utils/TableGen/DAGISelEmitter.cpp:1.201 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.200 Tue May 9 19:05:46 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue May 9 21:47:57 2006 @@ -2462,6 +2462,8 @@ PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE)); bool NodeHasChain = InstPatNode && PatternHasProperty(InstPatNode, SDNodeInfo::SDNPHasChain, ISE); + bool InputHasChain = isRoot && + NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE); if (NodeHasInFlag || NodeHasOutFlag || NodeHasOptInFlag || HasImpInputs) emitDecl("InFlag"); @@ -2538,7 +2540,8 @@ unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; - if (!isRoot || NodeHasChain || NodeHasOutFlag || NodeHasOptInFlag) { + if (!isRoot || InputHasChain || NodeHasChain || NodeHasOutFlag || + NodeHasOptInFlag) { if (NodeHasOptInFlag) { unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren(); emitDecl("ResNode", true); @@ -2548,7 +2551,7 @@ // Output order: results, chain, flags // Result types. - if (NumResults > 0) { + if (PatResults > 0) { if (N->getTypeNum(0) != MVT::isVoid) Code += ", MVT::" + getEnumName(N->getTypeNum(0)); } @@ -2569,7 +2572,7 @@ // Output order: results, chain, flags // Result types. - if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) + if (PatResults > 0 && N->getTypeNum(0) != MVT::isVoid) Code += ", MVT::" + getEnumName(N->getTypeNum(0)); if (NodeHasChain) Code += ", MVT::Other"; @@ -2581,14 +2584,20 @@ Code += ", Tmp" + utostr(Ops[i]); if (NodeHasChain) Code += ", " + ChainName + ");"; emitCode(Code); + + if (NodeHasChain) + // Remember which op produces the chain. + emitCode(ChainName + " = SDOperand(ResNode" + + ", " + utostr(PatResults) + ");"); } else { std::string Code; + std::string NodeName; if (!isRoot) { - std::string NodeName = "Tmp" + utostr(ResNo); + NodeName = "Tmp" + utostr(ResNo); emitDecl(NodeName); Code = NodeName + " = SDOperand("; } else { - std::string NodeName = "ResNode"; + NodeName = "ResNode"; emitDecl(NodeName, true); Code = NodeName + " = "; } @@ -2613,6 +2622,15 @@ emitCode(Code + "), 0);"); else emitCode(Code + ");"); + + if (NodeHasChain) + // Remember which op produces the chain. + if (!isRoot) + emitCode(ChainName + " = SDOperand(" + NodeName + + ".Val, " + utostr(PatResults) + ");"); + else + emitCode(ChainName + " = SDOperand(" + NodeName + + ", " + utostr(PatResults) + ");"); } if (!isRoot) @@ -2637,16 +2655,14 @@ NumResults = 1; } - bool InputHasChain = - NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE); if (InputHasChain) { emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(PatResults) + ", ResNode, " + - utostr(NumResults) + ");"); + utostr(PatResults) + ", " + ChainName + ".Val, " + + ChainName + ".ResNo" + ");"); if (DoReplace) emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " + - utostr(PatResults) + ", " + "ResNode, " + - utostr(NumResults) + ");"); + utostr(PatResults) + ", " + ChainName + ".Val, " + + ChainName + ".ResNo" + ");"); } if (FoldedChains.size() > 0) { @@ -2682,6 +2698,16 @@ emitCode("else"); emitCode(" Result = SDOperand(ResNode, N.ResNo+1);"); } + } else if (InputHasChain && !NodeHasChain) { + // One of the inner node produces a chain. + emitCode("if (N.ResNo < " + utostr(PatResults) + ")"); + emitCode(" Result = SDOperand(ResNode, N.ResNo);"); + if (NodeHasOutFlag) { + emitCode("else if (N.ResNo > " + utostr(PatResults) + ")"); + emitCode(" Result = SDOperand(ResNode, N.ResNo-1);"); + } + emitCode("else"); + emitCode(" Result = SDOperand(" + ChainName + ".Val, " + ChainName + ".ResNo);"); } else { emitCode("Result = SDOperand(ResNode, N.ResNo);"); } From lattner at cs.uiuc.edu Tue May 9 22:53:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 22:53:51 -0500 Subject: [llvm-commits] CVS: llvm-www/OpenProjects.html Message-ID: <200605100353.WAA21722@zion.cs.uiuc.edu> Changes in directory llvm-www: OpenProjects.html updated: 1.13 -> 1.14 --- Log message: Add a new open project --- Diffs of the changes: (+21 -10) OpenProjects.html | 31 +++++++++++++++++++++---------- 1 files changed, 21 insertions(+), 10 deletions(-) Index: llvm-www/OpenProjects.html diff -u llvm-www/OpenProjects.html:1.13 llvm-www/OpenProjects.html:1.14 --- llvm-www/OpenProjects.html:1.13 Tue Apr 11 23:18:36 2006 +++ llvm-www/OpenProjects.html Tue May 9 22:53:37 2006 @@ -7,8 +7,8 @@
  • Improving the current system
    1. Implementing Code Cleanup bugs
    2. -
    3. Port glibc to LLVM
    4. Compile programs with the LLVM Compiler
    5. +
    6. Add programs to the llvm-test suite
    7. Extend the LLVM intermediate representation
    8. Benchmark the LLVM compiler
    9. Miscellaneous Improvements
    10. @@ -92,18 +92,29 @@
      -

      It would be very useful to port glibc to LLVM. This would allow a -variety of interprocedural algorithms to be much more effective in the face of -library calls. The most important pieces to port are things like the string -library and the stdio related functions... low-level system calls like -'read' should stay unimplemented in LLVM.

      +

      +The llvm-test testsuite is +a large collection of programs we use for nightly testing of generated code +performance, compile times, correctness, etc. Having a large testsuite gives +us a lot of coverage of programs and enables us to spot and improve any +problem areas in the compiler.

      + +

      +One extremely useful task, which does not require in-depth knowledge of +compilers, would be to extend our testsuite to include new programs and benchmarks. +In particular, we are interested in cpu-intensive programs that have few +library dependencies, produce some output that can be used for correctness +testing, and that are redistributable in source form. Many different programs +are suitable, for example, see this list for some +potential candidates. +

      @@ -365,7 +376,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
      - Last modified: $Date: 2006/04/12 04:18:36 $ + Last modified: $Date: 2006/05/10 03:53:37 $ From lattner at cs.uiuc.edu Tue May 9 22:55:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 22:55:27 -0500 Subject: [llvm-commits] CVS: llvm-www/OpenProjects.html Message-ID: <200605100355.WAA21750@zion.cs.uiuc.edu> Changes in directory llvm-www: OpenProjects.html updated: 1.14 -> 1.15 --- Log message: fine tune an entry --- Diffs of the changes: (+2 -4) OpenProjects.html | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) Index: llvm-www/OpenProjects.html diff -u llvm-www/OpenProjects.html:1.14 llvm-www/OpenProjects.html:1.15 --- llvm-www/OpenProjects.html:1.14 Tue May 9 22:53:37 2006 +++ llvm-www/OpenProjects.html Tue May 9 22:55:15 2006 @@ -340,9 +340,7 @@ output LLVM bytecode. It seems that it can already output .NET bytecode, JVM bytecode, and C, so LLVM would ostensibly be another good candidate. -
    11. Write a new frontend for C/C++ in C++, giving us the ability to -directly use LLVM C++ classes from within a compiler rather than use -C-based wrapper functions a la llvm-gcc. Possible starting points: +
    12. Write a new frontend for C/C++ that isn't GCC based. Possible starting points:
      • Elsa C++ parser, written in C++ and built with a Generalized LR parser @@ -376,7 +374,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
        - Last modified: $Date: 2006/05/10 03:53:37 $ + Last modified: $Date: 2006/05/10 03:55:15 $ From lattner at cs.uiuc.edu Tue May 9 23:32:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 23:32:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Instructions.cpp Message-ID: <200605100432.XAA22069@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Instructions.cpp updated: 1.36 -> 1.37 --- Log message: Add an assertion for a common error --- Diffs of the changes: (+4 -1) Instructions.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.36 llvm/lib/VMCore/Instructions.cpp:1.37 --- llvm/lib/VMCore/Instructions.cpp:1.36 Tue May 2 19:48:22 2006 +++ llvm/lib/VMCore/Instructions.cpp Tue May 9 23:32:43 2006 @@ -505,9 +505,12 @@ static Value *getAISize(Value *Amt) { if (!Amt) Amt = ConstantUInt::get(Type::UIntTy, 1); - else + else { + assert(!isa(Amt) && + "Passed basic block into allocation size parameter! Ue other ctor"); assert(Amt->getType() == Type::UIntTy && "Malloc/Allocation array size != UIntTy!"); + } return Amt; } From lattner at cs.uiuc.edu Tue May 9 23:38:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 9 May 2006 23:38:48 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Instructions.h Message-ID: <200605100438.XAA22137@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Instructions.h updated: 1.34 -> 1.35 --- Log message: Add alloca/malloc ctors that don't take array sizes. --- Diffs of the changes: (+21 -8) Instructions.h | 29 +++++++++++++++++++++-------- 1 files changed, 21 insertions(+), 8 deletions(-) Index: llvm/include/llvm/Instructions.h diff -u llvm/include/llvm/Instructions.h:1.34 llvm/include/llvm/Instructions.h:1.35 --- llvm/include/llvm/Instructions.h:1.34 Fri Apr 14 17:20:07 2006 +++ llvm/include/llvm/Instructions.h Tue May 9 23:38:35 2006 @@ -104,13 +104,20 @@ MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name, BasicBlock *InsertAtEnd) : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertAtEnd) {} + + explicit MallocInst(const Type *Ty, const std::string &Name, + Instruction *InsertBefore = 0) + : AllocationInst(Ty, 0, Malloc, 0, Name, InsertBefore) {} + MallocInst(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) + : AllocationInst(Ty, 0, Malloc, 0, Name, InsertAtEnd) {} + MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertAtEnd) {} - explicit MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, + : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertAtEnd) {} + MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, const std::string &Name = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertBefore) {} virtual MallocInst *clone() const; @@ -141,13 +148,19 @@ AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name, BasicBlock *InsertAtEnd) : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertAtEnd) {} + + AllocaInst(const Type *Ty, const std::string &Name, + Instruction *InsertBefore = 0) + : AllocationInst(Ty, 0, Alloca, 0, Name, InsertBefore) {} + AllocaInst(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) + : AllocationInst(Ty, 0, Alloca, 0, Name, InsertAtEnd) {} + + AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, + const std::string &Name = "", Instruction *InsertBefore = 0) + : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertBefore) {} AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertAtEnd) {} - explicit AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, - const std::string &Name = "", - Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertAtEnd) {} virtual AllocaInst *clone() const; From evan.cheng at apple.com Wed May 10 01:16:57 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 May 2006 01:16:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200605100616.BAA22740@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.56 -> 1.57 --- Log message: Templatify RegReductionPriorityQueue --- Diffs of the changes: (+12 -7) ScheduleDAGList.cpp | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.56 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.57 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.56 Tue May 9 02:13:34 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Wed May 10 01:16:44 2006 @@ -892,12 +892,13 @@ // to reduce register pressure. // namespace { + template class RegReductionPriorityQueue; /// Sorting functions for the Available queue. struct ls_rr_sort : public std::binary_function { - RegReductionPriorityQueue *SPQ; - ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} + RegReductionPriorityQueue *SPQ; + ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} bool operator()(const SUnit* left, const SUnit* right) const; @@ -905,6 +906,7 @@ } // end anonymous namespace namespace { + template class RegReductionPriorityQueue : public SchedulingPriorityQueue { // SUnits - The SUnits for the current graph. const std::vector *SUnits; @@ -912,7 +914,7 @@ // SethiUllmanNumbers - The SethiUllman number for each node. std::vector SethiUllmanNumbers; - std::priority_queue, ls_rr_sort> Queue; + std::priority_queue, SF> Queue; public: RegReductionPriorityQueue() : Queue(ls_rr_sort(this)) {} @@ -1079,7 +1081,8 @@ /// it as a def&use operand. Add a pseudo control edge from it to the other /// node (if it won't create a cycle) so the two-address one will be scheduled /// first (lower in the schedule). -void RegReductionPriorityQueue::AddPseudoTwoAddrDeps() { +template +void RegReductionPriorityQueue::AddPseudoTwoAddrDeps() { for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { SUnit *SU = (SUnit *)&((*SUnits)[i]); SDNode *Node = SU->Node; @@ -1112,7 +1115,8 @@ /// CalcNodePriority - Priority is the Sethi Ullman number. /// Smaller number is the higher priority. -int RegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) { +template +int RegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) { int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; if (SethiUllmanNumber != 0) return SethiUllmanNumber; @@ -1150,7 +1154,8 @@ } /// CalculatePriorities - Calculate priorities of all scheduling units. -void RegReductionPriorityQueue::CalculatePriorities() { +template +void RegReductionPriorityQueue::CalculatePriorities() { SethiUllmanNumbers.assign(SUnits->size(), 0); for (unsigned i = 0, e = SUnits->size(); i != e; ++i) @@ -1386,7 +1391,7 @@ llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB) { return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, - new RegReductionPriorityQueue(), + new RegReductionPriorityQueue(), new HazardRecognizer()); } From lattner at cs.uiuc.edu Wed May 10 01:38:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 May 2006 01:38:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Message-ID: <200605100638.BAA22865@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCRegisterInfo.cpp updated: 1.65 -> 1.66 --- Log message: Fix the PowerPC JIT-only failure on UnitTests/Vector/sumarray-dbl, which is really a bad codegen bug that LLC happens to get lucky with. I must chat with Nate for the proper fix. --- Diffs of the changes: (+2 -2) PPCRegisterInfo.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.65 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.66 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.65 Thu May 4 12:52:23 2006 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Wed May 10 01:38:32 2006 @@ -506,11 +506,11 @@ // If there is a preferred stack alignment, align R1 now if (MaxAlign > TargetAlign) { assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767 && "Invalid alignment!"); - assert(isInt16(MaxAlign-NumBytes) && "Unhandled stack size and alignment!"); + assert(isInt16(0-NumBytes) && "Unhandled stack size and alignment!"); BuildMI(MBB, MBBI, PPC::RLWINM, 4, PPC::R0) .addReg(PPC::R1).addImm(0).addImm(32-Log2_32(MaxAlign)).addImm(31); BuildMI(MBB, MBBI, PPC::SUBFIC,2,PPC::R0).addReg(PPC::R0) - .addImm(MaxAlign-NumBytes); + .addImm(0-NumBytes); BuildMI(MBB, MBBI, PPC::STWUX, 3) .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); } else if (NumBytes <= 32768) { From lattner at cs.uiuc.edu Wed May 10 13:56:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 May 2006 13:56:17 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/deadcode.ll Message-ID: <200605101856.NAA05504@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: deadcode.ll added (r1.1) --- Log message: New testcase, check that dead code doesn't pessimize instcombine --- Diffs of the changes: (+12 -0) deadcode.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/deadcode.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/deadcode.ll:1.1 *** /dev/null Wed May 10 13:56:14 2006 --- llvm/test/Regression/Transforms/InstCombine/deadcode.ll Wed May 10 13:56:04 2006 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 'ret int %A' + + int %test(int %A) { + %X = or bool false, false + br bool %X, label %T, label %C + T: + %B = add int %A, 1 + br label %C + C: + %C = phi int [%B, %T], [%A, %0] + ret int %C + } From lattner at cs.uiuc.edu Wed May 10 14:00:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 10 May 2006 14:00:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605101900.OAA05551@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.477 -> 1.478 --- Log message: Two changes: 1. Implement InstCombine/deadcode.ll by not adding instructions in unreachable blocks (due to constants in conditional branches/switches) to the worklist. This causes them to be deleted before instcombine starts up, leading to better optimization. 2. In the prepass over instructions, do trivial constprop/dce as we go. This has the effect of improving the effectiveness of #1. In addition, it *significantly* speeds up instcombine on test cases with large amounts of constant folding code (for example, that produced by code specialization or partial evaluation). In one example, it speeds up instcombine from 0.0589s to 0.0224s with a release build (a 2.6x speedup). --- Diffs of the changes: (+72 -7) InstructionCombining.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 72 insertions(+), 7 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.477 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.477 Sat May 6 04:00:16 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed May 10 14:00:36 2006 @@ -48,7 +48,6 @@ #include "llvm/Support/InstVisitor.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/PatternMatch.h" -#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include @@ -7318,17 +7317,83 @@ return true; } + +/// AddReachableCodeToWorklist - Walk the function in depth-first order, adding +/// all reachable code to the worklist. +/// +/// This has a couple of tricks to make the code faster and more powerful. In +/// particular, we constant fold and DCE instructions as we go, to avoid adding +/// them to the worklist (this significantly speeds up instcombine on code where +/// many instructions are dead or constant). Additionally, if we find a branch +/// whose condition is a known constant, we only visit the reachable successors. +/// +static void AddReachableCodeToWorklist(BasicBlock *BB, + std::set &Visited, + std::vector &WorkList) { + // We have now visited this block! If we've already been here, bail out. + if (!Visited.insert(BB).second) return; + + for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) { + Instruction *Inst = BBI++; + + // DCE instruction if trivially dead. + if (isInstructionTriviallyDead(Inst)) { + ++NumDeadInst; + DEBUG(std::cerr << "IC: DCE: " << *Inst); + Inst->eraseFromParent(); + continue; + } + + // ConstantProp instruction if trivially constant. + if (Constant *C = ConstantFoldInstruction(Inst)) { + DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *Inst); + Inst->replaceAllUsesWith(C); + ++NumConstProp; + Inst->eraseFromParent(); + continue; + } + + WorkList.push_back(Inst); + } + + // Recursively visit successors. If this is a branch or switch on a constant, + // only visit the reachable successor. + TerminatorInst *TI = BB->getTerminator(); + if (BranchInst *BI = dyn_cast(TI)) { + if (BI->isConditional() && isa(BI->getCondition())) { + bool CondVal = cast(BI->getCondition())->getValue(); + AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList); + return; + } + } else if (SwitchInst *SI = dyn_cast(TI)) { + if (ConstantInt *Cond = dyn_cast(SI->getCondition())) { + // See if this is an explicit destination. + for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) + if (SI->getCaseValue(i) == Cond) { + AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList); + return; + } + + // Otherwise it is the default destination. + AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList); + return; + } + } + + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) + AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList); +} + bool InstCombiner::runOnFunction(Function &F) { bool Changed = false; TD = &getAnalysis(); { - // Populate the worklist with the reachable instructions. + // Do a depth-first traversal of the function, populate the worklist with + // the reachable instructions. Ignore blocks that are not reachable. Keep + // track of which blocks we visit. std::set Visited; - for (df_ext_iterator BB = df_ext_begin(&F.front(), Visited), - E = df_ext_end(&F.front(), Visited); BB != E; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - WorkList.push_back(I); + AddReachableCodeToWorklist(F.begin(), Visited, WorkList); // Do a quick scan over the function. If we find any blocks that are // unreachable, remove any instructions inside of them. This prevents @@ -7397,7 +7462,7 @@ ReplaceInstUsesWith(*I, C); ++NumConstProp; - I->getParent()->getInstList().erase(I); + I->eraseFromParent(); removeFromWorkList(I); continue; } From evan.cheng at apple.com Wed May 10 14:53:18 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 May 2006 14:53:18 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll Message-ID: <200605101953.OAA05818@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-08-InstrSched.ll updated: 1.1 -> 1.2 --- Log message: Update test case --- Diffs of the changes: (+1 -0) 2006-05-08-InstrSched.ll | 1 + 1 files changed, 1 insertion(+) Index: llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll diff -u llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.1 llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.2 --- llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.1 Tue May 9 02:20:24 2006 +++ llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll Wed May 10 14:53:05 2006 @@ -1,3 +1,4 @@ +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static -sched-lower-defnuse && ; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static -sched-lower-defnuse | not grep 'xorb $16, %cl' %A = external global ushort* From evan.cheng at apple.com Wed May 10 17:30:54 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 10 May 2006 17:30:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200605102230.RAA06951@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.120 -> 1.121 --- Log message: If the live interval legnth is essentially zero, i.e. in every live range the use follows def immediately, it doesn't make sense to spill it and hope it will be easier to allocate for this LI. --- Diffs of the changes: (+15 -1) RegAllocLinearScan.cpp | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.120 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.121 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.120 Sat Mar 25 17:00:56 2006 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Wed May 10 17:30:41 2006 @@ -406,6 +406,14 @@ } } +static bool isZeroLengthInterval(LiveInterval *li) { + for (LiveInterval::Ranges::const_iterator + i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i) + if (i->end - i->start > LiveIntervals::InstrSlots::NUM) + return false; + return true; +} + /// assignRegOrStackSlotAtInterval - assign a register if one is available, or /// spill. @@ -557,10 +565,16 @@ DEBUG(std::cerr << "\t\tregister with min weight: " << mri_->getName(minReg) << " (" << minWeight << ")\n"); + // If the live interval legnth is essentially zero, i.e. in every live range + // the use follows def immediately, it doesn't make sense to spill it and + // hope it will be easier to allocate for this li. + if (isZeroLengthInterval(cur)) + DEBUG(std::cerr << "\t\tavoid spilling zero length live interval: " + << *cur << '\n';); // if the current has the minimum weight, we need to spill it and // add any added intervals back to unhandled, and restart // linearscan. - if (cur->weight <= minWeight) { + else if (cur->weight <= minWeight) { DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';); int slot = vrm_->assignVirt2StackSlot(cur->reg); std::vector added = From resistor at mac.com Wed May 10 22:10:27 2006 From: resistor at mac.com (Owen Anderson) Date: Wed, 10 May 2006 22:10:27 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200605110310.WAA08436@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.365 -> 1.366 --- Log message: Fix some problems linking stuff in libTarget. --- Diffs of the changes: (+1 -1) Makefile.rules | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.365 llvm/Makefile.rules:1.366 --- llvm/Makefile.rules:1.365 Thu Apr 20 13:42:24 2006 +++ llvm/Makefile.rules Wed May 10 22:10:15 2006 @@ -629,7 +629,7 @@ endif LLVMLIBS := $(JIT_LIBS) LLVMScalarOpts.a LLVMTransformUtils.a LLVMAnalysis.a \ - LLVMBCReader LLVMCore LLVMSupport.a LLVMTarget.a LLVMbzip2 \ + LLVMBCReader LLVMTarget.a LLVMCore LLVMSupport.a LLVMbzip2 \ LLVMSystem.a $(PLATFORMLIBDL) endif From evan.cheng at apple.com Thu May 11 02:28:30 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 02:28:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200605110728.CAA18341@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.121 -> 1.122 --- Log message: Backing out previous check-in. --- Diffs of the changes: (+1 -16) RegAllocLinearScan.cpp | 17 +---------------- 1 files changed, 1 insertion(+), 16 deletions(-) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.121 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.122 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.121 Wed May 10 17:30:41 2006 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Thu May 11 02:28:16 2006 @@ -406,15 +406,6 @@ } } -static bool isZeroLengthInterval(LiveInterval *li) { - for (LiveInterval::Ranges::const_iterator - i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i) - if (i->end - i->start > LiveIntervals::InstrSlots::NUM) - return false; - return true; -} - - /// assignRegOrStackSlotAtInterval - assign a register if one is available, or /// spill. void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur) @@ -565,16 +556,10 @@ DEBUG(std::cerr << "\t\tregister with min weight: " << mri_->getName(minReg) << " (" << minWeight << ")\n"); - // If the live interval legnth is essentially zero, i.e. in every live range - // the use follows def immediately, it doesn't make sense to spill it and - // hope it will be easier to allocate for this li. - if (isZeroLengthInterval(cur)) - DEBUG(std::cerr << "\t\tavoid spilling zero length live interval: " - << *cur << '\n';); // if the current has the minimum weight, we need to spill it and // add any added intervals back to unhandled, and restart // linearscan. - else if (cur->weight <= minWeight) { + if (cur->weight <= minWeight) { DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';); int slot = vrm_->assignVirt2StackSlot(cur->reg); std::vector added = From evan.cheng at apple.com Thu May 11 02:29:37 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 02:29:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200605110729.CAA18848@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.158 -> 1.159 --- Log message: Set weight of zero length intervals to infinite to prevent them from being spilled. --- Diffs of the changes: (+19 -0) LiveIntervalAnalysis.cpp | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.158 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.159 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.158 Tue May 9 01:37:47 2006 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Thu May 11 02:29:24 2006 @@ -80,6 +80,15 @@ } +static bool isZeroLengthInterval(LiveInterval *li) { + for (LiveInterval::Ranges::const_iterator + i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i) + if (i->end - i->start > LiveIntervals::InstrSlots::NUM) + return false; + return true; +} + + /// runOnMachineFunction - Register allocate the whole function /// bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { @@ -199,6 +208,16 @@ } } + for (iterator I = begin(), E = end(); I != E; ++I) { + LiveInterval &li = I->second; + if (MRegisterInfo::isVirtualRegister(li.reg)) + // If the live interval legnth is essentially zero, i.e. in every live + // range the use follows def immediately, it doesn't make sense to spill + // it and hope it will be easier to allocate for this li. + if (isZeroLengthInterval(&li)) + li.weight = float(HUGE_VAL); + } + DEBUG(dump()); return true; } From evan.cheng at apple.com Thu May 11 02:30:39 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 02:30:39 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200605110730.CAA18975@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.41 -> 1.42 --- Log message: Also add super- register classes info. --- Diffs of the changes: (+38 -0) RegisterInfoEmitter.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.41 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.42 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.41 Tue May 9 01:34:26 2006 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Thu May 11 02:30:26 2006 @@ -166,6 +166,7 @@ OS << " " << RegisterClasses[i].getName() << "Class\t" << RegisterClasses[i].getName() << "RegClass;\n"; + std::map > SuperClassMap; OS << "\n"; // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { @@ -194,12 +195,48 @@ if (!Empty) OS << ", "; OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; Empty = false; + + std::map >::iterator SCMI = + SuperClassMap.find(rc2); + if (SCMI == SuperClassMap.end()) { + SuperClassMap.insert(std::make_pair(rc2, std::set())); + SCMI = SuperClassMap.find(rc2); + } + SCMI->second.insert(rc); } OS << (!Empty ? ", " : "") << "NULL"; OS << "\n };\n\n"; } + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Register Class super-classes...\n const TargetRegisterClass* " + << Name << "Superclasses [] = {\n "; + + bool Empty = true; + std::map >::iterator I = + SuperClassMap.find(rc); + if (I != SuperClassMap.end()) { + for (std::set::iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) { + const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; + if (!Empty) OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + } + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RegisterClasses[i]; OS << RC.MethodBodies << "\n"; @@ -207,6 +244,7 @@ << "Class() : TargetRegisterClass(" << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " + << RC.getName() + "Superclasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; From evan.cheng at apple.com Thu May 11 02:31:57 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 02:31:57 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200605110731.CAA18988@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.76 -> 1.77 --- Log message: Also add super- register class info. --- Diffs of the changes: (+26 -2) MRegisterInfo.h | 28 ++++++++++++++++++++++++++-- 1 files changed, 26 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.76 llvm/include/llvm/Target/MRegisterInfo.h:1.77 --- llvm/include/llvm/Target/MRegisterInfo.h:1.76 Tue May 9 01:35:30 2006 +++ llvm/include/llvm/Target/MRegisterInfo.h Thu May 11 02:31:44 2006 @@ -49,15 +49,18 @@ typedef const MVT::ValueType* vt_iterator; typedef const TargetRegisterClass** sc_iterator; private: + bool isSubClass; const vt_iterator VTs; const sc_iterator SubClasses; + const sc_iterator SuperClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: TargetRegisterClass(const MVT::ValueType *vts, - const TargetRegisterClass **scs, + const TargetRegisterClass **subcs, + const TargetRegisterClass **supcs, unsigned RS, unsigned Al, iterator RB, iterator RE) - : VTs(vts), SubClasses(scs), + : VTs(vts), SubClasses(subcs), SuperClasses(supcs), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses @@ -124,6 +127,27 @@ return I; } + /// hasSuperRegClass - return true if the specified TargetRegisterClass is a + /// super-register class of this TargetRegisterClass. + bool hasSuperRegClass(const TargetRegisterClass *cs) const { + for (int i = 0; SuperClasses[i] != NULL; ++i) + if (SuperClasses[i] == cs) + return true; + return false; + } + + /// superclasses_begin / superclasses_end - Loop over all of the super-classes + /// of this register class. + sc_iterator superclasses_begin() const { + return SuperClasses; + } + + sc_iterator superclasses_end() const { + sc_iterator I = SuperClasses; + while (*I != NULL) ++I; + return I; + } + /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register /// allocate, and the preferred order to allocate them in. For example, From evan.cheng at apple.com Thu May 11 02:34:01 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 02:34:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200605110734.CAA19004@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.50 -> 1.51 --- Log message: Add MOV16_rm / MOV32_rm and MOV16_mr / MOV32_mr to isLoadFromStackSlot and isStoreToStackSlot --- Diffs of the changes: (+4 -0) X86InstrInfo.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.50 llvm/lib/Target/X86/X86InstrInfo.cpp:1.51 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.50 Mon May 8 03:01:26 2006 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Thu May 11 02:33:49 2006 @@ -53,7 +53,9 @@ default: break; case X86::MOV8rm: case X86::MOV16rm: + case X86::MOV16_rm: case X86::MOV32rm: + case X86::MOV32_rm: case X86::FpLD64m: case X86::MOVSSrm: case X86::MOVSDrm: @@ -78,7 +80,9 @@ default: break; case X86::MOV8mr: case X86::MOV16mr: + case X86::MOV16_mr: case X86::MOV32mr: + case X86::MOV32_mr: case X86::FpSTP64m: case X86::MOVSSmr: case X86::MOVSDmr: From lattner at cs.uiuc.edu Thu May 11 12:12:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 May 2006 12:12:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605111712.MAA23546@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.478 -> 1.479 --- Log message: Refactor some code, making it simpler. When doing the initial pass of constant folding, if we get a constantexpr, simplify the constant expr like we would do if the constant is folded in the normal loop. This fixes the missed-optimization regression in Transforms/InstCombine/getelementptr.ll last night. --- Diffs of the changes: (+43 -31) InstructionCombining.cpp | 74 +++++++++++++++++++++++++++-------------------- 1 files changed, 43 insertions(+), 31 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.479 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.478 Wed May 10 14:00:36 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 11 12:11:52 2006 @@ -7317,6 +7317,33 @@ return true; } +/// OptimizeConstantExpr - Given a constant expression and target data layout +/// information, symbolically evaluation the constant expr to something simpler +/// if possible. +static Constant *OptimizeConstantExpr(ConstantExpr *CE, const TargetData *TD) { + if (!TD) return CE; + + Constant *Ptr = CE->getOperand(0); + if (CE->getOpcode() == Instruction::GetElementPtr && Ptr->isNullValue() && + cast(Ptr->getType())->getElementType()->isSized()) { + // If this is a constant expr gep that is effectively computing an + // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' + bool isFoldableGEP = true; + for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) + if (!isa(CE->getOperand(i))) + isFoldableGEP = false; + if (isFoldableGEP) { + std::vector Ops(CE->op_begin()+1, CE->op_end()); + uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), Ops); + Constant *C = ConstantUInt::get(Type::ULongTy, Offset); + C = ConstantExpr::getCast(C, TD->getIntPtrType()); + return ConstantExpr::getCast(C, CE->getType()); + } + } + + return CE; +} + /// AddReachableCodeToWorklist - Walk the function in depth-first order, adding /// all reachable code to the worklist. @@ -7329,7 +7356,8 @@ /// static void AddReachableCodeToWorklist(BasicBlock *BB, std::set &Visited, - std::vector &WorkList) { + std::vector &WorkList, + const TargetData *TD) { // We have now visited this block! If we've already been here, bail out. if (!Visited.insert(BB).second) return; @@ -7346,6 +7374,8 @@ // ConstantProp instruction if trivially constant. if (Constant *C = ConstantFoldInstruction(Inst)) { + if (ConstantExpr *CE = dyn_cast(C)) + C = OptimizeConstantExpr(CE, TD); DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *Inst); Inst->replaceAllUsesWith(C); ++NumConstProp; @@ -7362,7 +7392,8 @@ if (BranchInst *BI = dyn_cast(TI)) { if (BI->isConditional() && isa(BI->getCondition())) { bool CondVal = cast(BI->getCondition())->getValue(); - AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList); + AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList, + TD); return; } } else if (SwitchInst *SI = dyn_cast(TI)) { @@ -7370,18 +7401,18 @@ // See if this is an explicit destination. for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) if (SI->getCaseValue(i) == Cond) { - AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList); + AddReachableCodeToWorklist(SI->getSuccessor(i), Visited, WorkList,TD); return; } // Otherwise it is the default destination. - AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList); + AddReachableCodeToWorklist(SI->getSuccessor(0), Visited, WorkList, TD); return; } } for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) - AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList); + AddReachableCodeToWorklist(TI->getSuccessor(i), Visited, WorkList, TD); } bool InstCombiner::runOnFunction(Function &F) { @@ -7393,7 +7424,7 @@ // the reachable instructions. Ignore blocks that are not reachable. Keep // track of which blocks we visit. std::set Visited; - AddReachableCodeToWorklist(F.begin(), Visited, WorkList); + AddReachableCodeToWorklist(F.begin(), Visited, WorkList, TD); // Do a quick scan over the function. If we find any blocks that are // unreachable, remove any instructions inside of them. This prevents @@ -7418,10 +7449,9 @@ Instruction *I = WorkList.back(); // Get an instruction from the worklist WorkList.pop_back(); - // Check to see if we can DCE or ConstantPropagate the instruction... - // Check to see if we can DIE the instruction... + // Check to see if we can DCE the instruction. if (isInstructionTriviallyDead(I)) { - // Add operands to the worklist... + // Add operands to the worklist. if (I->getNumOperands() < 4) AddUsesToWorkList(*I); ++NumDeadInst; @@ -7433,31 +7463,13 @@ continue; } - // Instruction isn't dead, see if we can constant propagate it... + // Instruction isn't dead, see if we can constant propagate it. if (Constant *C = ConstantFoldInstruction(I)) { - Value* Ptr = I->getOperand(0); - if (isa(I) && - cast(Ptr)->isNullValue() && - !isa(C) && - cast(Ptr->getType())->getElementType()->isSized()) { - // If this is a constant expr gep that is effectively computing an - // "offsetof", fold it into 'cast int X to T*' instead of 'gep 0, 0, 12' - bool isFoldableGEP = true; - for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i) - if (!isa(I->getOperand(i))) - isFoldableGEP = false; - if (isFoldableGEP) { - uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), - std::vector(I->op_begin()+1, I->op_end())); - C = ConstantUInt::get(Type::ULongTy, Offset); - C = ConstantExpr::getCast(C, TD->getIntPtrType()); - C = ConstantExpr::getCast(C, I->getType()); - } - } - + if (ConstantExpr *CE = dyn_cast(C)) + C = OptimizeConstantExpr(CE, TD); DEBUG(std::cerr << "IC: ConstFold to: " << *C << " from: " << *I); - // Add operands to the worklist... + // Add operands to the worklist. AddUsesToWorkList(*I); ReplaceInstUsesWith(*I, C); From lattner at cs.uiuc.edu Thu May 11 18:08:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 May 2006 18:08:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200605112308.SAA26499@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JITEmitter.cpp updated: 1.97 -> 1.98 --- Log message: Significantly revamp allocation of machine code to use free lists, real allocation policies and much more. All this complexity, and we have no functionality change, woo! :) --- Diffs of the changes: (+340 -51) JITEmitter.cpp | 391 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 340 insertions(+), 51 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.97 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.98 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.97 Mon May 8 17:00:52 2006 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Thu May 11 18:08:08 2006 @@ -44,6 +44,203 @@ // JITMemoryManager code. // namespace { + /// MemoryRangeHeader - For a range of memory, this is the header that we put + /// on the block of memory. It is carefully crafted to be one word of memory. + /// Allocated blocks have just this header, free'd blocks have FreeRangeHeader + /// which starts with this. + struct FreeRangeHeader; + struct MemoryRangeHeader { + /// ThisAllocated - This is true if this block is currently allocated. If + /// not, this can be converted to a FreeRangeHeader. + intptr_t ThisAllocated : 1; + + /// PrevAllocated - Keep track of whether the block immediately before us is + /// allocated. If not, the word immediately before this header is the size + /// of the previous block. + intptr_t PrevAllocated : 1; + + /// BlockSize - This is the size in bytes of this memory block, + /// including this header. + uintptr_t BlockSize : (sizeof(intptr_t)*8 - 2); + + + /// getBlockAfter - Return the memory block immediately after this one. + /// + MemoryRangeHeader &getBlockAfter() const { + return *(MemoryRangeHeader*)((char*)this+BlockSize); + } + + /// getFreeBlockBefore - If the block before this one is free, return it, + /// otherwise return null. + FreeRangeHeader *getFreeBlockBefore() const { + if (PrevAllocated) return 0; + intptr_t PrevSize = ((intptr_t *)this)[-1]; + return (FreeRangeHeader*)((char*)this-PrevSize); + } + + /// MakeFreeBlock - Turn an allocated block into a free block, adjusting + /// bits in the object headers, and adding an end of region memory block. + FreeRangeHeader &MakeFreeBlock(FreeRangeHeader *FreeList); + + /// TrimAllocationToSize - If this allocated block is significantly larger + /// than NewSize, split it into two pieces (where the former is NewSize + /// bytes, including the header), and add the new block to the free list. + FreeRangeHeader *TrimAllocationToSize(FreeRangeHeader *FreeList, + uint64_t NewSize); + }; + + /// FreeRangeHeader - For a memory block that isn't already allocated, this + /// keeps track of the current block and has a pointer to the next free block. + /// Free blocks are kept on a circularly linked list. + struct FreeRangeHeader : public MemoryRangeHeader { + FreeRangeHeader *Prev; + FreeRangeHeader *Next; + + /// getMinBlockSize - Get the minimum size for a memory block. Blocks + /// smaller than this size cannot be created. + static unsigned getMinBlockSize() { + return sizeof(FreeRangeHeader)+sizeof(intptr_t); + } + + /// SetEndOfBlockSizeMarker - The word at the end of every free block is + /// known to be the size of the free block. Set it for this block. + void SetEndOfBlockSizeMarker() { + void *EndOfBlock = (char*)this + BlockSize; + ((intptr_t *)EndOfBlock)[-1] = BlockSize; + } + + FreeRangeHeader *RemoveFromFreeList() { + assert(Next->Prev == this && Prev->Next == this && "Freelist broken!"); + Next->Prev = Prev; + return Prev->Next = Next; + } + + void AddToFreeList(FreeRangeHeader *FreeList) { + Next = FreeList; + Prev = FreeList->Prev; + Prev->Next = this; + Next->Prev = this; + } + + /// GrowBlock - The block after this block just got deallocated. Merge it + /// into the current block. + void GrowBlock(uintptr_t NewSize); + + /// AllocateBlock - Mark this entire block allocated, updating freelists + /// etc. This returns a pointer to the circular free-list. + FreeRangeHeader *AllocateBlock(); + }; +} + + +/// AllocateBlock - Mark this entire block allocated, updating freelists +/// etc. This returns a pointer to the circular free-list. +FreeRangeHeader *FreeRangeHeader::AllocateBlock() { + assert(!ThisAllocated && !getBlockAfter().PrevAllocated && + "Cannot allocate an allocated block!"); + // Mark this block allocated. + ThisAllocated = 1; + getBlockAfter().PrevAllocated = 1; + + // Remove it from the free list. + return RemoveFromFreeList(); +} + +/// MakeFreeBlock - Turn an allocated block into a free block, adjusting +/// bits in the object headers, and adding an end of region memory block. +/// If possible, coallesce this block with neighboring blocks. Return the +/// FreeRangeHeader this block ends up in, which may be != this if it got +/// coallesced. +FreeRangeHeader &MemoryRangeHeader::MakeFreeBlock(FreeRangeHeader *FreeList) { + MemoryRangeHeader *FollowingBlock = &getBlockAfter(); + assert(ThisAllocated && "This block is already allocated!"); + assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); + + // If the block after this one is free, merge it into this block. + if (!FollowingBlock->ThisAllocated) { + FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; + FollowingFreeBlock.RemoveFromFreeList(); + + // Include the following block into this one. + BlockSize += FollowingFreeBlock.BlockSize; + FollowingBlock = &FollowingFreeBlock.getBlockAfter(); + + // Tell the block after the block we are coallescing that this block is + // allocated. + FollowingBlock->PrevAllocated = 1; + } + + assert(FollowingBlock->ThisAllocated && "Missed coallescing?"); + + if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { + PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); + return *PrevFreeBlock; + } + + // Otherwise, mark this block free. + FreeRangeHeader &FreeBlock = *(FreeRangeHeader*)this; + FollowingBlock->PrevAllocated = 0; + FreeBlock.ThisAllocated = 0; + + // Link this into the linked list of free blocks. + FreeBlock.AddToFreeList(FreeList); + + // Add a marker at the end of the block, indicating the size of this free + // block. + FreeBlock.SetEndOfBlockSizeMarker(); + return FreeBlock; +} + +/// GrowBlock - The block after this block just got deallocated. Merge it +/// into the current block. +void FreeRangeHeader::GrowBlock(uintptr_t NewSize) { + assert(NewSize > BlockSize && "Not growing block?"); + BlockSize = NewSize; + SetEndOfBlockSizeMarker(); +} + +/// TrimAllocationToSize - If this allocated block is significantly larger +/// than NewSize, split it into two pieces (where the former is NewSize +/// bytes, including the header), and add the new block to the free list. +FreeRangeHeader *MemoryRangeHeader:: +TrimAllocationToSize(FreeRangeHeader *FreeList, uint64_t NewSize) { + assert(ThisAllocated && getBlockAfter().PrevAllocated && + "Cannot deallocate part of an allocated block!"); + + // Round up size for alignment of header. + unsigned HeaderAlign = __alignof(FreeRangeHeader); + NewSize = (NewSize+ (HeaderAlign-1)) & ~(HeaderAlign-1); + + // Size is now the size of the block we will remove from the start of the + // current block. + assert(NewSize <= BlockSize && + "Allocating more space from this block than exists!"); + + // If splitting this block will cause the remainder to be too small, do not + // split the block. + if (BlockSize <= NewSize+FreeRangeHeader::getMinBlockSize()) + return FreeList; + + // Otherwise, we splice the required number of bytes out of this block, form + // a new block immediately after it, then mark this block allocated. + MemoryRangeHeader &FormerNextBlock = getBlockAfter(); + + // Change the size of this block. + BlockSize = NewSize; + + // Get the new block we just sliced out and turn it into a free block. + FreeRangeHeader &NewNextBlock = (FreeRangeHeader &)getBlockAfter(); + NewNextBlock.BlockSize = (char*)&FormerNextBlock - (char*)&NewNextBlock; + NewNextBlock.ThisAllocated = 0; + NewNextBlock.PrevAllocated = 1; + NewNextBlock.SetEndOfBlockSizeMarker(); + FormerNextBlock.PrevAllocated = 0; + NewNextBlock.AddToFreeList(FreeList); + return &NewNextBlock; +} + + +namespace { /// JITMemoryManager - Manage memory for the JIT code generation in a logical, /// sane way. This splits a large block of MAP_NORESERVE'd memory into two /// sections, one for function stubs, one for the functions themselves. We @@ -53,19 +250,49 @@ /// we are ready to destroy the JIT, the program exits. class JITMemoryManager { std::vector Blocks; // Memory blocks allocated by the JIT - unsigned char *FunctionBase; // Start of the function body area - unsigned char *CurStubPtr, *CurFunctionPtr; + FreeRangeHeader *FreeMemoryList; // Circular list of free blocks. + + // When emitting code into a memory block, this is the block. + MemoryRangeHeader *CurBlock; + + unsigned char *CurStubPtr, *StubBase; unsigned char *GOTBase; // Target Specific reserved memory - // centralize memory block allocation + // Centralize memory block allocation. sys::MemoryBlock getNewMemoryBlock(unsigned size); + + std::map FunctionBlocks; public: JITMemoryManager(bool useGOT); ~JITMemoryManager(); inline unsigned char *allocateStub(unsigned StubSize); - inline unsigned char *startFunctionBody(); - inline void endFunctionBody(unsigned char *FunctionEnd); + + /// startFunctionBody - When a function starts, allocate a block of free + /// executable memory, returning a pointer to it and its actual size. + unsigned char *startFunctionBody(uintptr_t &ActualSize) { + CurBlock = FreeMemoryList; + + // Allocate the entire memory block. + FreeMemoryList = FreeMemoryList->AllocateBlock(); + ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader); + return (unsigned char *)(CurBlock+1); + } + + /// endFunctionBody - The function F is now allocated, and takes the memory + /// in the range [FunctionStart,FunctionEnd). + void endFunctionBody(const Function *F, unsigned char *FunctionStart, + unsigned char *FunctionEnd) { + assert(FunctionEnd > FunctionStart); + assert(FunctionStart == (unsigned char *)(CurBlock+1) && + "Mismatched function start/end!"); + + uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock; + FunctionBlocks[F] = CurBlock; + + // Release the memory at the end of this block that isn't needed. + FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); + } unsigned char *getGOTBase() const { return GOTBase; @@ -73,18 +300,71 @@ bool isManagingGOT() const { return GOTBase != NULL; } + + /// deallocateMemForFunction - Deallocate all memory for the specified + /// function body. + void deallocateMemForFunction(const Function *F) { + + } }; } JITMemoryManager::JITMemoryManager(bool useGOT) { - // Allocate a 16M block of memory for functions - sys::MemoryBlock FunBlock = getNewMemoryBlock(16 << 20); + // Allocate a 16M block of memory for functions. + sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20); - FunctionBase = reinterpret_cast(FunBlock.base()); + unsigned char *MemBase = reinterpret_cast(MemBlock.base()); // Allocate stubs backwards from the base, allocate functions forward // from the base. - CurStubPtr = CurFunctionPtr = FunctionBase + 512*1024;// Use 512k for stubs + StubBase = MemBase; + CurStubPtr = MemBase + 512*1024; // Use 512k for stubs, working backwards. + + // We set up the memory chunk with 4 mem regions, like this: + // [ START + // [ Free #0 ] -> Large space to allocate functions from. + // [ Allocated #1 ] -> Tiny space to separate regions. + // [ Free #2 ] -> Tiny space so there is always at least 1 free block. + // [ Allocated #3 ] -> Tiny space to prevent looking past end of block. + // END ] + // + // The last three blocks are never deallocated or touched. + + // Add MemoryRangeHeader to the end of the memory region, indicating that + // the space after the block of memory is allocated. This is block #3. + MemoryRangeHeader *Mem3 = (MemoryRangeHeader*)(MemBase+MemBlock.size())-1; + Mem3->ThisAllocated = 1; + Mem3->PrevAllocated = 0; + Mem3->BlockSize = 0; + + /// Add a tiny free region so that the free list always has one entry. + FreeRangeHeader *Mem2 = + (FreeRangeHeader *)(((char*)Mem3)-FreeRangeHeader::getMinBlockSize()); + Mem2->ThisAllocated = 0; + Mem2->PrevAllocated = 1; + Mem2->BlockSize = FreeRangeHeader::getMinBlockSize(); + Mem2->SetEndOfBlockSizeMarker(); + Mem2->Prev = Mem2; // Mem2 *is* the free list for now. + Mem2->Next = Mem2; + + /// Add a tiny allocated region so that Mem2 is never coallesced away. + MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; + Mem2->ThisAllocated = 1; + Mem2->PrevAllocated = 0; + Mem2->BlockSize = (char*)Mem2 - (char*)Mem1; + + // Add a FreeRangeHeader to the start of the function body region, indicating + // that the space is free. Mark the previous block allocated so we never look + // at it. + FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr; + Mem0->ThisAllocated = 0; + Mem0->PrevAllocated = 1; + Mem0->BlockSize = (unsigned char*)Mem1-(unsigned char*)Mem0; + Mem0->SetEndOfBlockSizeMarker(); + Mem0->AddToFreeList(Mem2); + + // Start out with the freelist pointing to Mem0. + FreeMemoryList = Mem0; // Allocate the GOT. GOTBase = NULL; @@ -99,7 +379,7 @@ unsigned char *JITMemoryManager::allocateStub(unsigned StubSize) { CurStubPtr -= StubSize; - if (CurStubPtr < FunctionBase) { + if (CurStubPtr < StubBase) { // FIXME: allocate a new block std::cerr << "JIT ran out of memory for function stubs!\n"; abort(); @@ -107,17 +387,9 @@ return CurStubPtr; } -unsigned char *JITMemoryManager::startFunctionBody() { - return CurFunctionPtr; -} - -void JITMemoryManager::endFunctionBody(unsigned char *FunctionEnd) { - assert(FunctionEnd > CurFunctionPtr); - CurFunctionPtr = FunctionEnd; -} - sys::MemoryBlock JITMemoryManager::getNewMemoryBlock(unsigned size) { try { + // Allocate a new block close to the last one. const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front(); sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld); Blocks.push_back(B); @@ -324,28 +596,6 @@ } -// getPointerToFunctionOrStub - If the specified function has been -// code-gen'd, return a pointer to the function. If not, compile it, or use -// a stub to implement lazy compilation if available. -// -void *JIT::getPointerToFunctionOrStub(Function *F) { - // If we have already code generated the function, just return the address. - if (void *Addr = getPointerToGlobalIfAvailable(F)) - return Addr; - - // Get a stub if the target supports it - return getJITResolver(MCE).getFunctionStub(F); -} - -/// freeMachineCodeForFunction - release machine code memory for given Function. -/// -void JIT::freeMachineCodeForFunction(Function *F) { - // Delete translation for this from the ExecutionEngine, so it will get - // retranslated next time it is used. - updateGlobalMapping(F, 0); - -} - //===----------------------------------------------------------------------===// // JITEmitter code. // @@ -418,16 +668,16 @@ return MBBLocations[MBB->getNumber()]; } - + /// deallocateMemForFunction - Deallocate all memory for the specified + /// function body. + void deallocateMemForFunction(Function *F) { + MemMgr.deallocateMemForFunction(F); + } private: void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); }; } -MachineCodeEmitter *JIT::createEmitter(JIT &jit) { - return new JITEmitter(jit); -} - void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference, bool DoesntNeedStub) { if (GlobalVariable *GV = dyn_cast(V)) { @@ -461,10 +711,9 @@ } void JITEmitter::startFunction(MachineFunction &F) { - BufferBegin = CurBufferPtr = MemMgr.startFunctionBody(); - - /// FIXME: implement out of space handling correctly! - BufferEnd = (unsigned char*)(intptr_t)~0ULL; + uintptr_t ActualSize; + BufferBegin = CurBufferPtr = MemMgr.startFunctionBody(ActualSize); + BufferEnd = BufferBegin+ActualSize; emitConstantPool(F.getConstantPool()); initJumpTableInfo(F.getJumpTableInfo()); @@ -477,9 +726,15 @@ } bool JITEmitter::finishFunction(MachineFunction &F) { + if (CurBufferPtr == BufferEnd) { + // FIXME: Allocate more space, then try again. + std::cerr << "JIT: Ran out of space for generated machine code!\n"; + abort(); + } + emitJumpTableInfo(F.getJumpTableInfo()); - MemMgr.endFunctionBody(CurBufferPtr); + MemMgr.endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); NumBytes += getCurrentPCOffset(); if (!Relocations.empty()) { @@ -642,6 +897,14 @@ return (intptr_t)((char *)JumpTableBase + Offset); } +//===----------------------------------------------------------------------===// +// Public interface to this file +//===----------------------------------------------------------------------===// + +MachineCodeEmitter *JIT::createEmitter(JIT &jit) { + return new JITEmitter(jit); +} + // getPointerToNamedFunction - This function is used as a global wrapper to // JIT::getPointerToNamedFunction for the purpose of resolving symbols when // bugpoint is debugging the JIT. In that scenario, we are loading an .so and @@ -655,3 +918,29 @@ return TheJIT->getPointerToNamedFunction(Name); } } + +// getPointerToFunctionOrStub - If the specified function has been +// code-gen'd, return a pointer to the function. If not, compile it, or use +// a stub to implement lazy compilation if available. +// +void *JIT::getPointerToFunctionOrStub(Function *F) { + // If we have already code generated the function, just return the address. + if (void *Addr = getPointerToGlobalIfAvailable(F)) + return Addr; + + // Get a stub if the target supports it + return getJITResolver(MCE).getFunctionStub(F); +} + +/// freeMachineCodeForFunction - release machine code memory for given Function. +/// +void JIT::freeMachineCodeForFunction(Function *F) { + // Delete translation for this from the ExecutionEngine, so it will get + // retranslated next time it is used. + updateGlobalMapping(F, 0); + + // Free the actual memory for the function body and related stuff. + assert(dynamic_cast(MCE) && "Unexpected MCE?"); + dynamic_cast(MCE)->deallocateMemForFunction(F); +} + From evan.cheng at apple.com Thu May 11 18:55:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 18:55:56 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200605112355.SAA26626@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.23 -> 1.24 --- Log message: Refactor scheduler code. Move register-reduction list scheduler to a separate file. Added an initial implementation of top-down register pressure reduction list scheduler. --- Diffs of the changes: (+111 -0) ScheduleDAG.h | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 111 insertions(+) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.23 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.24 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.23 Sat Apr 22 13:53:45 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Thu May 11 18:55:42 2006 @@ -17,6 +17,8 @@ #include "llvm/CodeGen/SelectionDAG.h" +#include + namespace llvm { struct InstrStage; class MachineConstantPool; @@ -71,8 +73,88 @@ } }; + /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or + /// a group of nodes flagged together. + struct SUnit { + SDNode *Node; // Representative node. + std::vector FlaggedNodes; // All nodes flagged to Node. + + // Preds/Succs - The SUnits before/after us in the graph. The boolean value + // is true if the edge is a token chain edge, false if it is a value edge. + std::set > Preds; // All sunit predecessors. + std::set > Succs; // All sunit successors. + + short NumPreds; // # of preds. + short NumSuccs; // # of sucss. + short NumPredsLeft; // # of preds not scheduled. + short NumSuccsLeft; // # of succs not scheduled. + short NumChainPredsLeft; // # of chain preds not scheduled. + short NumChainSuccsLeft; // # of chain succs not scheduled. + bool isTwoAddress : 1; // Is a two-address instruction. + bool isDefNUseOperand : 1; // Is a def&use operand. + bool isPending : 1; // True once pending. + bool isAvailable : 1; // True once available. + bool isScheduled : 1; // True once scheduled. + unsigned short Latency; // Node latency. + unsigned CycleBound; // Upper/lower cycle to be scheduled at. + unsigned Cycle; // Once scheduled, the cycle of the op. + unsigned Depth; // Node depth; + unsigned Height; // Node height; + unsigned NodeNum; // Entry # of node in the node vector. + + SUnit(SDNode *node, unsigned nodenum) + : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), + NumChainPredsLeft(0), NumChainSuccsLeft(0), + isTwoAddress(false), isDefNUseOperand(false), + isPending(false), isAvailable(false), isScheduled(false), + Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0), + NodeNum(nodenum) {} + + void dump(const SelectionDAG *G) const; + void dumpAll(const SelectionDAG *G) const; + }; + + //===--------------------------------------------------------------------===// + /// SchedulingPriorityQueue - This interface is used to plug different + /// priorities computation algorithms into the list scheduler. It implements + /// the interface of a standard priority queue, where nodes are inserted in + /// arbitrary order and returned in priority order. The computation of the + /// priority and the representation of the queue are totally up to the + /// implementation to decide. + /// + class SchedulingPriorityQueue { + public: + virtual ~SchedulingPriorityQueue() {} + + virtual void initNodes(const std::vector &SUnits) = 0; + virtual void releaseState() = 0; + + virtual bool empty() const = 0; + virtual void push(SUnit *U) = 0; + + virtual void push_all(const std::vector &Nodes) = 0; + virtual SUnit *pop() = 0; + + /// ScheduledNode - As each node is scheduled, this method is invoked. This + /// allows the priority function to adjust the priority of node that have + /// already been emitted. + virtual void ScheduledNode(SUnit *Node) {} + }; + class ScheduleDAG { public: + + // Scheduling heuristics + enum SchedHeuristics { + defaultScheduling, // Let the target specify its preference. + noScheduling, // No scheduling, emit breadth first sequence. + simpleScheduling, // Two pass, min. critical path, max. utilization. + simpleNoItinScheduling, // Same as above exact using generic latency. + listSchedulingBURR, // Bottom-up reg reduction list scheduling. + listSchedulingTDRR, // Top-down reg reduction list scheduling. + listSchedulingTD // Top-down list scheduler. + }; + SelectionDAG &DAG; // DAG of the current basic block MachineBasicBlock *BB; // Current basic block const TargetMachine &TM; // Target processor @@ -80,6 +162,10 @@ const MRegisterInfo *MRI; // Target processor register info SSARegMap *RegMap; // Virtual/real register map MachineConstantPool *ConstPool; // Target constant pool + std::vector Sequence; // The schedule. Null SUnit*'s represent + // noop instructions. + std::map SUnitMap; // SDNode to SUnit mapping (n -> 1). + std::vector SUnits; // The scheduling units. ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm) @@ -105,6 +191,23 @@ return false; } + /// NewSUnit - Creates a new SUnit and return a ptr to it. + /// + SUnit *NewSUnit(SDNode *N) { + SUnits.push_back(SUnit(N, SUnits.size())); + return &SUnits.back(); + } + + /// BuildSchedUnits - Build SUnits from the selection dag that we are input. + /// This SUnit graph is similar to the SelectionDAG, but represents flagged + /// together nodes with a single SUnit. + void BuildSchedUnits(); + + /// CalculateDepths, CalculateHeights - Calculate node depth / height. + /// + void CalculateDepths(); + void CalculateHeights(); + /// EmitNode - Generate machine code for an node and needed dependencies. /// VRBaseMap contains, for each already emitted node, the first virtual /// register number for the results of the node. @@ -115,6 +218,9 @@ /// void EmitNoop(); + void EmitSchedule(); + + void dumpSchedule() const; /// Schedule - Order nodes according to selected style. /// @@ -138,6 +244,11 @@ ScheduleDAG* createBURRListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB); + /// createTDRRListDAGScheduler - This creates a top down register usage + /// reduction list scheduler. + ScheduleDAG* createTDRRListDAGScheduler(SelectionDAG &DAG, + MachineBasicBlock *BB); + /// createTDListDAGScheduler - This creates a top-down list scheduler with /// the specified hazard recognizer. This takes ownership of the hazard /// recognizer and deletes it when done. From evan.cheng at apple.com Thu May 11 18:55:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 18:55:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp ScheduleDAG.cpp ScheduleDAGList.cpp SelectionDAGISel.cpp Message-ID: <200605112355.SAA26636@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGRRList.cpp added (r1.1) ScheduleDAG.cpp updated: 1.86 -> 1.87 ScheduleDAGList.cpp updated: 1.57 -> 1.58 SelectionDAGISel.cpp updated: 1.237 -> 1.238 --- Log message: Refactor scheduler code. Move register-reduction list scheduler to a separate file. Added an initial implementation of top-down register pressure reduction list scheduler. --- Diffs of the changes: (+1104 -932) ScheduleDAG.cpp | 251 +++++++++++++ ScheduleDAGList.cpp | 927 +------------------------------------------------- ScheduleDAGRRList.cpp | 813 +++++++++++++++++++++++++++++++++++++++++++ SelectionDAGISel.cpp | 45 +- 4 files changed, 1104 insertions(+), 932 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp diff -c /dev/null llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.1 *** /dev/null Thu May 11 18:55:52 2006 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu May 11 18:55:42 2006 *************** *** 0 **** --- 1,813 ---- + //===----- ScheduleDAGList.cpp - Reg pressure reduction list scheduler ----===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Evan Cheng and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This implements bottom-up and top-down register pressure reduction list + // schedulers, using standard algorithms. The basic approach uses a priority + // queue of available nodes to schedule. One at a time, nodes are taken from + // the priority queue (thus in priority order), checked for legality to + // schedule, and emitted if legal. + // + //===----------------------------------------------------------------------===// + + #define DEBUG_TYPE "sched" + #include "llvm/CodeGen/ScheduleDAG.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/MRegisterInfo.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Target/TargetInstrInfo.h" + #include "llvm/Support/Debug.h" + #include "llvm/ADT/Statistic.h" + #include + #include + #include + #include "llvm/Support/CommandLine.h" + using namespace llvm; + + namespace { + cl::opt SchedLowerDefNUse("sched-lower-defnuse", cl::Hidden); + } + + namespace { + //===----------------------------------------------------------------------===// + /// ScheduleDAGRRList - The actual register reduction list scheduler + /// implementation. This supports both top-down and bottom-up scheduling. + /// + + class ScheduleDAGRRList : public ScheduleDAG { + private: + /// isBottomUp - This is true if the scheduling problem is bottom-up, false if + /// it is top-down. + bool isBottomUp; + + /// AvailableQueue - The priority queue to use for the available SUnits. + /// + SchedulingPriorityQueue *AvailableQueue; + + public: + ScheduleDAGRRList(SelectionDAG &dag, MachineBasicBlock *bb, + const TargetMachine &tm, bool isbottomup, + SchedulingPriorityQueue *availqueue) + : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), + AvailableQueue(availqueue) { + } + + ~ScheduleDAGRRList() { + delete AvailableQueue; + } + + void Schedule(); + + private: + void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle); + void ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle); + void ScheduleNodeBottomUp(SUnit *SU, unsigned& CurCycle); + void ScheduleNodeTopDown(SUnit *SU, unsigned& CurCycle); + void ListScheduleTopDown(); + void ListScheduleBottomUp(); + }; + } // end anonymous namespace + + + /// Schedule - Schedule the DAG using list scheduling. + void ScheduleDAGRRList::Schedule() { + DEBUG(std::cerr << "********** List Scheduling **********\n"); + + // Build scheduling units. + BuildSchedUnits(); + + CalculateDepths(); + CalculateHeights(); + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) + SUnits[su].dumpAll(&DAG)); + + AvailableQueue->initNodes(SUnits); + + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. + if (isBottomUp) + ListScheduleBottomUp(); + else + ListScheduleTopDown(); + + AvailableQueue->releaseState(); + + DEBUG(std::cerr << "*** Final schedule ***\n"); + DEBUG(dumpSchedule()); + DEBUG(std::cerr << "\n"); + + // Emit in scheduled order + EmitSchedule(); + } + + + //===----------------------------------------------------------------------===// + // Bottom-Up Scheduling + //===----------------------------------------------------------------------===// + + static const TargetRegisterClass *getRegClass(SUnit *SU, + const TargetInstrInfo *TII, + const MRegisterInfo *MRI, + SSARegMap *RegMap) { + if (SU->Node->isTargetOpcode()) { + unsigned Opc = SU->Node->getTargetOpcode(); + const TargetInstrDescriptor &II = TII->get(Opc); + return II.OpInfo->RegClass; + } else { + assert(SU->Node->getOpcode() == ISD::CopyFromReg); + unsigned SrcReg = cast(SU->Node->getOperand(1))->getReg(); + if (MRegisterInfo::isVirtualRegister(SrcReg)) + return RegMap->getRegClass(SrcReg); + else { + for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(), + E = MRI->regclass_end(); I != E; ++I) + if ((*I)->hasType(SU->Node->getValueType(0)) && + (*I)->contains(SrcReg)) + return *I; + assert(false && "Couldn't find register class for reg copy!"); + } + return NULL; + } + } + + static unsigned getNumResults(SUnit *SU) { + unsigned NumResults = 0; + for (unsigned i = 0, e = SU->Node->getNumValues(); i != e; ++i) { + MVT::ValueType VT = SU->Node->getValueType(i); + if (VT != MVT::Other && VT != MVT::Flag) + NumResults++; + } + return NumResults; + } + + /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to + /// the Available queue is the count reaches zero. Also update its cycle bound. + void ScheduleDAGRRList::ReleasePred(SUnit *PredSU, bool isChain, + unsigned CurCycle) { + // FIXME: the distance between two nodes is not always == the predecessor's + // latency. For example, the reader can very well read the register written + // by the predecessor later than the issue cycle. It also depends on the + // interrupt model (drain vs. freeze). + PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); + + if (!isChain) + PredSU->NumSuccsLeft--; + else + PredSU->NumChainSuccsLeft--; + + #ifndef NDEBUG + if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) { + std::cerr << "*** List scheduling failed! ***\n"; + PredSU->dump(&DAG); + std::cerr << " has been released too many times!\n"; + assert(0); + } + #endif + + if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) { + // EntryToken has to go last! Special case it here. + if (PredSU->Node->getOpcode() != ISD::EntryToken) { + PredSU->isAvailable = true; + AvailableQueue->push(PredSU); + } + } + } + + /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending + /// count of its predecessors. If a predecessor pending count is zero, add it to + /// the Available queue. + void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned& CurCycle) { + DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: "); + DEBUG(SU->dump(&DAG)); + SU->Cycle = CurCycle; + + AvailableQueue->ScheduledNode(SU); + Sequence.push_back(SU); + + // Bottom up: release predecessors + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) + ReleasePred(I->first, I->second, CurCycle); + SU->isScheduled = true; + CurCycle++; + } + + /// isReady - True if node's lower cycle bound is less or equal to the current + /// scheduling cycle. Always true if all nodes have uniform latency 1. + static inline bool isReady(SUnit *SU, unsigned CurCycle) { + return SU->CycleBound <= CurCycle; + } + + /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up + /// schedulers. + void ScheduleDAGRRList::ListScheduleBottomUp() { + unsigned CurCycle = 0; + // Add root to Available queue. + AvailableQueue->push(SUnitMap[DAG.getRoot().Val]); + + // While Available queue is not empty, grab the node with the highest + // priority. If it is not ready put it back. Schedule the node. + std::vector NotReady; + SUnit *CurNode = NULL; + while (!AvailableQueue->empty()) { + SUnit *CurNode = AvailableQueue->pop(); + while (!isReady(CurNode, CurCycle)) { + NotReady.push_back(CurNode); + CurNode = AvailableQueue->pop(); + } + + // Add the nodes that aren't ready back onto the available list. + AvailableQueue->push_all(NotReady); + NotReady.clear(); + + ScheduleNodeBottomUp(CurNode, CurCycle); + } + + // Add entry node last + if (DAG.getEntryNode().Val != DAG.getRoot().Val) { + SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; + Sequence.push_back(Entry); + } + + // Reverse the order if it is bottom up. + std::reverse(Sequence.begin(), Sequence.end()); + + + #ifndef NDEBUG + // Verify that all SUnits were scheduled. + bool AnyNotSched = false; + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + if (SUnits[i].NumSuccsLeft != 0 || SUnits[i].NumChainSuccsLeft != 0) { + if (!AnyNotSched) + std::cerr << "*** List scheduling failed! ***\n"; + SUnits[i].dump(&DAG); + std::cerr << "has not been scheduled!\n"; + AnyNotSched = true; + } + } + assert(!AnyNotSched); + #endif + } + + //===----------------------------------------------------------------------===// + // Top-Down Scheduling + //===----------------------------------------------------------------------===// + + /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to + /// the PendingQueue if the count reaches zero. + void ScheduleDAGRRList::ReleaseSucc(SUnit *SuccSU, bool isChain, + unsigned CurCycle) { + // FIXME: the distance between two nodes is not always == the predecessor's + // latency. For example, the reader can very well read the register written + // by the predecessor later than the issue cycle. It also depends on the + // interrupt model (drain vs. freeze). + SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency); + + if (!isChain) + SuccSU->NumPredsLeft--; + else + SuccSU->NumChainPredsLeft--; + + #ifndef NDEBUG + if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) { + std::cerr << "*** List scheduling failed! ***\n"; + SuccSU->dump(&DAG); + std::cerr << " has been released too many times!\n"; + assert(0); + } + #endif + + if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) { + SuccSU->isAvailable = true; + AvailableQueue->push(SuccSU); + } + } + + + /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending + /// count of its successors. If a successor pending count is zero, add it to + /// the Available queue. + void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned& CurCycle) { + DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: "); + DEBUG(SU->dump(&DAG)); + SU->Cycle = CurCycle; + + AvailableQueue->ScheduledNode(SU); + Sequence.push_back(SU); + + // Top down: release successors + for (std::set >::iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) + ReleaseSucc(I->first, I->second, CurCycle); + SU->isScheduled = true; + CurCycle++; + } + + void ScheduleDAGRRList::ListScheduleTopDown() { + unsigned CurCycle = 0; + SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; + + // All leaves to Available queue. + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + // It is available if it has no predecessors. + if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) { + AvailableQueue->push(&SUnits[i]); + SUnits[i].isAvailable = true; + } + } + + // Emit the entry node first. + ScheduleNodeTopDown(Entry, CurCycle); + + // While Available queue is not empty, grab the node with the highest + // priority. If it is not ready put it back. Schedule the node. + std::vector NotReady; + SUnit *CurNode = NULL; + while (!AvailableQueue->empty()) { + SUnit *CurNode = AvailableQueue->pop(); + while (!isReady(CurNode, CurCycle)) { + NotReady.push_back(CurNode); + CurNode = AvailableQueue->pop(); + } + + // Add the nodes that aren't ready back onto the available list. + AvailableQueue->push_all(NotReady); + NotReady.clear(); + + ScheduleNodeTopDown(CurNode, CurCycle); + } + + + #ifndef NDEBUG + // Verify that all SUnits were scheduled. + bool AnyNotSched = false; + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + if (!SUnits[i].isScheduled) { + if (!AnyNotSched) + std::cerr << "*** List scheduling failed! ***\n"; + SUnits[i].dump(&DAG); + std::cerr << "has not been scheduled!\n"; + AnyNotSched = true; + } + } + assert(!AnyNotSched); + #endif + } + + + + //===----------------------------------------------------------------------===// + // RegReductionPriorityQueue Implementation + //===----------------------------------------------------------------------===// + // + // This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers + // to reduce register pressure. + // + namespace { + template + class RegReductionPriorityQueue; + + /// Sorting functions for the Available queue. + struct bu_ls_rr_sort : public std::binary_function { + RegReductionPriorityQueue *SPQ; + bu_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} + bu_ls_rr_sort(const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} + + bool operator()(const SUnit* left, const SUnit* right) const; + }; + + struct td_ls_rr_sort : public std::binary_function { + RegReductionPriorityQueue *SPQ; + td_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} + td_ls_rr_sort(const td_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} + + bool operator()(const SUnit* left, const SUnit* right) const; + }; + } // end anonymous namespace + + namespace { + template + class RegReductionPriorityQueue : public SchedulingPriorityQueue { + std::priority_queue, SF> Queue; + + public: + RegReductionPriorityQueue() : + Queue(SF(this)) {} + + virtual void initNodes(const std::vector &sunits) {} + virtual void releaseState() {} + + virtual int getSethiUllmanNumber(unsigned NodeNum) const { + return 0; + } + + bool empty() const { return Queue.empty(); } + + void push(SUnit *U) { + Queue.push(U); + } + void push_all(const std::vector &Nodes) { + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) + Queue.push(Nodes[i]); + } + + SUnit *pop() { + SUnit *V = Queue.top(); + Queue.pop(); + return V; + } + }; + + template + class BURegReductionPriorityQueue : public RegReductionPriorityQueue { + // SUnits - The SUnits for the current graph. + const std::vector *SUnits; + + // SethiUllmanNumbers - The SethiUllman number for each node. + std::vector SethiUllmanNumbers; + + public: + BURegReductionPriorityQueue() {} + + void initNodes(const std::vector &sunits) { + SUnits = &sunits; + // Add pseudo dependency edges for two-address nodes. + if (SchedLowerDefNUse) + AddPseudoTwoAddrDeps(); + // Calculate node priorities. + CalculatePriorities(); + } + + void releaseState() { + SUnits = 0; + SethiUllmanNumbers.clear(); + } + + int getSethiUllmanNumber(unsigned NodeNum) const { + assert(NodeNum < SethiUllmanNumbers.size()); + return SethiUllmanNumbers[NodeNum]; + } + + private: + void AddPseudoTwoAddrDeps(); + void CalculatePriorities(); + int CalcNodePriority(const SUnit *SU); + }; + + + template + class TDRegReductionPriorityQueue : public RegReductionPriorityQueue { + // SUnits - The SUnits for the current graph. + const std::vector *SUnits; + + // SethiUllmanNumbers - The SethiUllman number for each node. + std::vector SethiUllmanNumbers; + + public: + TDRegReductionPriorityQueue() {} + + void initNodes(const std::vector &sunits) { + SUnits = &sunits; + // Calculate node priorities. + CalculatePriorities(); + } + + void releaseState() { + SUnits = 0; + SethiUllmanNumbers.clear(); + } + + int getSethiUllmanNumber(unsigned NodeNum) const { + assert(NodeNum < SethiUllmanNumbers.size()); + return SethiUllmanNumbers[NodeNum]; + } + + private: + void CalculatePriorities(); + int CalcNodePriority(const SUnit *SU); + }; + } + + // Bottom up + bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { + unsigned LeftNum = left->NodeNum; + unsigned RightNum = right->NodeNum; + bool LIsTarget = left->Node->isTargetOpcode(); + bool RIsTarget = right->Node->isTargetOpcode(); + int LPriority = SPQ->getSethiUllmanNumber(LeftNum); + int RPriority = SPQ->getSethiUllmanNumber(RightNum); + bool LIsFloater = LIsTarget && (LPriority == 1 || LPriority == 0); + bool RIsFloater = RIsTarget && (RPriority == 1 || RPriority == 0); + int LBonus = 0; + int RBonus = 0; + + // Schedule floaters (e.g. load from some constant address) and those nodes + // with a single predecessor each first. They maintain / reduce register + // pressure. + if (LIsFloater) + LBonus += 2; + if (RIsFloater) + RBonus += 2; + + if (!SchedLowerDefNUse) { + // Special tie breaker: if two nodes share a operand, the one that use it + // as a def&use operand is preferred. + if (LIsTarget && RIsTarget) { + if (left->isTwoAddress && !right->isTwoAddress) { + SDNode *DUNode = left->Node->getOperand(0).Val; + if (DUNode->isOperand(right->Node)) + LBonus += 2; + } + if (!left->isTwoAddress && right->isTwoAddress) { + SDNode *DUNode = right->Node->getOperand(0).Val; + if (DUNode->isOperand(left->Node)) + RBonus += 2; + } + } + } + + if (LPriority+LBonus < RPriority+RBonus) + return true; + else if (LPriority+LBonus == RPriority+RBonus) + if (left->NumPredsLeft > right->NumPredsLeft) + return true; + else if (left->NumPredsLeft+LBonus == right->NumPredsLeft+RBonus) + if (left->CycleBound > right->CycleBound) + return true; + return false; + } + + static inline bool isCopyFromLiveIn(const SUnit *SU) { + SDNode *N = SU->Node; + return N->getOpcode() == ISD::CopyFromReg && + N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag; + } + + // FIXME: This is probably too slow! + static void isReachable(SUnit *SU, SUnit *TargetSU, + std::set &Visited, bool &Reached) { + if (Reached) return; + if (SU == TargetSU) { + Reached = true; + return; + } + if (!Visited.insert(SU).second) return; + + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) + isReachable(I->first, TargetSU, Visited, Reached); + } + + static bool isReachable(SUnit *SU, SUnit *TargetSU) { + std::set Visited; + bool Reached = false; + isReachable(SU, TargetSU, Visited, Reached); + return Reached; + } + + static SUnit *getDefUsePredecessor(SUnit *SU) { + SDNode *DU = SU->Node->getOperand(0).Val; + for (std::set >::iterator + I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (I->second) continue; // ignore chain preds + SUnit *PredSU = I->first; + if (PredSU->Node == DU) + return PredSU; + } + + // Must be flagged. + return NULL; + } + + static bool canClobber(SUnit *SU, SUnit *Op) { + if (SU->isTwoAddress) + return Op == getDefUsePredecessor(SU); + return false; + } + + /// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses + /// it as a def&use operand. Add a pseudo control edge from it to the other + /// node (if it won't create a cycle) so the two-address one will be scheduled + /// first (lower in the schedule). + template + void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() { + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { + SUnit *SU = (SUnit *)&((*SUnits)[i]); + SDNode *Node = SU->Node; + if (!Node->isTargetOpcode()) + continue; + + if (SU->isTwoAddress) { + unsigned Depth = SU->Node->getNodeDepth(); + SUnit *DUSU = getDefUsePredecessor(SU); + if (!DUSU) continue; + + for (std::set >::iterator I = DUSU->Succs.begin(), + E = DUSU->Succs.end(); I != E; ++I) { + SUnit *SuccSU = I->first; + if (SuccSU != SU && !canClobber(SuccSU, DUSU)) { + if (SuccSU->Node->getNodeDepth() <= Depth+2 && + !isReachable(SuccSU, SU)) { + DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum + << " to SU #" << SuccSU->NodeNum << "\n"); + if (SU->Preds.insert(std::make_pair(SuccSU, true)).second) + SU->NumChainPredsLeft++; + if (SuccSU->Succs.insert(std::make_pair(SU, true)).second) + SuccSU->NumChainSuccsLeft++; + } + } + } + } + } + } + + /// CalcNodePriority - Priority is the Sethi Ullman number. + /// Smaller number is the higher priority. + template + int BURegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) { + int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; + if (SethiUllmanNumber != 0) + return SethiUllmanNumber; + + unsigned Opc = SU->Node->getOpcode(); + if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg) + SethiUllmanNumber = INT_MAX - 10; + else if (SU->NumSuccsLeft == 0) + // If SU does not have a use, i.e. it doesn't produce a value that would + // be consumed (e.g. store), then it terminates a chain of computation. + // Give it a small SethiUllman number so it will be scheduled right before its + // predecessors that it doesn't lengthen their live ranges. + SethiUllmanNumber = INT_MIN + 10; + else if (SU->NumPredsLeft == 0 && + (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU))) + SethiUllmanNumber = 1; + else { + int Extra = 0; + for (std::set >::const_iterator + I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (I->second) continue; // ignore chain preds + SUnit *PredSU = I->first; + int PredSethiUllman = CalcNodePriority(PredSU); + if (PredSethiUllman > SethiUllmanNumber) { + SethiUllmanNumber = PredSethiUllman; + Extra = 0; + } else if (PredSethiUllman == SethiUllmanNumber && !I->second) + Extra++; + } + + SethiUllmanNumber += Extra; + } + + return SethiUllmanNumber; + } + + /// CalculatePriorities - Calculate priorities of all scheduling units. + template + void BURegReductionPriorityQueue::CalculatePriorities() { + SethiUllmanNumbers.assign(SUnits->size(), 0); + + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) + CalcNodePriority(&(*SUnits)[i]); + } + + static unsigned SumOfUnscheduledPredsOfSuccs(const SUnit *SU) { + unsigned Sum = 0; + for (std::set >::const_iterator + I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { + SUnit *SuccSU = I->first; + for (std::set >::const_iterator + II = SuccSU->Preds.begin(), EE = SuccSU->Preds.end(); II != EE; ++II) { + SUnit *PredSU = II->first; + if (!PredSU->isScheduled) + Sum++; + } + } + + return Sum; + } + + + // Top down + bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { + unsigned LeftNum = left->NodeNum; + unsigned RightNum = right->NodeNum; + int LPriority = SPQ->getSethiUllmanNumber(LeftNum); + int RPriority = SPQ->getSethiUllmanNumber(RightNum); + bool LIsTarget = left->Node->isTargetOpcode(); + bool RIsTarget = right->Node->isTargetOpcode(); + bool LIsFloater = LIsTarget && left->NumPreds == 0; + bool RIsFloater = RIsTarget && right->NumPreds == 0; + unsigned LBonus = (SumOfUnscheduledPredsOfSuccs(left) == 1) ? 2 : 0; + unsigned RBonus = (SumOfUnscheduledPredsOfSuccs(right) == 1) ? 2 : 0; + + if (left->NumSuccs == 0 && right->NumSuccs != 0) + return false; + else if (left->NumSuccs != 0 && right->NumSuccs == 0) + return true; + + // Special tie breaker: if two nodes share a operand, the one that use it + // as a def&use operand is preferred. + if (LIsTarget && RIsTarget) { + if (left->isTwoAddress && !right->isTwoAddress) { + SDNode *DUNode = left->Node->getOperand(0).Val; + if (DUNode->isOperand(right->Node)) + RBonus += 2; + } + if (!left->isTwoAddress && right->isTwoAddress) { + SDNode *DUNode = right->Node->getOperand(0).Val; + if (DUNode->isOperand(left->Node)) + LBonus += 2; + } + } + if (LIsFloater) + LBonus -= 2; + if (RIsFloater) + RBonus -= 2; + if (left->NumSuccs == 1) + LBonus += 2; + if (right->NumSuccs == 1) + RBonus += 2; + + if (LPriority+LBonus < RPriority+RBonus) + return true; + else if (LPriority == RPriority) + if (left->Depth < right->Depth) + return true; + else if (left->Depth == right->Depth) + if (left->NumSuccsLeft > right->NumSuccsLeft) + return true; + else if (left->NumSuccsLeft == right->NumSuccsLeft) + if (left->CycleBound > right->CycleBound) + return true; + return false; + } + + /// CalcNodePriority - Priority is the Sethi Ullman number. + /// Smaller number is the higher priority. + template + int TDRegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) { + int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; + if (SethiUllmanNumber != 0) + return SethiUllmanNumber; + + unsigned Opc = SU->Node->getOpcode(); + if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg) + SethiUllmanNumber = INT_MAX - 10; + else if (SU->NumSuccsLeft == 0) + // If SU does not have a use, i.e. it doesn't produce a value that would + // be consumed (e.g. store), then it terminates a chain of computation. + // Give it a small SethiUllman number so it will be scheduled right before its + // predecessors that it doesn't lengthen their live ranges. + SethiUllmanNumber = INT_MIN + 10; + else if (SU->NumPredsLeft == 0 && + (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU))) + SethiUllmanNumber = 1; + else { + int Extra = 0; + for (std::set >::const_iterator + I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (I->second) continue; // ignore chain preds + SUnit *PredSU = I->first; + int PredSethiUllman = CalcNodePriority(PredSU); + if (PredSethiUllman > SethiUllmanNumber) { + SethiUllmanNumber = PredSethiUllman; + Extra = 0; + } else if (PredSethiUllman == SethiUllmanNumber && !I->second) + Extra++; + } + + SethiUllmanNumber += Extra; + } + + return SethiUllmanNumber; + } + + /// CalculatePriorities - Calculate priorities of all scheduling units. + template + void TDRegReductionPriorityQueue::CalculatePriorities() { + SethiUllmanNumbers.assign(SUnits->size(), 0); + + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) + CalcNodePriority(&(*SUnits)[i]); + } + + //===----------------------------------------------------------------------===// + // Public Constructor Functions + //===----------------------------------------------------------------------===// + + llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, + MachineBasicBlock *BB) { + return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), true, + new BURegReductionPriorityQueue()); + } + + llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAG &DAG, + MachineBasicBlock *BB) { + return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), false, + new TDRegReductionPriorityQueue()); + } + Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.86 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.87 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.86 Thu May 4 13:16:01 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu May 11 18:55:42 2006 @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "sched" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" @@ -20,10 +21,185 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" +#include using namespace llvm; +/// BuildSchedUnits - Build SUnits from the selection dag that we are input. +/// This SUnit graph is similar to the SelectionDAG, but represents flagged +/// together nodes with a single SUnit. +void ScheduleDAG::BuildSchedUnits() { + // Reserve entries in the vector for each of the SUnits we are creating. This + // ensure that reallocation of the vector won't happen, so SUnit*'s won't get + // invalidated. + SUnits.reserve(std::distance(DAG.allnodes_begin(), DAG.allnodes_end())); + + const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); + + for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(), + E = DAG.allnodes_end(); NI != E; ++NI) { + if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. + continue; + + // If this node has already been processed, stop now. + if (SUnitMap[NI]) continue; + + SUnit *NodeSUnit = NewSUnit(NI); + + // See if anything is flagged to this node, if so, add them to flagged + // nodes. Nodes can have at most one flag input and one flag output. Flags + // are required the be the last operand and result of a node. + + // Scan up, adding flagged preds to FlaggedNodes. + SDNode *N = NI; + while (N->getNumOperands() && + N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { + N = N->getOperand(N->getNumOperands()-1).Val; + NodeSUnit->FlaggedNodes.push_back(N); + SUnitMap[N] = NodeSUnit; + } + + // Scan down, adding this node and any flagged succs to FlaggedNodes if they + // have a user of the flag operand. + N = NI; + while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { + SDOperand FlagVal(N, N->getNumValues()-1); + + // There are either zero or one users of the Flag result. + bool HasFlagUse = false; + for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); + UI != E; ++UI) + if (FlagVal.isOperand(*UI)) { + HasFlagUse = true; + NodeSUnit->FlaggedNodes.push_back(N); + SUnitMap[N] = NodeSUnit; + N = *UI; + break; + } + if (!HasFlagUse) break; + } + + // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. + // Update the SUnit + NodeSUnit->Node = N; + SUnitMap[N] = NodeSUnit; + + // Compute the latency for the node. We use the sum of the latencies for + // all nodes flagged together into this SUnit. + if (InstrItins.isEmpty()) { + // No latency information. + NodeSUnit->Latency = 1; + } else { + NodeSUnit->Latency = 0; + if (N->isTargetOpcode()) { + unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode()); + InstrStage *S = InstrItins.begin(SchedClass); + InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + NodeSUnit->Latency += S->Cycles; + } + for (unsigned i = 0, e = NodeSUnit->FlaggedNodes.size(); i != e; ++i) { + SDNode *FNode = NodeSUnit->FlaggedNodes[i]; + if (FNode->isTargetOpcode()) { + unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode()); + InstrStage *S = InstrItins.begin(SchedClass); + InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + NodeSUnit->Latency += S->Cycles; + } + } + } + } + + // Pass 2: add the preds, succs, etc. + for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { + SUnit *SU = &SUnits[su]; + SDNode *MainNode = SU->Node; + + if (MainNode->isTargetOpcode()) { + unsigned Opc = MainNode->getTargetOpcode(); + if (TII->isTwoAddrInstr(Opc)) { + SU->isTwoAddress = true; + SDNode *OpN = MainNode->getOperand(0).Val; + SUnit *OpSU = SUnitMap[OpN]; + if (OpSU) + OpSU->isDefNUseOperand = true; + } + } + + // Find all predecessors and successors of the group. + // Temporarily add N to make code simpler. + SU->FlaggedNodes.push_back(MainNode); + + for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { + SDNode *N = SU->FlaggedNodes[n]; + + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDNode *OpN = N->getOperand(i).Val; + if (isPassiveNode(OpN)) continue; // Not scheduled. + SUnit *OpSU = SUnitMap[OpN]; + assert(OpSU && "Node has no SUnit!"); + if (OpSU == SU) continue; // In the same group. + + MVT::ValueType OpVT = N->getOperand(i).getValueType(); + assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); + bool isChain = OpVT == MVT::Other; + + if (SU->Preds.insert(std::make_pair(OpSU, isChain)).second) { + if (!isChain) { + SU->NumPreds++; + SU->NumPredsLeft++; + } else { + SU->NumChainPredsLeft++; + } + } + if (OpSU->Succs.insert(std::make_pair(SU, isChain)).second) { + if (!isChain) { + OpSU->NumSuccs++; + OpSU->NumSuccsLeft++; + } else { + OpSU->NumChainSuccsLeft++; + } + } + } + } + + // Remove MainNode from FlaggedNodes again. + SU->FlaggedNodes.pop_back(); + } + + return; +} + +static void CalculateDepths(SUnit *SU, unsigned Depth) { + if (Depth > SU->Depth) SU->Depth = Depth; + for (std::set >::iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) + CalculateDepths(I->first, Depth+1); +} + +void ScheduleDAG::CalculateDepths() { + SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; + ::CalculateDepths(Entry, 0U); + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) + if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) { + ::CalculateDepths(&SUnits[i], 0U); + } +} + +static void CalculateHeights(SUnit *SU, unsigned Height) { + if (Height > SU->Height) SU->Height = Height; + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) + CalculateHeights(I->first, Height+1); +} +void ScheduleDAG::CalculateHeights() { + SUnit *Root = SUnitMap[DAG.getRoot().Val]; + ::CalculateHeights(Root, 0U); +} + /// CountResults - The results of target nodes have register or immediate /// operands first, then an optional chain, and optional flag operands (which do /// not go into the machine instrs.) @@ -348,6 +524,32 @@ TII->insertNoop(*BB, BB->end()); } +/// EmitSchedule - Emit the machine code in scheduled order. +void ScheduleDAG::EmitSchedule() { + std::map VRBaseMap; + for (unsigned i = 0, e = Sequence.size(); i != e; i++) { + if (SUnit *SU = Sequence[i]) { + for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) + EmitNode(SU->FlaggedNodes[j], VRBaseMap); + EmitNode(SU->Node, VRBaseMap); + } else { + // Null SUnit* is a noop. + EmitNoop(); + } + } +} + +/// dump - dump the schedule. +void ScheduleDAG::dumpSchedule() const { + for (unsigned i = 0, e = Sequence.size(); i != e; i++) { + if (SUnit *SU = Sequence[i]) + SU->dump(&DAG); + else + std::cerr << "**** NOOP ****\n"; + } +} + + /// Run - perform scheduling. /// MachineBasicBlock *ScheduleDAG::Run() { @@ -360,4 +562,53 @@ return BB; } +/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or +/// a group of nodes flagged together. +void SUnit::dump(const SelectionDAG *G) const { + std::cerr << "SU(" << NodeNum << "): "; + Node->dump(G); + std::cerr << "\n"; + if (FlaggedNodes.size() != 0) { + for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) { + std::cerr << " "; + FlaggedNodes[i]->dump(G); + std::cerr << "\n"; + } + } +} + +void SUnit::dumpAll(const SelectionDAG *G) const { + dump(G); + std::cerr << " # preds left : " << NumPredsLeft << "\n"; + std::cerr << " # succs left : " << NumSuccsLeft << "\n"; + std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n"; + std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n"; + std::cerr << " Latency : " << Latency << "\n"; + std::cerr << " Depth : " << Depth << "\n"; + std::cerr << " Height : " << Height << "\n"; + + if (Preds.size() != 0) { + std::cerr << " Predecessors:\n"; + for (std::set >::const_iterator I = Preds.begin(), + E = Preds.end(); I != E; ++I) { + if (I->second) + std::cerr << " ch "; + else + std::cerr << " val "; + I->first->dump(G); + } + } + if (Succs.size() != 0) { + std::cerr << " Successors:\n"; + for (std::set >::const_iterator I = Succs.begin(), + E = Succs.end(); I != E; ++I) { + if (I->second) + std::cerr << " ch "; + else + std::cerr << " val "; + I->first->dump(G); + } + } + std::cerr << "\n"; +} Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.57 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.58 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.57 Wed May 10 01:16:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu May 11 18:55:42 2006 @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// // -// This implements bottom-up and top-down list schedulers, using standard -// algorithms. The basic approach uses a priority queue of available nodes to -// schedule. One at a time, nodes are taken from the priority queue (thus in -// priority order), checked for legality to schedule, and emitted if legal. +// This implements a top-down list scheduler, using standard algorithms. +// The basic approach uses a priority queue of available nodes to schedule. +// One at a time, nodes are taken from the priority queue (thus in priority +// order), checked for legality to schedule, and emitted if legal. // // Nodes may not be legal to schedule either due to structural hazards (e.g. // pipeline or resource constraints) or because an input to the instruction has @@ -29,157 +29,20 @@ #include #include #include -#include -#include -#include "llvm/Support/CommandLine.h" using namespace llvm; namespace { - cl::opt SchedVertically("sched-vertically", cl::Hidden); - cl::opt SchedLowerDefNUse("sched-lower-defnuse", cl::Hidden); -} - -namespace { Statistic<> NumNoops ("scheduler", "Number of noops inserted"); Statistic<> NumStalls("scheduler", "Number of pipeline stalls"); - - /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or - /// a group of nodes flagged together. - struct SUnit { - SDNode *Node; // Representative node. - std::vector FlaggedNodes; // All nodes flagged to Node. - - // Preds/Succs - The SUnits before/after us in the graph. The boolean value - // is true if the edge is a token chain edge, false if it is a value edge. - std::set > Preds; // All sunit predecessors. - std::set > Succs; // All sunit successors. - - short NumPredsLeft; // # of preds not scheduled. - short NumSuccsLeft; // # of succs not scheduled. - short NumChainPredsLeft; // # of chain preds not scheduled. - short NumChainSuccsLeft; // # of chain succs not scheduled. - bool isTwoAddress : 1; // Is a two-address instruction. - bool isDefNUseOperand : 1; // Is a def&use operand. - bool isPending : 1; // True once pending. - bool isAvailable : 1; // True once available. - bool isScheduled : 1; // True once scheduled. - unsigned short Latency; // Node latency. - unsigned CycleBound; // Upper/lower cycle to be scheduled at. - unsigned Cycle; // Once scheduled, the cycle of the op. - unsigned NodeNum; // Entry # of node in the node vector. - - SUnit(SDNode *node, unsigned nodenum) - : Node(node), NumPredsLeft(0), NumSuccsLeft(0), - NumChainPredsLeft(0), NumChainSuccsLeft(0), - isTwoAddress(false), isDefNUseOperand(false), - isPending(false), isAvailable(false), isScheduled(false), - Latency(0), CycleBound(0), Cycle(0), NodeNum(nodenum) {} - - void dump(const SelectionDAG *G) const; - void dumpAll(const SelectionDAG *G) const; - }; -} - -void SUnit::dump(const SelectionDAG *G) const { - std::cerr << "SU(" << NodeNum << "): "; - Node->dump(G); - std::cerr << "\n"; - if (FlaggedNodes.size() != 0) { - for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) { - std::cerr << " "; - FlaggedNodes[i]->dump(G); - std::cerr << "\n"; - } - } -} - -void SUnit::dumpAll(const SelectionDAG *G) const { - dump(G); - - std::cerr << " # preds left : " << NumPredsLeft << "\n"; - std::cerr << " # succs left : " << NumSuccsLeft << "\n"; - std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n"; - std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n"; - std::cerr << " Latency : " << Latency << "\n"; - - if (Preds.size() != 0) { - std::cerr << " Predecessors:\n"; - for (std::set >::const_iterator I = Preds.begin(), - E = Preds.end(); I != E; ++I) { - if (I->second) - std::cerr << " ch "; - else - std::cerr << " val "; - I->first->dump(G); - } - } - if (Succs.size() != 0) { - std::cerr << " Successors:\n"; - for (std::set >::const_iterator I = Succs.begin(), - E = Succs.end(); I != E; ++I) { - if (I->second) - std::cerr << " ch "; - else - std::cerr << " val "; - I->first->dump(G); - } - } - std::cerr << "\n"; } -//===----------------------------------------------------------------------===// -/// SchedulingPriorityQueue - This interface is used to plug different -/// priorities computation algorithms into the list scheduler. It implements the -/// interface of a standard priority queue, where nodes are inserted in -/// arbitrary order and returned in priority order. The computation of the -/// priority and the representation of the queue are totally up to the -/// implementation to decide. -/// -namespace { -class SchedulingPriorityQueue { -public: - virtual ~SchedulingPriorityQueue() {} - - virtual void initNodes(const std::vector &SUnits) = 0; - virtual void releaseState() = 0; - - virtual bool empty() const = 0; - virtual void push(SUnit *U) = 0; - - virtual void push_all(const std::vector &Nodes) = 0; - virtual SUnit *pop() = 0; - - virtual void RemoveFromPriorityQueue(SUnit *SU) = 0; - - /// ScheduledNode - As each node is scheduled, this method is invoked. This - /// allows the priority function to adjust the priority of node that have - /// already been emitted. - virtual void ScheduledNode(SUnit *Node) {} -}; -} - - - namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGList - The actual list scheduler implementation. This supports -/// both top-down and bottom-up scheduling. +/// top-down scheduling. /// class ScheduleDAGList : public ScheduleDAG { private: - // SDNode to SUnit mapping (many to one). - std::map SUnitMap; - - // The schedule. Null SUnit*'s represent noop instructions. - std::vector Sequence; - - // The scheduling units. - std::vector SUnits; - - /// isBottomUp - This is true if the scheduling problem is bottom-up, false if - /// it is top-down. - bool isBottomUp; - /// AvailableQueue - The priority queue to use for the available SUnits. /// SchedulingPriorityQueue *AvailableQueue; @@ -194,20 +57,12 @@ /// HazardRec - The hazard recognizer to use. HazardRecognizer *HazardRec; - /// OpenNodes - Nodes with open live ranges, i.e. predecessors or successors - /// of scheduled nodes which are not themselves scheduled. - std::map > OpenNodes; - - /// RegPressureLimits - Keep track of upper limit of register pressure for - /// each register class that allows the scheduler to go into vertical mode. - std::map RegPressureLimits; - public: ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb, - const TargetMachine &tm, bool isbottomup, + const TargetMachine &tm, SchedulingPriorityQueue *availqueue, HazardRecognizer *HR) - : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), + : ScheduleDAG(dag, bb, tm), AvailableQueue(availqueue), HazardRec(HR) { } @@ -218,202 +73,16 @@ void Schedule(); - void dumpSchedule() const; - private: - SUnit *NewSUnit(SDNode *N); - void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle); void ReleaseSucc(SUnit *SuccSU, bool isChain); - void ScheduleNodeBottomUp(SUnit *SU, unsigned& CurCycle, bool Veritical=true); - void ScheduleVertically(SUnit *SU, unsigned& CurCycle); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); - void ListScheduleBottomUp(); - void BuildSchedUnits(); - void EmitSchedule(); }; } // end anonymous namespace HazardRecognizer::~HazardRecognizer() {} -/// NewSUnit - Creates a new SUnit and return a ptr to it. -SUnit *ScheduleDAGList::NewSUnit(SDNode *N) { - SUnits.push_back(SUnit(N, SUnits.size())); - return &SUnits.back(); -} - -/// BuildSchedUnits - Build SUnits from the selection dag that we are input. -/// This SUnit graph is similar to the SelectionDAG, but represents flagged -/// together nodes with a single SUnit. -void ScheduleDAGList::BuildSchedUnits() { - // Reserve entries in the vector for each of the SUnits we are creating. This - // ensure that reallocation of the vector won't happen, so SUnit*'s won't get - // invalidated. - SUnits.reserve(std::distance(DAG.allnodes_begin(), DAG.allnodes_end())); - - const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); - - for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(), - E = DAG.allnodes_end(); NI != E; ++NI) { - if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. - continue; - - // If this node has already been processed, stop now. - if (SUnitMap[NI]) continue; - - SUnit *NodeSUnit = NewSUnit(NI); - - // See if anything is flagged to this node, if so, add them to flagged - // nodes. Nodes can have at most one flag input and one flag output. Flags - // are required the be the last operand and result of a node. - - // Scan up, adding flagged preds to FlaggedNodes. - SDNode *N = NI; - while (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { - N = N->getOperand(N->getNumOperands()-1).Val; - NodeSUnit->FlaggedNodes.push_back(N); - SUnitMap[N] = NodeSUnit; - } - - // Scan down, adding this node and any flagged succs to FlaggedNodes if they - // have a user of the flag operand. - N = NI; - while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { - SDOperand FlagVal(N, N->getNumValues()-1); - - // There are either zero or one users of the Flag result. - bool HasFlagUse = false; - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); - UI != E; ++UI) - if (FlagVal.isOperand(*UI)) { - HasFlagUse = true; - NodeSUnit->FlaggedNodes.push_back(N); - SUnitMap[N] = NodeSUnit; - N = *UI; - break; - } - if (!HasFlagUse) break; - } - - // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. - // Update the SUnit - NodeSUnit->Node = N; - SUnitMap[N] = NodeSUnit; - - // Compute the latency for the node. We use the sum of the latencies for - // all nodes flagged together into this SUnit. - if (InstrItins.isEmpty()) { - // No latency information. - NodeSUnit->Latency = 1; - } else { - NodeSUnit->Latency = 0; - if (N->isTargetOpcode()) { - unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode()); - InstrStage *S = InstrItins.begin(SchedClass); - InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - NodeSUnit->Latency += S->Cycles; - } - for (unsigned i = 0, e = NodeSUnit->FlaggedNodes.size(); i != e; ++i) { - SDNode *FNode = NodeSUnit->FlaggedNodes[i]; - if (FNode->isTargetOpcode()) { - unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode()); - InstrStage *S = InstrItins.begin(SchedClass); - InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - NodeSUnit->Latency += S->Cycles; - } - } - } - } - - // Pass 2: add the preds, succs, etc. - for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { - SUnit *SU = &SUnits[su]; - SDNode *MainNode = SU->Node; - - if (MainNode->isTargetOpcode()) { - unsigned Opc = MainNode->getTargetOpcode(); - if (TII->isTwoAddrInstr(Opc)) { - SU->isTwoAddress = true; - SDNode *OpN = MainNode->getOperand(0).Val; - SUnit *OpSU = SUnitMap[OpN]; - if (OpSU) - OpSU->isDefNUseOperand = true; - } - } - - // Find all predecessors and successors of the group. - // Temporarily add N to make code simpler. - SU->FlaggedNodes.push_back(MainNode); - - for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { - SDNode *N = SU->FlaggedNodes[n]; - - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - SDNode *OpN = N->getOperand(i).Val; - if (isPassiveNode(OpN)) continue; // Not scheduled. - SUnit *OpSU = SUnitMap[OpN]; - assert(OpSU && "Node has no SUnit!"); - if (OpSU == SU) continue; // In the same group. - - MVT::ValueType OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); - bool isChain = OpVT == MVT::Other; - - if (SU->Preds.insert(std::make_pair(OpSU, isChain)).second) { - if (!isChain) { - SU->NumPredsLeft++; - } else { - SU->NumChainPredsLeft++; - } - } - if (OpSU->Succs.insert(std::make_pair(SU, isChain)).second) { - if (!isChain) { - OpSU->NumSuccsLeft++; - } else { - OpSU->NumChainSuccsLeft++; - } - } - } - } - - // Remove MainNode from FlaggedNodes again. - SU->FlaggedNodes.pop_back(); - } - - DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) - SUnits[su].dumpAll(&DAG)); - return; -} - -/// EmitSchedule - Emit the machine code in scheduled order. -void ScheduleDAGList::EmitSchedule() { - std::map VRBaseMap; - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) { - for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) - EmitNode(SU->FlaggedNodes[j], VRBaseMap); - EmitNode(SU->Node, VRBaseMap); - } else { - // Null SUnit* is a noop. - EmitNoop(); - } - } -} - -/// dump - dump the schedule. -void ScheduleDAGList::dumpSchedule() const { - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) - SU->dump(&DAG); - else - std::cerr << "**** NOOP ****\n"; - } -} - /// Schedule - Schedule the DAG using list scheduling. void ScheduleDAGList::Schedule() { DEBUG(std::cerr << "********** List Scheduling **********\n"); @@ -423,11 +92,7 @@ AvailableQueue->initNodes(SUnits); - // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. - if (isBottomUp) - ListScheduleBottomUp(); - else - ListScheduleTopDown(); + ListScheduleTopDown(); AvailableQueue->releaseState(); @@ -440,273 +105,6 @@ } //===----------------------------------------------------------------------===// -// Bottom-Up Scheduling -//===----------------------------------------------------------------------===// - -static const TargetRegisterClass *getRegClass(SUnit *SU, - const TargetInstrInfo *TII, - const MRegisterInfo *MRI, - SSARegMap *RegMap) { - if (SU->Node->isTargetOpcode()) { - unsigned Opc = SU->Node->getTargetOpcode(); - const TargetInstrDescriptor &II = TII->get(Opc); - return II.OpInfo->RegClass; - } else { - assert(SU->Node->getOpcode() == ISD::CopyFromReg); - unsigned SrcReg = cast(SU->Node->getOperand(1))->getReg(); - if (MRegisterInfo::isVirtualRegister(SrcReg)) - return RegMap->getRegClass(SrcReg); - else { - for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(), - E = MRI->regclass_end(); I != E; ++I) - if ((*I)->hasType(SU->Node->getValueType(0)) && - (*I)->contains(SrcReg)) - return *I; - assert(false && "Couldn't find register class for reg copy!"); - } - return NULL; - } -} - -static unsigned getNumResults(SUnit *SU) { - unsigned NumResults = 0; - for (unsigned i = 0, e = SU->Node->getNumValues(); i != e; ++i) { - MVT::ValueType VT = SU->Node->getValueType(i); - if (VT != MVT::Other && VT != MVT::Flag) - NumResults++; - } - return NumResults; -} - -/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to -/// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain, - unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); - - if (!isChain) - PredSU->NumSuccsLeft--; - else - PredSU->NumChainSuccsLeft--; - -#ifndef NDEBUG - if (PredSU->NumSuccsLeft < 0 || PredSU->NumChainSuccsLeft < 0) { - std::cerr << "*** List scheduling failed! ***\n"; - PredSU->dump(&DAG); - std::cerr << " has been released too many times!\n"; - assert(0); - } -#endif - - if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) { - // EntryToken has to go last! Special case it here. - if (PredSU->Node->getOpcode() != ISD::EntryToken) { - PredSU->isAvailable = true; - AvailableQueue->push(PredSU); - } - } - - if (getNumResults(PredSU) > 0) { - const TargetRegisterClass *RegClass = getRegClass(PredSU, TII, MRI, RegMap); - OpenNodes[RegClass].insert(PredSU); - } -} - -/// SharesOperandWithTwoAddr - Check if there is a unscheduled two-address node -/// with which SU shares an operand. If so, returns the node. -static SUnit *SharesOperandWithTwoAddr(SUnit *SU) { - assert(!SU->isTwoAddress && "Node cannot be two-address op"); - for (std::set >::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) { - if (I->second) continue; - SUnit *PredSU = I->first; - for (std::set >::iterator II = - PredSU->Succs.begin(), EE = PredSU->Succs.end(); II != EE; ++II) { - if (II->second) continue; - SUnit *SSU = II->first; - if (SSU->isTwoAddress && !SSU->isScheduled) { - return SSU; - } - } - } - return NULL; -} - -static bool isFloater(const SUnit *SU) { - unsigned Opc = SU->Node->getOpcode(); - return (Opc != ISD::CopyFromReg && SU->NumPredsLeft == 0); -} - -static bool isSimpleFloaterUse(const SUnit *SU) { - unsigned NumOps = 0; - for (std::set >::const_iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) { - if (I->second) continue; - if (++NumOps > 1) - return false; - if (!isFloater(I->first)) - return false; - } - return true; -} - -/// ScheduleVertically - Schedule vertically. That is, follow up the D&U chain -/// (of two-address code) and schedule floaters aggressively. -void ScheduleDAGList::ScheduleVertically(SUnit *SU, unsigned& CurCycle) { - // Try scheduling Def&Use operand if register pressure is low. - const TargetRegisterClass *RegClass = getRegClass(SU, TII, MRI, RegMap); - unsigned Pressure = OpenNodes[RegClass].size(); - unsigned Limit = RegPressureLimits[RegClass]; - - // See if we can schedule any predecessor that takes no registers. - for (std::set >::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) { - if (I->second) continue; - - SUnit *PredSU = I->first; - if (!PredSU->isAvailable || PredSU->isScheduled) - continue; - - if (isFloater(PredSU)) { - DEBUG(std::cerr<<"*** Scheduling floater\n"); - AvailableQueue->RemoveFromPriorityQueue(PredSU); - ScheduleNodeBottomUp(PredSU, CurCycle, false); - } - } - - SUnit *DUSU = NULL; - if (SU->isTwoAddress && Pressure < Limit) { - DUSU = SUnitMap[SU->Node->getOperand(0).Val]; - if (!DUSU->isAvailable || DUSU->isScheduled) - DUSU = NULL; - else if (!DUSU->isTwoAddress) { - SUnit *SSU = SharesOperandWithTwoAddr(DUSU); - if (SSU && SSU->isAvailable) { - AvailableQueue->RemoveFromPriorityQueue(SSU); - ScheduleNodeBottomUp(SSU, CurCycle, false); - Pressure = OpenNodes[RegClass].size(); - if (Pressure >= Limit) - DUSU = NULL; - } - } - } - - if (DUSU) { - DEBUG(std::cerr<<"*** Low register pressure: scheduling D&U operand\n"); - AvailableQueue->RemoveFromPriorityQueue(DUSU); - ScheduleNodeBottomUp(DUSU, CurCycle, false); - Pressure = OpenNodes[RegClass].size(); - ScheduleVertically(DUSU, CurCycle); - } -} - -/// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending -/// count of its predecessors. If a predecessor pending count is zero, add it to -/// the Available queue. -void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU, unsigned& CurCycle, - bool Vertical) { - DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: "); - DEBUG(SU->dump(&DAG)); - SU->Cycle = CurCycle; - - AvailableQueue->ScheduledNode(SU); - Sequence.push_back(SU); - - // Bottom up: release predecessors - for (std::set >::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) - ReleasePred(I->first, I->second, CurCycle); - SU->isScheduled = true; - CurCycle++; - - if (getNumResults(SU) != 0) { - const TargetRegisterClass *RegClass = getRegClass(SU, TII, MRI, RegMap); - OpenNodes[RegClass].erase(SU); - - if (SchedVertically && Vertical) - ScheduleVertically(SU, CurCycle); - } -} - -/// isReady - True if node's lower cycle bound is less or equal to the current -/// scheduling cycle. Always true if all nodes have uniform latency 1. -static inline bool isReady(SUnit *SU, unsigned CurCycle) { - return SU->CycleBound <= CurCycle; -} - -/// ListScheduleBottomUp - The main loop of list scheduling for bottom-up -/// schedulers. -void ScheduleDAGList::ListScheduleBottomUp() { - // Determine rough register pressure limit. - for (MRegisterInfo::regclass_iterator RCI = MRI->regclass_begin(), - E = MRI->regclass_end(); RCI != E; ++RCI) { - const TargetRegisterClass *RC = *RCI; - unsigned Limit = RC->getNumRegs(); - Limit = (Limit > 2) ? Limit - 2 : 0; - std::map::iterator RPI = - RegPressureLimits.find(RC); - if (RPI == RegPressureLimits.end()) - RegPressureLimits[RC] = Limit; - else { - unsigned &OldLimit = RegPressureLimits[RC]; - if (Limit < OldLimit) - OldLimit = Limit; - } - } - - unsigned CurCycle = 0; - // Add root to Available queue. - AvailableQueue->push(SUnitMap[DAG.getRoot().Val]); - - // While Available queue is not empty, grab the node with the highest - // priority. If it is not ready put it back. Schedule the node. - std::vector NotReady; - SUnit *CurNode = NULL; - while (!AvailableQueue->empty()) { - SUnit *CurNode = AvailableQueue->pop(); - while (!isReady(CurNode, CurCycle)) { - NotReady.push_back(CurNode); - CurNode = AvailableQueue->pop(); - } - - // Add the nodes that aren't ready back onto the available list. - AvailableQueue->push_all(NotReady); - NotReady.clear(); - - ScheduleNodeBottomUp(CurNode, CurCycle); - } - - // Add entry node last - if (DAG.getEntryNode().Val != DAG.getRoot().Val) { - SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; - Sequence.push_back(Entry); - } - - // Reverse the order if it is bottom up. - std::reverse(Sequence.begin(), Sequence.end()); - - -#ifndef NDEBUG - // Verify that all SUnits were scheduled. - bool AnyNotSched = false; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - if (SUnits[i].NumSuccsLeft != 0 || SUnits[i].NumChainSuccsLeft != 0) { - if (!AnyNotSched) - std::cerr << "*** List scheduling failed! ***\n"; - SUnits[i].dump(&DAG); - std::cerr << "has not been scheduled!\n"; - AnyNotSched = true; - } - } - assert(!AnyNotSched); -#endif -} - -//===----------------------------------------------------------------------===// // Top-Down Scheduling //===----------------------------------------------------------------------===// @@ -885,284 +283,6 @@ } //===----------------------------------------------------------------------===// -// RegReductionPriorityQueue Implementation -//===----------------------------------------------------------------------===// -// -// This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers -// to reduce register pressure. -// -namespace { - template - class RegReductionPriorityQueue; - - /// Sorting functions for the Available queue. - struct ls_rr_sort : public std::binary_function { - RegReductionPriorityQueue *SPQ; - ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} - ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} - - bool operator()(const SUnit* left, const SUnit* right) const; - }; -} // end anonymous namespace - -namespace { - template - class RegReductionPriorityQueue : public SchedulingPriorityQueue { - // SUnits - The SUnits for the current graph. - const std::vector *SUnits; - - // SethiUllmanNumbers - The SethiUllman number for each node. - std::vector SethiUllmanNumbers; - - std::priority_queue, SF> Queue; - public: - RegReductionPriorityQueue() : - Queue(ls_rr_sort(this)) {} - - void initNodes(const std::vector &sunits) { - SUnits = &sunits; - // Add pseudo dependency edges for two-address nodes. - if (SchedLowerDefNUse) - AddPseudoTwoAddrDeps(); - // Calculate node priorities. - CalculatePriorities(); - } - void releaseState() { - SUnits = 0; - SethiUllmanNumbers.clear(); - } - - int getSethiUllmanNumber(unsigned NodeNum) const { - assert(NodeNum < SethiUllmanNumbers.size()); - return SethiUllmanNumbers[NodeNum]; - } - - bool empty() const { return Queue.empty(); } - - void push(SUnit *U) { - Queue.push(U); - } - void push_all(const std::vector &Nodes) { - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - Queue.push(Nodes[i]); - } - - SUnit *pop() { - SUnit *V = Queue.top(); - Queue.pop(); - return V; - } - - /// RemoveFromPriorityQueue - This is a really inefficient way to remove a - /// node from a priority queue. We should roll our own heap to make this - /// better or something. - void RemoveFromPriorityQueue(SUnit *SU) { - std::vector Temp; - - assert(!Queue.empty() && "Not in queue!"); - while (Queue.top() != SU) { - Temp.push_back(Queue.top()); - Queue.pop(); - assert(!Queue.empty() && "Not in queue!"); - } - - // Remove the node from the PQ. - Queue.pop(); - - // Add all the other nodes back. - for (unsigned i = 0, e = Temp.size(); i != e; ++i) - Queue.push(Temp[i]); - } - - private: - void AddPseudoTwoAddrDeps(); - void CalculatePriorities(); - int CalcNodePriority(const SUnit *SU); - }; -} - -bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { - unsigned LeftNum = left->NodeNum; - unsigned RightNum = right->NodeNum; - bool LIsTarget = left->Node->isTargetOpcode(); - bool RIsTarget = right->Node->isTargetOpcode(); - int LPriority = SPQ->getSethiUllmanNumber(LeftNum); - int RPriority = SPQ->getSethiUllmanNumber(RightNum); - bool LIsFloater = LIsTarget && (LPriority == 1 || LPriority == 0); - bool RIsFloater = RIsTarget && (RPriority == 1 || RPriority == 0); - int LBonus = 0; - int RBonus = 0; - - // Schedule floaters (e.g. load from some constant address) and those nodes - // with a single predecessor each first. They maintain / reduce register - // pressure. - if (LIsFloater) - LBonus += 2; - if (RIsFloater) - RBonus += 2; - - if (!SchedLowerDefNUse) { - // Special tie breaker: if two nodes share a operand, the one that use it - // as a def&use operand is preferred. - if (LIsTarget && RIsTarget) { - if (left->isTwoAddress && !right->isTwoAddress) { - SDNode *DUNode = left->Node->getOperand(0).Val; - if (DUNode->isOperand(right->Node)) - LBonus += 2; - } - if (!left->isTwoAddress && right->isTwoAddress) { - SDNode *DUNode = right->Node->getOperand(0).Val; - if (DUNode->isOperand(left->Node)) - RBonus += 2; - } - } - } - - if (LPriority+LBonus < RPriority+RBonus) - return true; - else if (LPriority+LBonus == RPriority+RBonus) - if (left->NumPredsLeft > right->NumPredsLeft) - return true; - else if (left->NumPredsLeft+LBonus == right->NumPredsLeft+RBonus) - if (left->CycleBound > right->CycleBound) - return true; - return false; -} - -static inline bool isCopyFromLiveIn(const SUnit *SU) { - SDNode *N = SU->Node; - return N->getOpcode() == ISD::CopyFromReg && - N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag; -} - -// FIXME: This is probably too slow! -static void isReachable(SUnit *SU, SUnit *TargetSU, - std::set &Visited, bool &Reached) { - if (Reached) return; - if (SU == TargetSU) { - Reached = true; - return; - } - if (!Visited.insert(SU).second) return; - - for (std::set >::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) - isReachable(I->first, TargetSU, Visited, Reached); -} - -static bool isReachable(SUnit *SU, SUnit *TargetSU) { - std::set Visited; - bool Reached = false; - isReachable(SU, TargetSU, Visited, Reached); - return Reached; -} - -static SUnit *getDefUsePredecessor(SUnit *SU) { - SDNode *DU = SU->Node->getOperand(0).Val; - for (std::set >::iterator - I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - if (I->second) continue; // ignore chain preds - SUnit *PredSU = I->first; - if (PredSU->Node == DU) - return PredSU; - } - - // Must be flagged. - return NULL; -} - -static bool canClobber(SUnit *SU, SUnit *Op) { - if (SU->isTwoAddress) - return Op == getDefUsePredecessor(SU); - return false; -} - -/// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses -/// it as a def&use operand. Add a pseudo control edge from it to the other -/// node (if it won't create a cycle) so the two-address one will be scheduled -/// first (lower in the schedule). -template -void RegReductionPriorityQueue::AddPseudoTwoAddrDeps() { - for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { - SUnit *SU = (SUnit *)&((*SUnits)[i]); - SDNode *Node = SU->Node; - if (!Node->isTargetOpcode()) - continue; - - if (SU->isTwoAddress) { - unsigned Depth = SU->Node->getNodeDepth(); - SUnit *DUSU = getDefUsePredecessor(SU); - if (!DUSU) continue; - - for (std::set >::iterator I = DUSU->Succs.begin(), - E = DUSU->Succs.end(); I != E; ++I) { - SUnit *SuccSU = I->first; - if (SuccSU != SU && !canClobber(SuccSU, DUSU)) { - if (SuccSU->Node->getNodeDepth() <= Depth+2 && - !isReachable(SuccSU, SU)) { - DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum - << " to SU #" << SuccSU->NodeNum << "\n"); - if (SU->Preds.insert(std::make_pair(SuccSU, true)).second) - SU->NumChainPredsLeft++; - if (SuccSU->Succs.insert(std::make_pair(SU, true)).second) - SuccSU->NumChainSuccsLeft++; - } - } - } - } - } -} - -/// CalcNodePriority - Priority is the Sethi Ullman number. -/// Smaller number is the higher priority. -template -int RegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) { - int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; - if (SethiUllmanNumber != 0) - return SethiUllmanNumber; - - unsigned Opc = SU->Node->getOpcode(); - if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg) - SethiUllmanNumber = INT_MAX - 10; - else if (SU->NumSuccsLeft == 0) - // If SU does not have a use, i.e. it doesn't produce a value that would - // be consumed (e.g. store), then it terminates a chain of computation. - // Give it a small SethiUllman number so it will be scheduled right before its - // predecessors that it doesn't lengthen their live ranges. - SethiUllmanNumber = INT_MIN + 10; - else if (SU->NumPredsLeft == 0 && - (Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU))) - SethiUllmanNumber = 1; - else { - int Extra = 0; - for (std::set >::const_iterator - I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - if (I->second) continue; // ignore chain preds - SUnit *PredSU = I->first; - int PredSethiUllman = CalcNodePriority(PredSU); - if (PredSethiUllman > SethiUllmanNumber) { - SethiUllmanNumber = PredSethiUllman; - Extra = 0; - } else if (PredSethiUllman == SethiUllmanNumber && !I->second) - Extra++; - } - - SethiUllmanNumber += Extra; - } - - return SethiUllmanNumber; -} - -/// CalculatePriorities - Calculate priorities of all scheduling units. -template -void RegReductionPriorityQueue::CalculatePriorities() { - SethiUllmanNumbers.assign(SUnits->size(), 0); - - for (unsigned i = 0, e = SUnits->size(); i != e; ++i) - CalcNodePriority(&(*SUnits)[i]); -} - -//===----------------------------------------------------------------------===// // LatencyPriorityQueue Implementation //===----------------------------------------------------------------------===// // @@ -1240,6 +360,17 @@ return V; } + // ScheduledNode - As nodes are scheduled, we look to see if there are any + // successor nodes that have a single unscheduled predecessor. If so, that + // single predecessor has a higher priority, since scheduling it will make + // the node available. + void ScheduledNode(SUnit *Node); + +private: + void CalculatePriorities(); + int CalcLatency(const SUnit &SU); + void AdjustPriorityOfUnscheduledPreds(SUnit *SU); + /// RemoveFromPriorityQueue - This is a really inefficient way to remove a /// node from a priority queue. We should roll our own heap to make this /// better or something. @@ -1260,17 +391,6 @@ for (unsigned i = 0, e = Temp.size(); i != e; ++i) Queue.push(Temp[i]); } - - // ScheduledNode - As nodes are scheduled, we look to see if there are any - // successor nodes that have a single unscheduled predecessor. If so, that - // single predecessor has a higher priority, since scheduling it will make - // the node available. - void ScheduledNode(SUnit *Node); - -private: - void CalculatePriorities(); - int CalcLatency(const SUnit &SU); - void AdjustPriorityOfUnscheduledPreds(SUnit *SU); }; } @@ -1388,19 +508,12 @@ // Public Constructor Functions //===----------------------------------------------------------------------===// -llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, - MachineBasicBlock *BB) { - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, - new RegReductionPriorityQueue(), - new HazardRecognizer()); -} - /// createTDListDAGScheduler - This creates a top-down list scheduler with the /// specified hazard recognizer. ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB, HazardRecognizer *HR) { - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, + return new ScheduleDAGList(DAG, BB, DAG.getTarget(), new LatencyPriorityQueue(), HR); } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.237 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.238 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.237 Mon May 8 11:51:36 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu May 11 18:55:42 2006 @@ -58,36 +58,28 @@ static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0; #endif -// Scheduling heuristics -enum SchedHeuristics { - defaultScheduling, // Let the target specify its preference. - noScheduling, // No scheduling, emit breadth first sequence. - simpleScheduling, // Two pass, min. critical path, max. utilization. - simpleNoItinScheduling, // Same as above exact using generic latency. - listSchedulingBURR, // Bottom up reg reduction list scheduling. - listSchedulingTD // Top-down list scheduler. -}; - namespace { - cl::opt + cl::opt ISHeuristic( "sched", cl::desc("Choose scheduling style"), - cl::init(defaultScheduling), + cl::init(ScheduleDAG::defaultScheduling), cl::values( - clEnumValN(defaultScheduling, "default", + clEnumValN(ScheduleDAG::defaultScheduling, "default", "Target preferred scheduling style"), - clEnumValN(noScheduling, "none", + clEnumValN(ScheduleDAG::noScheduling, "none", "No scheduling: breadth first sequencing"), - clEnumValN(simpleScheduling, "simple", + clEnumValN(ScheduleDAG::simpleScheduling, "simple", "Simple two pass scheduling: minimize critical path " "and maximize processor utilization"), - clEnumValN(simpleNoItinScheduling, "simple-noitin", + clEnumValN(ScheduleDAG::simpleNoItinScheduling, "simple-noitin", "Simple two pass scheduling: Same as simple " "except using generic latency"), - clEnumValN(listSchedulingBURR, "list-burr", - "Bottom up register reduction list scheduling"), - clEnumValN(listSchedulingTD, "list-td", + clEnumValN(ScheduleDAG::listSchedulingBURR, "list-burr", + "Bottom-up register reduction list scheduling"), + clEnumValN(ScheduleDAG::listSchedulingTDRR, "list-tdrr", + "Top-down register reduction list scheduling"), + clEnumValN(ScheduleDAG::listSchedulingTD, "list-td", "Top-down list scheduler"), clEnumValEnd)); } // namespace @@ -3418,7 +3410,7 @@ switch (ISHeuristic) { default: assert(0 && "Unrecognized scheduling heuristic"); - case defaultScheduling: + case ScheduleDAG::defaultScheduling: if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer()); else { @@ -3427,19 +3419,22 @@ SL = createBURRListDAGScheduler(DAG, BB); } break; - case noScheduling: + case ScheduleDAG::noScheduling: SL = createBFS_DAGScheduler(DAG, BB); break; - case simpleScheduling: + case ScheduleDAG::simpleScheduling: SL = createSimpleDAGScheduler(false, DAG, BB); break; - case simpleNoItinScheduling: + case ScheduleDAG::simpleNoItinScheduling: SL = createSimpleDAGScheduler(true, DAG, BB); break; - case listSchedulingBURR: + case ScheduleDAG::listSchedulingBURR: SL = createBURRListDAGScheduler(DAG, BB); break; - case listSchedulingTD: + case ScheduleDAG::listSchedulingTDRR: + SL = createTDRRListDAGScheduler(DAG, BB); + break; + case ScheduleDAG::listSchedulingTD: SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer()); break; } From lattner at cs.uiuc.edu Thu May 11 18:57:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 May 2006 18:57:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200605112357.SAA26703@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JITEmitter.cpp updated: 1.98 -> 1.99 --- Log message: Fix some bugs in the freelist manipulation code. Finally, implement ExecutionEngine::freeMachineCodeForFunction. --- Diffs of the changes: (+33 -12) JITEmitter.cpp | 45 +++++++++++++++++++++++++++++++++------------ 1 files changed, 33 insertions(+), 12 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.98 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.99 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.98 Thu May 11 18:08:08 2006 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Thu May 11 18:56:57 2006 @@ -78,9 +78,9 @@ return (FreeRangeHeader*)((char*)this-PrevSize); } - /// MakeFreeBlock - Turn an allocated block into a free block, adjusting + /// FreeBlock - Turn an allocated block into a free block, adjusting /// bits in the object headers, and adding an end of region memory block. - FreeRangeHeader &MakeFreeBlock(FreeRangeHeader *FreeList); + FreeRangeHeader *FreeBlock(FreeRangeHeader *FreeList); /// TrimAllocationToSize - If this allocated block is significantly larger /// than NewSize, split it into two pieces (where the former is NewSize @@ -146,19 +146,27 @@ return RemoveFromFreeList(); } -/// MakeFreeBlock - Turn an allocated block into a free block, adjusting +/// FreeBlock - Turn an allocated block into a free block, adjusting /// bits in the object headers, and adding an end of region memory block. /// If possible, coallesce this block with neighboring blocks. Return the -/// FreeRangeHeader this block ends up in, which may be != this if it got -/// coallesced. -FreeRangeHeader &MemoryRangeHeader::MakeFreeBlock(FreeRangeHeader *FreeList) { +/// FreeRangeHeader to allocate from. +FreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) { MemoryRangeHeader *FollowingBlock = &getBlockAfter(); assert(ThisAllocated && "This block is already allocated!"); assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); + FreeRangeHeader *FreeListToReturn = FreeList; + // If the block after this one is free, merge it into this block. if (!FollowingBlock->ThisAllocated) { FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; + // "FreeList" always needs to be a valid free block. If we're about to + // coallesce with it, update our notion of what the free list is. + if (&FollowingFreeBlock == FreeList) { + FreeList = FollowingFreeBlock.Next; + FreeListToReturn = 0; + assert(&FollowingFreeBlock != FreeList && "No tombstone block?"); + } FollowingFreeBlock.RemoveFromFreeList(); // Include the following block into this one. @@ -174,7 +182,7 @@ if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); - return *PrevFreeBlock; + return FreeListToReturn ? FreeListToReturn : PrevFreeBlock; } // Otherwise, mark this block free. @@ -188,7 +196,7 @@ // Add a marker at the end of the block, indicating the size of this free // block. FreeBlock.SetEndOfBlockSizeMarker(); - return FreeBlock; + return FreeListToReturn ? FreeListToReturn : &FreeBlock; } /// GrowBlock - The block after this block just got deallocated. Merge it @@ -197,6 +205,7 @@ assert(NewSize > BlockSize && "Not growing block?"); BlockSize = NewSize; SetEndOfBlockSizeMarker(); + getBlockAfter().PrevAllocated = 0; } /// TrimAllocationToSize - If this allocated block is significantly larger @@ -304,7 +313,19 @@ /// deallocateMemForFunction - Deallocate all memory for the specified /// function body. void deallocateMemForFunction(const Function *F) { + std::map::iterator + I = FunctionBlocks.find(F); + if (I == FunctionBlocks.end()) return; + + // Find the block that is allocated for this function. + MemoryRangeHeader *MemRange = I->second; + assert(MemRange->ThisAllocated && "Block isn't allocated!"); + + // Free the memory. + FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); + // Finally, remove this entry from FunctionBlocks. + FunctionBlocks.erase(I); } }; } @@ -349,9 +370,9 @@ /// Add a tiny allocated region so that Mem2 is never coallesced away. MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; - Mem2->ThisAllocated = 1; - Mem2->PrevAllocated = 0; - Mem2->BlockSize = (char*)Mem2 - (char*)Mem1; + Mem1->ThisAllocated = 1; + Mem1->PrevAllocated = 0; + Mem1->BlockSize = (char*)Mem2 - (char*)Mem1; // Add a FreeRangeHeader to the start of the function body region, indicating // that the space is free. Mark the previous block allocated so we never look @@ -359,7 +380,7 @@ FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr; Mem0->ThisAllocated = 0; Mem0->PrevAllocated = 1; - Mem0->BlockSize = (unsigned char*)Mem1-(unsigned char*)Mem0; + Mem0->BlockSize = (char*)Mem1-(char*)Mem0; Mem0->SetEndOfBlockSizeMarker(); Mem0->AddToFreeList(Mem2); From lattner at cs.uiuc.edu Thu May 11 19:03:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 11 May 2006 19:03:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200605120003.TAA26797@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JITEmitter.cpp updated: 1.99 -> 1.100 --- Log message: For extra sanity checking, fill free'd memory with garbage so we know that people aren't reusing machine code buffers at all. --- Diffs of the changes: (+3 -0) JITEmitter.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.99 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.100 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.99 Thu May 11 18:56:57 2006 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Thu May 11 19:03:12 2006 @@ -321,6 +321,9 @@ MemoryRangeHeader *MemRange = I->second; assert(MemRange->ThisAllocated && "Block isn't allocated!"); + // Fill the buffer with garbage! + DEBUG(memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange))); + // Free the memory. FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); From evan.cheng at apple.com Thu May 11 20:46:39 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 20:46:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetInstrInfo.cpp Message-ID: <200605120146.UAA27193@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetInstrInfo.cpp updated: 1.18 -> 1.19 --- Log message: Typo! How did we commute nodes before?! --- Diffs of the changes: (+1 -1) TargetInstrInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/TargetInstrInfo.cpp diff -u llvm/lib/Target/TargetInstrInfo.cpp:1.18 llvm/lib/Target/TargetInstrInfo.cpp:1.19 --- llvm/lib/Target/TargetInstrInfo.cpp:1.18 Thu May 4 12:52:23 2006 +++ llvm/lib/Target/TargetInstrInfo.cpp Thu May 11 20:46:26 2006 @@ -45,7 +45,7 @@ assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() && "This only knows how to commute register operands so far"); unsigned Reg1 = MI->getOperand(1).getReg(); - unsigned Reg2 = MI->getOperand(1).getReg(); + unsigned Reg2 = MI->getOperand(2).getReg(); MI->getOperand(2).setReg(Reg1); MI->getOperand(1).setReg(Reg2); return MI; From evan.cheng at apple.com Thu May 11 20:58:37 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 20:58:37 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200605120158.UAA27312@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.24 -> 1.25 --- Log message: Add capability to scheduler to commute nodes for profit. If a two-address code whose first operand has uses below, it should be commuted when possible. --- Diffs of the changes: (+5 -4) ScheduleDAG.h | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.24 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.25 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.24 Thu May 11 18:55:42 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Thu May 11 20:58:24 2006 @@ -91,7 +91,7 @@ short NumChainPredsLeft; // # of chain preds not scheduled. short NumChainSuccsLeft; // # of chain succs not scheduled. bool isTwoAddress : 1; // Is a two-address instruction. - bool isDefNUseOperand : 1; // Is a def&use operand. + bool isCommutable : 1; // Is a commutable instruction. bool isPending : 1; // True once pending. bool isAvailable : 1; // True once available. bool isScheduled : 1; // True once scheduled. @@ -105,7 +105,7 @@ SUnit(SDNode *node, unsigned nodenum) : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), - isTwoAddress(false), isDefNUseOperand(false), + isTwoAddress(false), isCommutable(false), isPending(false), isAvailable(false), isScheduled(false), Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0), NodeNum(nodenum) {} @@ -162,10 +162,11 @@ const MRegisterInfo *MRI; // Target processor register info SSARegMap *RegMap; // Virtual/real register map MachineConstantPool *ConstPool; // Target constant pool - std::vector Sequence; // The schedule. Null SUnit*'s represent - // noop instructions. + std::vector Sequence; // The schedule. Null SUnit*'s + // represent noop instructions. std::map SUnitMap; // SDNode to SUnit mapping (n -> 1). std::vector SUnits; // The scheduling units. + std::set CommuteSet; // Nodes the should be commuted. ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm) From evan.cheng at apple.com Thu May 11 20:58:38 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 20:58:38 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200605120158.UAA27317@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.85 -> 1.86 --- Log message: Add capability to scheduler to commute nodes for profit. If a two-address code whose first operand has uses below, it should be commuted when possible. --- Diffs of the changes: (+3 -0) TargetInstrInfo.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.85 llvm/include/llvm/Target/TargetInstrInfo.h:1.86 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.85 Thu Apr 20 13:32:02 2006 +++ llvm/include/llvm/Target/TargetInstrInfo.h Thu May 11 20:58:24 2006 @@ -165,6 +165,9 @@ bool isTwoAddrInstr(MachineOpCode Opcode) const { return get(Opcode).Flags & M_2_ADDR_FLAG; } + bool isCommutableInstr(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_COMMUTABLE; + } bool isTerminatorInstr(unsigned Opcode) const { return get(Opcode).Flags & M_TERMINATOR_FLAG; } From evan.cheng at apple.com Thu May 11 20:58:38 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 20:58:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGRRList.cpp Message-ID: <200605120158.UAA27320@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.87 -> 1.88 ScheduleDAGRRList.cpp updated: 1.1 -> 1.2 --- Log message: Add capability to scheduler to commute nodes for profit. If a two-address code whose first operand has uses below, it should be commuted when possible. --- Diffs of the changes: (+61 -31) ScheduleDAG.cpp | 22 ++++++++++----- ScheduleDAGRRList.cpp | 70 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 31 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.87 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.88 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.87 Thu May 11 18:55:42 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu May 11 20:58:24 2006 @@ -120,13 +120,10 @@ if (MainNode->isTargetOpcode()) { unsigned Opc = MainNode->getTargetOpcode(); - if (TII->isTwoAddrInstr(Opc)) { + if (TII->isTwoAddrInstr(Opc)) SU->isTwoAddress = true; - SDNode *OpN = MainNode->getOperand(0).Val; - SUnit *OpSU = SUnitMap[OpN]; - if (OpSU) - OpSU->isDefNUseOperand = true; - } + if (TII->isCommutableInstr(Opc)) + SU->isCommutable = true; } // Find all predecessors and successors of the group. @@ -391,7 +388,18 @@ // instruction as appropriate. for (unsigned i = 0; i != NodeOperands; ++i) AddOperand(MI, Node->getOperand(i), i+NumResults, &II, VRBaseMap); - + + // Commute node if it has been determined to be profitable. + if (CommuteSet.count(Node)) { + MachineInstr *NewMI = TII->commuteInstruction(MI); + if (NewMI == 0) + DEBUG(std::cerr << "Sched: COMMUTING FAILED!\n"); + else { + DEBUG(std::cerr << "Sched: COMMUTED TO: " << *NewMI); + MI = NewMI; + } + } + // Now that we have emitted all operands, emit this instruction itself. if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { BB->insert(BB->end(), MI); Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.1 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.2 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.1 Thu May 11 18:55:42 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu May 11 20:58:24 2006 @@ -30,7 +30,7 @@ using namespace llvm; namespace { - cl::opt SchedLowerDefNUse("sched-lower-defnuse", cl::Hidden); + cl::opt SchedCommuteNodes("sched-commute-nodes", cl::Hidden); } namespace { @@ -70,6 +70,7 @@ void ScheduleNodeTopDown(SUnit *SU, unsigned& CurCycle); void ListScheduleTopDown(); void ListScheduleBottomUp(); + void CommuteNodesToReducePressure(); }; } // end anonymous namespace @@ -95,6 +96,9 @@ ListScheduleTopDown(); AvailableQueue->releaseState(); + + if (SchedCommuteNodes) + CommuteNodesToReducePressure(); DEBUG(std::cerr << "*** Final schedule ***\n"); DEBUG(dumpSchedule()); @@ -104,6 +108,41 @@ EmitSchedule(); } +/// CommuteNodesToReducePressure - Is a node is two-address and commutable, and +/// it is not the last use of its first operand, add it to the CommuteSet if +/// possible. It will be commuted when it is translated to a MI. +void ScheduleDAGRRList::CommuteNodesToReducePressure() { + std::set OperandSeen; + for (unsigned i = Sequence.size()-1; i != 0; --i) { // Ignore first node. + SUnit *SU = Sequence[i]; + if (!SU) continue; + if (SU->isTwoAddress && SU->isCommutable) { + SDNode *OpN = SU->Node->getOperand(0).Val; + SUnit *OpSU = SUnitMap[OpN]; + if (OpSU && OperandSeen.count(OpSU) == 1) { + // Ok, so SU is not the last use of OpSU, but SU is two-address so + // it will clobber OpSU. Try to commute it if possible. + bool DoCommute = true; + for (unsigned j = 1, e = SU->Node->getNumOperands(); j != e; ++j) { + OpN = SU->Node->getOperand(j).Val; + OpSU = SUnitMap[OpN]; + if (OpSU && OperandSeen.count(OpSU) == 1) { + DoCommute = false; + break; + } + } + if (DoCommute) + CommuteSet.insert(SU->Node); + } + } + + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) { + if (!I->second) + OperandSeen.insert(I->first); + } + } +} //===----------------------------------------------------------------------===// // Bottom-Up Scheduling @@ -436,8 +475,7 @@ void initNodes(const std::vector &sunits) { SUnits = &sunits; // Add pseudo dependency edges for two-address nodes. - if (SchedLowerDefNUse) - AddPseudoTwoAddrDeps(); + AddPseudoTwoAddrDeps(); // Calculate node priorities. CalculatePriorities(); } @@ -513,23 +551,6 @@ if (RIsFloater) RBonus += 2; - if (!SchedLowerDefNUse) { - // Special tie breaker: if two nodes share a operand, the one that use it - // as a def&use operand is preferred. - if (LIsTarget && RIsTarget) { - if (left->isTwoAddress && !right->isTwoAddress) { - SDNode *DUNode = left->Node->getOperand(0).Val; - if (DUNode->isOperand(right->Node)) - LBonus += 2; - } - if (!left->isTwoAddress && right->isTwoAddress) { - SDNode *DUNode = right->Node->getOperand(0).Val; - if (DUNode->isOperand(left->Node)) - RBonus += 2; - } - } - } - if (LPriority+LBonus < RPriority+RBonus) return true; else if (LPriority+LBonus == RPriority+RBonus) @@ -602,16 +623,17 @@ continue; if (SU->isTwoAddress) { - unsigned Depth = SU->Node->getNodeDepth(); SUnit *DUSU = getDefUsePredecessor(SU); if (!DUSU) continue; for (std::set >::iterator I = DUSU->Succs.begin(), E = DUSU->Succs.end(); I != E; ++I) { + if (I->second) continue; SUnit *SuccSU = I->first; - if (SuccSU != SU && !canClobber(SuccSU, DUSU)) { - if (SuccSU->Node->getNodeDepth() <= Depth+2 && - !isReachable(SuccSU, SU)) { + if (SuccSU != SU && + (!canClobber(SuccSU, DUSU) || + (SchedCommuteNodes && !SU->isCommutable && SuccSU->isCommutable))){ + if (SuccSU->Depth <= SU->Depth+2 && !isReachable(SuccSU, SU)) { DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum << " to SU #" << SuccSU->NodeNum << "\n"); if (SU->Preds.insert(std::make_pair(SuccSU, true)).second) From evan.cheng at apple.com Thu May 11 20:59:05 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 20:59:05 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200605120159.UAA27335@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.211 -> 1.212 --- Log message: Set x86 llcbeta to -sched-commute-nodes --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.211 llvm-test/Makefile.programs:1.212 --- llvm-test/Makefile.programs:1.211 Tue May 9 02:13:59 2006 +++ llvm-test/Makefile.programs Thu May 11 20:58:52 2006 @@ -197,7 +197,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -sched-lower-defnuse +LLCBETAOPTION := -sched-commute-nodes endif ifeq ($(ARCH),Sparc) LLCBETAOPTION := -enable-sparc-v9-insts From evan.cheng at apple.com Thu May 11 20:59:29 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 11 May 2006 20:59:29 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll 2006-05-08-InstrSched.ll Message-ID: <200605120159.UAA27349@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-11-InstrSched.ll added (r1.1) 2006-05-08-InstrSched.ll updated: 1.2 -> 1.3 --- Log message: New scheduling test case. --- Diffs of the changes: (+54 -2) 2006-05-08-InstrSched.ll | 3 -- 2006-05-11-InstrSched.ll | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) Index: llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll:1.1 *** /dev/null Thu May 11 20:59:27 2006 --- llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll Thu May 11 20:59:17 2006 *************** *** 0 **** --- 1,53 ---- + ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -sched-commute-nodes && + ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -sched-commute-nodes -stats 2>&1 | grep 'asm-printer' | grep 39 + + void %foo(int* %mc, int* %bp, int* %ms, int* %xmb, int* %mpp, int* %tpmm, int* %ip, int* %tpim, int* %dpp, int* %tpdm, int* %bpi, int %M) { + entry: + %tmp9 = setlt int %M, 5 ; [#uses=1] + br bool %tmp9, label %return, label %cond_true + + cond_true: ; preds = %cond_true, %entry + %indvar = phi uint [ 0, %entry ], [ %indvar.next, %cond_true ] ; [#uses=2] + %tmp. = shl uint %indvar, ubyte 2 ; [#uses=1] + %tmp.10 = add uint %tmp., 1 ; [#uses=2] + %k.0.0 = cast uint %tmp.10 to int ; [#uses=2] + %tmp31 = add int %k.0.0, -1 ; [#uses=4] + %tmp32 = getelementptr int* %mpp, int %tmp31 ; [#uses=1] + %tmp34 = cast int* %tmp32 to sbyte* ; [#uses=1] + %tmp = tail call <16 x sbyte> %llvm.x86.sse2.loadu.dq( sbyte* %tmp34 ) ; <<16 x sbyte>> [#uses=1] + %tmp42 = getelementptr int* %tpmm, int %tmp31 ; [#uses=1] + %tmp42 = cast int* %tmp42 to <4 x int>* ; <<4 x int>*> [#uses=1] + %tmp46 = load <4 x int>* %tmp42 ; <<4 x int>> [#uses=1] + %tmp54 = cast <16 x sbyte> %tmp to <4 x int> ; <<4 x int>> [#uses=1] + %tmp55 = add <4 x int> %tmp54, %tmp46 ; <<4 x int>> [#uses=2] + %tmp55 = cast <4 x int> %tmp55 to <2 x long> ; <<2 x long>> [#uses=1] + %tmp62 = getelementptr int* %ip, int %tmp31 ; [#uses=1] + %tmp65 = cast int* %tmp62 to sbyte* ; [#uses=1] + %tmp66 = tail call <16 x sbyte> %llvm.x86.sse2.loadu.dq( sbyte* %tmp65 ) ; <<16 x sbyte>> [#uses=1] + %tmp73 = getelementptr int* %tpim, int %tmp31 ; [#uses=1] + %tmp73 = cast int* %tmp73 to <4 x int>* ; <<4 x int>*> [#uses=1] + %tmp77 = load <4 x int>* %tmp73 ; <<4 x int>> [#uses=1] + %tmp87 = cast <16 x sbyte> %tmp66 to <4 x int> ; <<4 x int>> [#uses=1] + %tmp88 = add <4 x int> %tmp87, %tmp77 ; <<4 x int>> [#uses=2] + %tmp88 = cast <4 x int> %tmp88 to <2 x long> ; <<2 x long>> [#uses=1] + %tmp99 = tail call <4 x int> %llvm.x86.sse2.pcmpgt.d( <4 x int> %tmp88, <4 x int> %tmp55 ) ; <<4 x int>> [#uses=1] + %tmp99 = cast <4 x int> %tmp99 to <2 x long> ; <<2 x long>> [#uses=2] + %tmp110 = xor <2 x long> %tmp99, < long -1, long -1 > ; <<2 x long>> [#uses=1] + %tmp111 = and <2 x long> %tmp110, %tmp55 ; <<2 x long>> [#uses=1] + %tmp121 = and <2 x long> %tmp99, %tmp88 ; <<2 x long>> [#uses=1] + %tmp131 = or <2 x long> %tmp121, %tmp111 ; <<2 x long>> [#uses=1] + %tmp137 = getelementptr int* %mc, uint %tmp.10 ; [#uses=1] + %tmp137 = cast int* %tmp137 to <2 x long>* ; <<2 x long>*> [#uses=1] + store <2 x long> %tmp131, <2 x long>* %tmp137 + %tmp147 = add int %k.0.0, 8 ; [#uses=1] + %tmp = setgt int %tmp147, %M ; [#uses=1] + %indvar.next = add uint %indvar, 1 ; [#uses=1] + br bool %tmp, label %return, label %cond_true + + return: ; preds = %cond_true, %entry + ret void + } + + declare <16 x sbyte> %llvm.x86.sse2.loadu.dq(sbyte*) + + declare <4 x int> %llvm.x86.sse2.pcmpgt.d(<4 x int>, <4 x int>) Index: llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll diff -u llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.2 llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.3 --- llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll:1.2 Wed May 10 14:53:05 2006 +++ llvm/test/Regression/CodeGen/X86/2006-05-08-InstrSched.ll Thu May 11 20:59:17 2006 @@ -1,5 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static -sched-lower-defnuse && -; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static -sched-lower-defnuse | not grep 'xorb $16, %cl' +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static | not grep 'xorb $16, %cl' %A = external global ushort* %B = external global uint From lattner at cs.uiuc.edu Fri May 12 00:01:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 00:01:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605120501.AAA28171@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.167 -> 1.168 --- Log message: Two simplifications for token factor nodes: simplify tf(x,x) -> x. simplify tf(x,y,y,z) -> tf(x,y,z). --- Diffs of the changes: (+6 -2) DAGCombiner.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.167 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.168 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.167 Tue May 9 01:55:15 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri May 12 00:01:37 2006 @@ -680,7 +680,8 @@ // If the token factor has two operands and one is the entry token, replace // the token factor with the other operand. if (N->getNumOperands() == 2) { - if (N->getOperand(0).getOpcode() == ISD::EntryToken) + if (N->getOperand(0).getOpcode() == ISD::EntryToken || + N->getOperand(0) == N->getOperand(1)) return N->getOperand(1); if (N->getOperand(1).getOpcode() == ISD::EntryToken) return N->getOperand(0); @@ -694,8 +695,11 @@ Changed = true; for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j) Ops.push_back(Op.getOperand(j)); - } else { + } else if (i == 0 || N->getOperand(i) != N->getOperand(i-1)) { Ops.push_back(Op); + } else { + // Deleted an operand that was the same as the last one. + Changed = true; } } if (Changed) From resistor at mac.com Fri May 12 00:50:00 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 00:50:00 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetData.h Message-ID: <200605120550.AAA28335@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetData.h updated: 1.35 -> 1.36 --- Log message: Add a new constructor to TargetData that builds a TargetData from its string representation. This is part of PR 761: http://llvm.cs.uiuc.edu/PR761 . --- Diffs of the changes: (+7 -0) TargetData.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/Target/TargetData.h diff -u llvm/include/llvm/Target/TargetData.h:1.35 llvm/include/llvm/Target/TargetData.h:1.36 --- llvm/include/llvm/Target/TargetData.h:1.35 Thu May 4 16:17:35 2006 +++ llvm/include/llvm/Target/TargetData.h Fri May 12 00:49:47 2006 @@ -53,6 +53,13 @@ unsigned char IntAl = 4, unsigned char ShortAl = 2, unsigned char ByteAl = 1, unsigned char BoolAl = 1); + /// Constructs a TargetData from a string of the following format: + /// "E-p:64:64-d:64:64-f:32:32-l:64:64-i:32:32-s:16:16-b:8:8-B:8:8" + /// The above string is considered the default, and any values not specified + /// in the string will be assumed to be as above. + TargetData(const std::string &TargetName, + const std::string &TargetDescription); + // Copy constructor TargetData (const TargetData &TD) : ImmutablePass(), From resistor at mac.com Fri May 12 00:50:00 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 00:50:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetData.cpp Message-ID: <200605120550.AAA28339@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetData.cpp updated: 1.61 -> 1.62 --- Log message: Add a new constructor to TargetData that builds a TargetData from its string representation. This is part of PR 761: http://llvm.cs.uiuc.edu/PR761 . --- Diffs of the changes: (+65 -0) TargetData.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 65 insertions(+) Index: llvm/lib/Target/TargetData.cpp diff -u llvm/lib/Target/TargetData.cpp:1.61 llvm/lib/Target/TargetData.cpp:1.62 --- llvm/lib/Target/TargetData.cpp:1.61 Mon Apr 3 18:14:49 2006 +++ llvm/lib/Target/TargetData.cpp Fri May 12 00:49:47 2006 @@ -22,7 +22,9 @@ #include "llvm/Constants.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" +#include "llvm/ADT/StringExtras.h" #include +#include using namespace llvm; // Handle the Pass registration stuff necessary to use TargetData's. @@ -118,6 +120,69 @@ BoolAlignment = BoolAl; } +TargetData::TargetData(const std::string &TargetName, + const std::string &TargetDescription) { + std::string temp = TargetDescription; + + LittleEndian = false; + PointerSize = 8; + PointerAlignment = 8; + DoubleAlignment = 8; + FloatAlignment = 4; + LongAlignment = 8; + IntAlignment = 4; + ShortAlignment = 2; + ByteAlignment = 1; + BoolAlignment = 1; + + while (temp.length() > 0) { + std::string token = getToken(temp, "-"); + + switch(token[0]) { + case 'E': + LittleEndian = false; + break; + case 'e': + LittleEndian = true; + break; + case 'p': + PointerSize = atoi(getToken(token,":").c_str()) / 8; + PointerAlignment = atoi(getToken(token,":").c_str()) / 8; + break; + case 'd': + token = getToken(token,":"); //Ignore the size + DoubleAlignment = atoi(getToken(token,":").c_str()) / 8; + break; + case 'f': + token = getToken(token, ":"); //Ignore the size + FloatAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; + case 'l': + token = getToken(token, ":"); //Ignore the size + LongAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; + case 'i': + token = getToken(token, ":"); //Ignore the size + IntAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; + case 's': + token = getToken(token, ":"); //Ignore the size + ShortAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; + case 'b': + token = getToken(token, ":"); //Ignore the size + ByteAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; + case 'B': + token = getToken(token, ":"); //Ignore the size + BoolAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; + default: + break; + } + } +} + TargetData::TargetData(const std::string &ToolName, const Module *M) { LittleEndian = M->getEndianness() != Module::BigEndian; PointerSize = M->getPointerSize() != Module::Pointer64 ? 4 : 8; From evan.cheng at apple.com Fri May 12 01:05:31 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 01:05:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200605120605.BAA28407@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.88 -> 1.89 --- Log message: Duh. That could take a long time. --- Diffs of the changes: (+15 -11) ScheduleDAG.cpp | 26 +++++++++++++++----------- 1 files changed, 15 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.88 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.89 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.88 Thu May 11 20:58:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri May 12 01:05:18 2006 @@ -170,27 +170,31 @@ return; } -static void CalculateDepths(SUnit *SU, unsigned Depth) { - if (Depth > SU->Depth) SU->Depth = Depth; - for (std::set >::iterator I = SU->Succs.begin(), - E = SU->Succs.end(); I != E; ++I) - CalculateDepths(I->first, Depth+1); +static void CalculateDepths(SUnit *SU, unsigned Depth, unsigned Max) { + if (Depth > SU->Depth) { + SU->Depth = Depth; + for (std::set >::iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) + CalculateDepths(I->first, Depth+1, Max); + } } void ScheduleDAG::CalculateDepths() { SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; - ::CalculateDepths(Entry, 0U); + ::CalculateDepths(Entry, 0U, SUnits.size()); for (unsigned i = 0, e = SUnits.size(); i != e; ++i) if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) { - ::CalculateDepths(&SUnits[i], 0U); + ::CalculateDepths(&SUnits[i], 0U, SUnits.size()); } } static void CalculateHeights(SUnit *SU, unsigned Height) { - if (Height > SU->Height) SU->Height = Height; - for (std::set >::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) - CalculateHeights(I->first, Height+1); + if (Height > SU->Height) { + SU->Height = Height; + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) + CalculateHeights(I->first, Height+1); + } } void ScheduleDAG::CalculateHeights() { SUnit *Root = SUnitMap[DAG.getRoot().Val]; From evan.cheng at apple.com Fri May 12 01:06:48 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 01:06:48 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Message-ID: <200605120606.BAA28435@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveIntervalAnalysis.h updated: 1.52 -> 1.53 --- Log message: Backing out fix for PR770: http://llvm.cs.uiuc.edu/PR770 . Need to re-apply it after live range splitting is possible --- Diffs of the changes: (+4 -5) LiveIntervalAnalysis.h | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) Index: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h diff -u llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.52 llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.53 --- llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.52 Tue May 9 01:37:48 2006 +++ llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Fri May 12 01:06:34 2006 @@ -167,11 +167,10 @@ unsigned SrcReg, unsigned DestReg, bool isLiveIn = false); - /// Return true if the two specified registers belong to the same or - /// compatible register classes. The registers may be either phys or - /// virt regs. - bool compatibleRegisterClasses(unsigned RegA, unsigned RegB, - bool &Swap) const; + /// Return true if the two specified registers belong to different + /// register classes. The registers may be either phys or virt regs. + bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; + bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, LiveInterval &IntB, From evan.cheng at apple.com Fri May 12 01:06:48 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 01:06:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200605120606.BAA28436@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.159 -> 1.160 --- Log message: Backing out fix for PR770: http://llvm.cs.uiuc.edu/PR770 . Need to re-apply it after live range splitting is possible --- Diffs of the changes: (+13 -25) LiveIntervalAnalysis.cpp | 38 +++++++++++++------------------------- 1 files changed, 13 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.159 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.160 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.159 Thu May 11 02:29:24 2006 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Fri May 12 01:06:34 2006 @@ -724,12 +724,9 @@ MRegisterInfo::isPhysicalRegister(DestReg)) continue; - // If they are not of compatible register classes, we cannot join them. - bool Swap = false; - if (!compatibleRegisterClasses(SrcReg, DestReg, Swap)) { - DEBUG(std::cerr << "Register classes aren't compatible!\n"); + // If they are not of the same register class, we cannot join them. + if (differingRegisterClasses(SrcReg, DestReg)) continue; - } LiveInterval &SrcInt = getInterval(SrcReg); LiveInterval &DestInt = getInterval(DestReg); @@ -763,7 +760,7 @@ DestInt.join(SrcInt, MIDefIdx); DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n"); - if (!Swap && !MRegisterInfo::isPhysicalRegister(SrcReg)) { + if (!MRegisterInfo::isPhysicalRegister(SrcReg)) { r2iMap_.erase(SrcReg); r2rMap_[SrcReg] = DestReg; } else { @@ -825,33 +822,24 @@ std::cerr << " reg " << i << " -> reg " << r2rMap_[i] << "\n"); } -/// Return true if the two specified registers belong to same or compatible -/// register classes. The registers may be either phys or virt regs. -bool LiveIntervals::compatibleRegisterClasses(unsigned RegA, unsigned RegB, - bool &Swap) const { +/// Return true if the two specified registers belong to different register +/// classes. The registers may be either phys or virt regs. +bool LiveIntervals::differingRegisterClasses(unsigned RegA, + unsigned RegB) const { // Get the register classes for the first reg. if (MRegisterInfo::isPhysicalRegister(RegA)) { assert(MRegisterInfo::isVirtualRegister(RegB) && "Shouldn't consider two physregs!"); - return mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); + return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); } // Compare against the regclass for the second reg. - const TargetRegisterClass *RegClassA = mf_->getSSARegMap()->getRegClass(RegA); - if (MRegisterInfo::isVirtualRegister(RegB)) { - const TargetRegisterClass *RegClassB=mf_->getSSARegMap()->getRegClass(RegB); - if (RegClassA == RegClassB) - return true; - else { - if (RegClassB->hasSubRegClass(RegClassA)) { - Swap = true; - return true; - } - return RegClassA->hasSubRegClass(RegClassB); - } - } else - return RegClassA->contains(RegB); + const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA); + if (MRegisterInfo::isVirtualRegister(RegB)) + return RegClass != mf_->getSSARegMap()->getRegClass(RegB); + else + return !RegClass->contains(RegB); } bool LiveIntervals::overlapsAliases(const LiveInterval *LHS, From resistor at mac.com Fri May 12 01:07:08 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:07:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetData.cpp Message-ID: <200605120607.BAA28449@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetData.cpp updated: 1.62 -> 1.63 --- Log message: Fix some tabbing issues. --- Diffs of the changes: (+29 -29) TargetData.cpp | 58 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 29 insertions(+), 29 deletions(-) Index: llvm/lib/Target/TargetData.cpp diff -u llvm/lib/Target/TargetData.cpp:1.62 llvm/lib/Target/TargetData.cpp:1.63 --- llvm/lib/Target/TargetData.cpp:1.62 Fri May 12 00:49:47 2006 +++ llvm/lib/Target/TargetData.cpp Fri May 12 01:06:55 2006 @@ -140,45 +140,45 @@ switch(token[0]) { case 'E': - LittleEndian = false; - break; + LittleEndian = false; + break; case 'e': - LittleEndian = true; - break; + LittleEndian = true; + break; case 'p': - PointerSize = atoi(getToken(token,":").c_str()) / 8; - PointerAlignment = atoi(getToken(token,":").c_str()) / 8; - break; + PointerSize = atoi(getToken(token,":").c_str()) / 8; + PointerAlignment = atoi(getToken(token,":").c_str()) / 8; + break; case 'd': - token = getToken(token,":"); //Ignore the size - DoubleAlignment = atoi(getToken(token,":").c_str()) / 8; - break; + token = getToken(token,":"); //Ignore the size + DoubleAlignment = atoi(getToken(token,":").c_str()) / 8; + break; case 'f': - token = getToken(token, ":"); //Ignore the size - FloatAlignment = atoi(getToken(token, ":").c_str()) / 8; - break; + token = getToken(token, ":"); //Ignore the size + FloatAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; case 'l': - token = getToken(token, ":"); //Ignore the size - LongAlignment = atoi(getToken(token, ":").c_str()) / 8; - break; + token = getToken(token, ":"); //Ignore the size + LongAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; case 'i': - token = getToken(token, ":"); //Ignore the size - IntAlignment = atoi(getToken(token, ":").c_str()) / 8; - break; + token = getToken(token, ":"); //Ignore the size + IntAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; case 's': - token = getToken(token, ":"); //Ignore the size - ShortAlignment = atoi(getToken(token, ":").c_str()) / 8; - break; + token = getToken(token, ":"); //Ignore the size + ShortAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; case 'b': - token = getToken(token, ":"); //Ignore the size - ByteAlignment = atoi(getToken(token, ":").c_str()) / 8; - break; + token = getToken(token, ":"); //Ignore the size + ByteAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; case 'B': - token = getToken(token, ":"); //Ignore the size - BoolAlignment = atoi(getToken(token, ":").c_str()) / 8; - break; + token = getToken(token, ":"); //Ignore the size + BoolAlignment = atoi(getToken(token, ":").c_str()) / 8; + break; default: - break; + break; } } } From resistor at mac.com Fri May 12 01:34:07 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp SparcTargetMachine.h Message-ID: <200605120634.BAA28656@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcAsmPrinter.cpp updated: 1.65 -> 1.66 SparcTargetMachine.h updated: 1.13 -> 1.14 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+2 -0) SparcAsmPrinter.cpp | 1 + SparcTargetMachine.h | 1 + 2 files changed, 2 insertions(+) Index: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp diff -u llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.65 llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.66 --- llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.65 Mon May 8 23:59:56 2006 +++ llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Fri May 12 01:33:48 2006 @@ -22,6 +22,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/Statistic.h" Index: llvm/lib/Target/Sparc/SparcTargetMachine.h diff -u llvm/lib/Target/Sparc/SparcTargetMachine.h:1.13 llvm/lib/Target/Sparc/SparcTargetMachine.h:1.14 --- llvm/lib/Target/Sparc/SparcTargetMachine.h:1.13 Tue May 2 20:29:57 2006 +++ llvm/lib/Target/Sparc/SparcTargetMachine.h Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #define SPARCTARGETMACHINE_H #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" #include "SparcInstrInfo.h" From resistor at mac.com Fri May 12 01:34:08 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:08 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200605120634.BAA28660@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.64 -> 1.65 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+3 -1) TargetMachine.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.64 llvm/include/llvm/Target/TargetMachine.h:1.65 --- llvm/include/llvm/Target/TargetMachine.h:1.64 Tue May 2 20:29:56 2006 +++ llvm/include/llvm/Target/TargetMachine.h Fri May 12 01:33:48 2006 @@ -14,12 +14,13 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H -#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrItineraries.h" #include +#include namespace llvm { +class TargetData; class TargetSubtarget; class TargetInstrInfo; class TargetInstrDescriptor; @@ -28,6 +29,7 @@ class TargetFrameInfo; class MachineCodeEmitter; class MRegisterInfo; +class Module; class FunctionPassManager; class PassManager; class Pass; From resistor at mac.com Fri May 12 01:34:09 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/CTargetMachine.h Message-ID: <200605120634.BAA28664@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: CTargetMachine.h updated: 1.12 -> 1.13 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) CTargetMachine.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/CBackend/CTargetMachine.h diff -u llvm/lib/Target/CBackend/CTargetMachine.h:1.12 llvm/lib/Target/CBackend/CTargetMachine.h:1.13 --- llvm/lib/Target/CBackend/CTargetMachine.h:1.12 Wed May 3 00:48:41 2006 +++ llvm/lib/Target/CBackend/CTargetMachine.h Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #define CTARGETMACHINE_H #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" namespace llvm { From resistor at mac.com Fri May 12 01:34:11 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200605120634.BAA28682@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.61 -> 1.62 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) TargetLowering.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.61 llvm/lib/Target/TargetLowering.cpp:1.62 --- llvm/lib/Target/TargetLowering.cpp:1.61 Mon May 8 12:22:53 2006 +++ llvm/lib/Target/TargetLowering.cpp Fri May 12 01:33:48 2006 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/DerivedTypes.h" From resistor at mac.com Fri May 12 01:34:10 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JIT.cpp Message-ID: <200605120634.BAA28668@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JIT.cpp updated: 1.65 -> 1.66 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) JIT.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/ExecutionEngine/JIT/JIT.cpp diff -u llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.65 llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.66 --- llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.65 Mon May 8 17:00:52 2006 +++ llvm/lib/ExecutionEngine/JIT/JIT.cpp Fri May 12 01:33:48 2006 @@ -24,6 +24,7 @@ #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Support/MutexGuard.h" #include "llvm/System/DynamicLibrary.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetJITInfo.h" #include From resistor at mac.com Fri May 12 01:34:11 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp DwarfWriter.cpp ELFWriter.cpp MachineBasicBlock.cpp MachineFunction.cpp Message-ID: <200605120634.BAA28698@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.76 -> 1.77 DwarfWriter.cpp updated: 1.59 -> 1.60 ELFWriter.cpp updated: 1.25 -> 1.26 MachineBasicBlock.cpp updated: 1.27 -> 1.28 MachineFunction.cpp updated: 1.90 -> 1.91 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+5 -0) AsmPrinter.cpp | 1 + DwarfWriter.cpp | 1 + ELFWriter.cpp | 1 + MachineBasicBlock.cpp | 1 + MachineFunction.cpp | 1 + 5 files changed, 5 insertions(+) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.76 llvm/lib/CodeGen/AsmPrinter.cpp:1.77 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.76 Tue May 9 11:41:59 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Fri May 12 01:33:48 2006 @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include #include Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.59 llvm/lib/CodeGen/DwarfWriter.cpp:1.60 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.59 Mon May 8 23:59:56 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Fri May 12 01:33:48 2006 @@ -24,6 +24,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Mangler.h" #include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" Index: llvm/lib/CodeGen/ELFWriter.cpp diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.25 llvm/lib/CodeGen/ELFWriter.cpp:1.26 --- llvm/lib/CodeGen/ELFWriter.cpp:1.25 Wed May 3 12:10:41 2006 +++ llvm/lib/CodeGen/ELFWriter.cpp Fri May 12 01:33:48 2006 @@ -35,6 +35,7 @@ #include "llvm/Module.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Mangler.h" #include Index: llvm/lib/CodeGen/MachineBasicBlock.cpp diff -u llvm/lib/CodeGen/MachineBasicBlock.cpp:1.27 llvm/lib/CodeGen/MachineBasicBlock.cpp:1.28 --- llvm/lib/CodeGen/MachineBasicBlock.cpp:1.27 Thu May 4 13:16:01 2006 +++ llvm/lib/CodeGen/MachineBasicBlock.cpp Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #include "llvm/BasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/LeakDetector.h" Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.90 llvm/lib/CodeGen/MachineFunction.cpp:1.91 --- llvm/lib/CodeGen/MachineFunction.cpp:1.90 Tue May 2 20:29:56 2006 +++ llvm/lib/CodeGen/MachineFunction.cpp Fri May 12 01:33:48 2006 @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Function.h" From resistor at mac.com Fri May 12 01:34:12 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:12 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200605120634.BAA28710@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.132 -> 1.133 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) llc.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.132 llvm/tools/llc/llc.cpp:1.133 --- llvm/tools/llc/llc.cpp:1.132 Thu May 4 16:18:40 2006 +++ llvm/tools/llc/llc.cpp Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #include "llvm/Bytecode/Reader.h" #include "llvm/Target/SubtargetFeature.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Transforms/Scalar.h" From resistor at mac.com Fri May 12 01:34:11 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:11 -0500 Subject: [llvm-commits] CVS: llvm/tools/opt/opt.cpp Message-ID: <200605120634.BAA28700@zion.cs.uiuc.edu> Changes in directory llvm/tools/opt: opt.cpp updated: 1.107 -> 1.108 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) opt.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/tools/opt/opt.cpp diff -u llvm/tools/opt/opt.cpp:1.107 llvm/tools/opt/opt.cpp:1.108 --- llvm/tools/opt/opt.cpp:1.107 Thu Apr 21 18:59:48 2005 +++ llvm/tools/opt/opt.cpp Fri May 12 01:33:49 2006 @@ -18,6 +18,7 @@ #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/PassNameParser.h" #include "llvm/System/Signals.h" From resistor at mac.com Fri May 12 01:34:11 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.h Message-ID: <200605120634.BAA28672@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.h updated: 1.34 -> 1.35 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) X86TargetMachine.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.34 llvm/lib/Target/X86/X86TargetMachine.h:1.35 --- llvm/lib/Target/X86/X86TargetMachine.h:1.34 Tue May 2 20:29:57 2006 +++ llvm/lib/Target/X86/X86TargetMachine.h Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #define X86TARGETMACHINE_H #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" #include "X86.h" From resistor at mac.com Fri May 12 01:34:12 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCTargetMachine.h Message-ID: <200605120634.BAA28718@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCTargetMachine.h updated: 1.19 -> 1.20 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) PPCTargetMachine.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.19 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.20 --- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.19 Tue May 2 20:29:57 2006 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.h Fri May 12 01:33:48 2006 @@ -20,6 +20,7 @@ #include "PPCInstrInfo.h" #include "PPCISelLowering.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" namespace llvm { class PassManager; From resistor at mac.com Fri May 12 01:34:12 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64TargetMachine.h Message-ID: <200605120634.BAA28714@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64TargetMachine.h updated: 1.8 -> 1.9 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) IA64TargetMachine.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/IA64/IA64TargetMachine.h diff -u llvm/lib/Target/IA64/IA64TargetMachine.h:1.8 llvm/lib/Target/IA64/IA64TargetMachine.h:1.9 --- llvm/lib/Target/IA64/IA64TargetMachine.h:1.8 Tue May 2 20:29:57 2006 +++ llvm/lib/Target/IA64/IA64TargetMachine.h Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #define IA64TARGETMACHINE_H #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" #include "IA64InstrInfo.h" From resistor at mac.com Fri May 12 01:34:11 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaTargetMachine.h Message-ID: <200605120634.BAA28706@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaTargetMachine.h updated: 1.13 -> 1.14 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+1 -0) AlphaTargetMachine.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/AlphaTargetMachine.h diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.13 llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.14 --- llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.13 Tue May 2 20:29:57 2006 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.h Fri May 12 01:33:48 2006 @@ -15,6 +15,7 @@ #define ALPHA_TARGETMACHINE_H #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" #include "AlphaInstrInfo.h" From resistor at mac.com Fri May 12 01:34:11 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 01:34:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp ScheduleDAGRRList.cpp ScheduleDAGSimple.cpp Message-ID: <200605120634.BAA28680@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.89 -> 1.90 ScheduleDAGList.cpp updated: 1.58 -> 1.59 ScheduleDAGRRList.cpp updated: 1.2 -> 1.3 ScheduleDAGSimple.cpp updated: 1.11 -> 1.12 --- Log message: Refactor a bunch of includes so that TargetMachine.h doesn't have to include TargetData.h. This should make recompiles a bit faster with my current TargetData tinkering. --- Diffs of the changes: (+4 -0) ScheduleDAG.cpp | 1 + ScheduleDAGList.cpp | 1 + ScheduleDAGRRList.cpp | 1 + ScheduleDAGSimple.cpp | 1 + 4 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.89 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.90 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.89 Fri May 12 01:05:18 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri May 12 01:33:48 2006 @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SSARegMap.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.58 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.59 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.58 Thu May 11 18:55:42 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri May 12 01:33:48 2006 @@ -22,6 +22,7 @@ #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.2 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.3 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.2 Thu May 11 20:58:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Fri May 12 01:33:48 2006 @@ -19,6 +19,7 @@ #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.11 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.12 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.11 Fri Mar 10 01:51:18 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Fri May 12 01:33:48 2006 @@ -16,6 +16,7 @@ #define DEBUG_TYPE "sched" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" From resistor at mac.com Fri May 12 02:01:57 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 02:01:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetData.cpp Message-ID: <200605120701.CAA28829@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetData.cpp updated: 1.63 -> 1.64 --- Log message: Add a method to generate a string representation from a TargetData. This continues the work on PR 761: http://llvm.cs.uiuc.edu/PR761 . --- Diffs of the changes: (+21 -0) TargetData.cpp | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/lib/Target/TargetData.cpp diff -u llvm/lib/Target/TargetData.cpp:1.63 llvm/lib/Target/TargetData.cpp:1.64 --- llvm/lib/Target/TargetData.cpp:1.63 Fri May 12 01:06:55 2006 +++ llvm/lib/Target/TargetData.cpp Fri May 12 02:01:44 2006 @@ -25,6 +25,7 @@ #include "llvm/ADT/StringExtras.h" #include #include +#include using namespace llvm; // Handle the Pass registration stuff necessary to use TargetData's. @@ -218,6 +219,26 @@ } } +std::string TargetData::getStringRepresentation() const { + std::stringstream repr; + + if (LittleEndian) + repr << "e"; + else + repr << "E"; + + repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8); + repr << "-d:64:" << (DoubleAlignment * 8); + repr << "-f:32:" << (FloatAlignment * 8); + repr << "-l:64:" << (LongAlignment * 8); + repr << "-i:32:" << (IntAlignment * 8); + repr << "-s:16:" << (ShortAlignment * 8); + repr << "-b:8:" << (ByteAlignment * 8); + repr << "-B:8:" << (BoolAlignment * 8); + + return repr.str(); +} + const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { if (Layouts == 0) Layouts = new std::map, From resistor at mac.com Fri May 12 02:01:57 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 12 May 2006 02:01:57 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetData.h Message-ID: <200605120701.CAA28833@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetData.h updated: 1.36 -> 1.37 --- Log message: Add a method to generate a string representation from a TargetData. This continues the work on PR 761: http://llvm.cs.uiuc.edu/PR761 . --- Diffs of the changes: (+5 -0) TargetData.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/Target/TargetData.h diff -u llvm/include/llvm/Target/TargetData.h:1.36 llvm/include/llvm/Target/TargetData.h:1.37 --- llvm/include/llvm/Target/TargetData.h:1.36 Fri May 12 00:49:47 2006 +++ llvm/include/llvm/Target/TargetData.h Fri May 12 02:01:44 2006 @@ -94,6 +94,11 @@ unsigned char getPointerSize() const { return PointerSize; } unsigned char getPointerSizeInBits() const { return 8*PointerSize; } + /// getStringRepresentation - Return the string representation of the + /// TargetData. This representation is in the same format accepted by the + /// string constructor above. + std::string getStringRepresentation() const; + /// getTypeSize - Return the number of bytes necessary to hold the specified /// type. /// From evan.cheng at apple.com Fri May 12 02:42:13 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 02:42:13 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200605120742.CAA05503@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.201 -> 1.202 --- Log message: Unused instruction --- Diffs of the changes: (+0 -1) DAGISelEmitter.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.201 llvm/utils/TableGen/DAGISelEmitter.cpp:1.202 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.201 Tue May 9 21:47:57 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri May 12 02:42:01 2006 @@ -2870,7 +2870,6 @@ if (Op->isSubClassOf("Instruction")) { const DAGInstruction &Inst = ISE.getInstruction(Op); const CodeGenTarget &CGT = ISE.getTargetInfo(); - CodeGenInstruction &II = CGT.getInstruction(Op->getName()); unsigned NumImpResults = Inst.getNumImpResults(); for (unsigned i = 0; i < NumImpResults; i++) { Record *RR = Inst.getImpResult(i); From evan.cheng at apple.com Fri May 12 02:47:12 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 02:47:12 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200605120747.CAA05538@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrInfoEmitter.cpp updated: 1.40 -> 1.41 --- Log message: Noop instruction --- Diffs of the changes: (+0 -2) InstrInfoEmitter.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.40 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.41 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.40 Tue May 2 21:08:34 2006 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Fri May 12 02:47:00 2006 @@ -26,8 +26,6 @@ CodeGenTarget Target; // We must emit the PHI opcode first... - Record *InstrInfo = Target.getInstructionSet(); - std::string Namespace; for (CodeGenTarget::inst_iterator II = Target.inst_begin(), E = Target.inst_end(); II != E; ++II) { From lattner at cs.uiuc.edu Fri May 12 11:28:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 11:28:25 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/2006-05-12-rlwimi-crash.ll Message-ID: <200605121628.LAA07620@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: 2006-05-12-rlwimi-crash.ll added (r1.1) --- Log message: new testcase for a recent rlwimi crash. --- Diffs of the changes: (+60 -0) 2006-05-12-rlwimi-crash.ll | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 60 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/2006-05-12-rlwimi-crash.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/2006-05-12-rlwimi-crash.ll:1.1 *** /dev/null Fri May 12 11:28:23 2006 --- llvm/test/Regression/CodeGen/PowerPC/2006-05-12-rlwimi-crash.ll Fri May 12 11:28:13 2006 *************** *** 0 **** --- 1,60 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 + + %struct.attr_desc = type { sbyte*, %struct.attr_desc*, %struct.attr_value*, %struct.attr_value*, uint } + %struct.attr_value = type { %struct.rtx_def*, %struct.attr_value*, %struct.insn_ent*, int, int } + %struct.insn_def = type { %struct.insn_def*, %struct.rtx_def*, int, int, int, int, int } + %struct.insn_ent = type { %struct.insn_ent*, %struct.insn_def* } + %struct.rtx_def = type { ushort, ubyte, ubyte, %struct.u } + %struct.u = type { [1 x long] } + + implementation ; Functions: + + void %find_attr() { + entry: + %tmp26 = seteq %struct.attr_desc* null, null ; [#uses=1] + br bool %tmp26, label %bb30, label %cond_true27 + + cond_true27: ; preds = %entry + ret void + + bb30: ; preds = %entry + %tmp67 = seteq %struct.attr_desc* null, null ; [#uses=1] + br bool %tmp67, label %cond_next92, label %cond_true68 + + cond_true68: ; preds = %bb30 + ret void + + cond_next92: ; preds = %bb30 + %tmp173 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=2] + %tmp174 = load uint* %tmp173 ; [#uses=1] + %tmp177 = and uint %tmp174, 4294967287 ; [#uses=1] + store uint %tmp177, uint* %tmp173 + %tmp180 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=1] + %tmp181 = load uint* %tmp180 ; [#uses=1] + %tmp185 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=2] + %tmp186 = load uint* %tmp185 ; [#uses=1] + %tmp183187 = shl uint %tmp181, ubyte 1 ; [#uses=1] + %tmp188 = and uint %tmp183187, 16 ; [#uses=1] + %tmp190 = and uint %tmp186, 4294967279 ; [#uses=1] + %tmp191 = or uint %tmp190, %tmp188 ; [#uses=1] + store uint %tmp191, uint* %tmp185 + %tmp193 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=1] + %tmp194 = load uint* %tmp193 ; [#uses=1] + %tmp198 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=2] + %tmp199 = load uint* %tmp198 ; [#uses=1] + %tmp196200 = shl uint %tmp194, ubyte 2 ; [#uses=1] + %tmp201 = and uint %tmp196200, 64 ; [#uses=1] + %tmp203 = and uint %tmp199, 4294967231 ; [#uses=1] + %tmp204 = or uint %tmp203, %tmp201 ; [#uses=1] + store uint %tmp204, uint* %tmp198 + %tmp206 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=1] + %tmp207 = load uint* %tmp206 ; [#uses=1] + %tmp211 = getelementptr %struct.attr_desc* null, int 0, uint 4 ; [#uses=2] + %tmp212 = load uint* %tmp211 ; [#uses=1] + %tmp209213 = shl uint %tmp207, ubyte 1 ; [#uses=1] + %tmp214 = and uint %tmp209213, 128 ; [#uses=1] + %tmp216 = and uint %tmp212, 4294967167 ; [#uses=1] + %tmp217 = or uint %tmp216, %tmp214 ; [#uses=1] + store uint %tmp217, uint* %tmp211 + ret void + } From lattner at cs.uiuc.edu Fri May 12 11:29:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 11:29:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200605121629.LAA07656@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.183 -> 1.184 --- Log message: Fix PowerPC/2006-05-12-rlwimi-crash.ll Nate, please verify that if InsertMask is 0, rlwimi shouldn't be used. This fixes the crash and causes no PPC testsuite regressions. --- Diffs of the changes: (+4 -3) PPCISelDAGToDAG.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.183 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.184 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.183 Mon May 8 12:38:32 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri May 12 11:29:37 2006 @@ -365,7 +365,7 @@ // if the mask doesn't intersect any Indeterminant bits if (Mask && !(Mask & Indeterminant)) { - SH = Shift; + SH = Shift & 31; // make sure the mask is still a mask (wrap arounds may not be) return isRunOfOnes(Mask, MB, ME); } @@ -431,7 +431,7 @@ } unsigned MB, ME; - if (isRunOfOnes(InsertMask, MB, ME)) { + if (InsertMask && isRunOfOnes(InsertMask, MB, ME)) { SDOperand Tmp1, Tmp2, Tmp3; bool DisjointMask = (TargetMask ^ InsertMask) == 0xFFFFFFFF; @@ -454,6 +454,7 @@ Tmp3 = (Op0Opc == ISD::AND && DisjointMask) ? Op0.getOperand(0) : Op0; Select(Tmp1, Tmp3); Select(Tmp2, Op1); + SH &= 31; return CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2, getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); } @@ -1149,7 +1150,7 @@ SDOperand Val; Select(Val, N->getOperand(0).getOperand(0)); Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, - Val, getI32Imm(SH & 0x1F), getI32Imm(MB), + Val, getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); return; } From lattner at cs.uiuc.edu Fri May 12 12:03:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:03:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200605121703.MAA07937@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.305 -> 1.306 --- Log message: Compile: %tmp152 = setgt uint %tmp144, %tmp149 ; [#uses=1] %tmp159 = setlt uint %tmp144, %tmp149 ; [#uses=1] %bothcond2 = or bool %tmp152, %tmp159 ; [#uses=1] To setne, not setune, which causes an assertion fault. --- Diffs of the changes: (+6 -1) SelectionDAG.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.305 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.306 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.305 Mon May 8 12:29:49 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri May 12 12:03:46 2006 @@ -217,7 +217,12 @@ // If the N and U bits get set then the resultant comparison DOES suddenly // care about orderedness, and is true when ordered. if (Op > ISD::SETTRUE2) - Op &= ~16; // Clear the N bit. + Op &= ~16; // Clear the U bit if the N bit is set. + + // Canonicalize illegal integer setcc's. + if (isInteger && Op == ISD::SETUNE) // e.g. SETUGT | SETULT + Op = ISD::SETNE; + return ISD::CondCode(Op); } From lattner at cs.uiuc.edu Fri May 12 12:28:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:28:49 -0500 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp Message-ID: <200605121728.MAA08054@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.46 -> 1.47 --- Log message: Remove dead return value. --- Diffs of the changes: (+1 -1) ExtractFunction.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.46 llvm/tools/bugpoint/ExtractFunction.cpp:1.47 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.46 Wed Mar 8 17:55:38 2006 +++ llvm/tools/bugpoint/ExtractFunction.cpp Fri May 12 12:28:36 2006 @@ -360,7 +360,7 @@ std::cout << "*** Basic Block extraction failed, please report a bug!\n"; M = swapProgramIn(M); EmitProgressBytecode("basicblockextractfail", true); - M = swapProgramIn(M); + swapProgramIn(M); } return Ret; } From lattner at cs.uiuc.edu Fri May 12 12:29:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:29:54 -0500 Subject: [llvm-commits] CVS: llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp Message-ID: <200605121729.MAA08092@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/lib/compiler: StackerCompiler.cpp updated: 1.15 -> 1.16 --- Log message: Avoid defining dead result --- Diffs of the changes: (+1 -1) StackerCompiler.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp diff -u llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.15 llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.16 --- llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.15 Wed May 4 10:33:48 2005 +++ llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp Fri May 12 12:29:40 2006 @@ -675,9 +675,9 @@ { // Look up the function name in the module to see if it was forward // declared. +#if 0 Function* existing_function = TheModule->getNamedFunction( name ); -#if 0 // If the function already exists... if ( existing_function ) { From lattner at cs.uiuc.edu Fri May 12 12:31:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:31:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Message-ID: <200605121731.MAA08153@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcISelDAGToDAG.cpp updated: 1.92 -> 1.93 --- Log message: Remove dead variable. --- Diffs of the changes: (+0 -1) SparcISelDAGToDAG.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.92 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.93 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.92 Sat Apr 22 13:53:45 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Fri May 12 12:31:21 2006 @@ -469,7 +469,6 @@ bool isVarArg, unsigned CC, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { - MachineFunction &MF = DAG.getMachineFunction(); // Count the size of the outgoing arguments. unsigned ArgsSize = 0; for (unsigned i = 0, e = Args.size(); i != e; ++i) { From lattner at cs.uiuc.edu Fri May 12 12:34:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:34:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200605121734.MAA08214@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.174 -> 1.175 --- Log message: remove dead variable. --- Diffs of the changes: (+0 -1) PPCAsmPrinter.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.174 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.175 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.174 Tue May 9 11:15:00 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Fri May 12 12:33:59 2006 @@ -748,7 +748,6 @@ bool AIXAsmPrinter::doInitialization(Module &M) { SwitchToDataSection("", 0); - const TargetData *TD = TM.getTargetData(); O << "\t.machine \"ppc64\"\n" << "\t.toc\n" From lattner at cs.uiuc.edu Fri May 12 12:41:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:41:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp Message-ID: <200605121741.MAA08320@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: EquivClassGraphs.cpp updated: 1.46 -> 1.47 --- Log message: Remove dead variable --- Diffs of the changes: (+0 -2) EquivClassGraphs.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp diff -u llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.46 llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.47 --- llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.46 Sun Jan 22 17:19:18 2006 +++ llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp Fri May 12 12:41:45 2006 @@ -41,8 +41,6 @@ #ifndef NDEBUG template static void CheckAllGraphs(Module *M, GT &ECGraphs) { - DSGraph &GG = ECGraphs.getGlobalsGraph(); - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isExternal()) { DSGraph &G = ECGraphs.getDSGraph(*I); From lattner at cs.uiuc.edu Fri May 12 12:50:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:50:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200605121750.MAA08392@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.77 -> 1.78 --- Log message: Remove dead var --- Diffs of the changes: (+0 -1) AsmPrinter.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.77 llvm/lib/CodeGen/AsmPrinter.cpp:1.78 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.77 Fri May 12 01:33:48 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Fri May 12 12:50:35 2006 @@ -147,7 +147,6 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { const std::vector &CP = MCP->getConstants(); if (CP.empty()) return; - const TargetData *TD = TM.getTargetData(); SwitchToDataSection(ConstantPoolSection, 0); EmitAlignment(MCP->getConstantPoolAlignment()); From reid at x10sys.com Fri May 12 12:56:33 2006 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 May 2006 12:56:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveReader.cpp Message-ID: <200605121756.MAA08413@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveReader.cpp updated: 1.43 -> 1.44 --- Log message: When reading the symbol table, make sure to delete the ArchiveMember created by reading the symbol table. --- Diffs of the changes: (+2 -0) ArchiveReader.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Bytecode/Archive/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.43 llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.44 --- llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.43 Mon Dec 26 08:31:26 2005 +++ llvm/lib/Bytecode/Archive/ArchiveReader.cpp Fri May 12 12:56:20 2006 @@ -363,6 +363,8 @@ At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) At++; + delete mbr; + // Can't be any more symtab headers so just advance FirstFile = At; } else { // There's no symbol table in the file. We have to rebuild it from scratch From lattner at cs.uiuc.edu Fri May 12 12:58:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 12:58:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605121758.MAA08448@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.168 -> 1.169 --- Log message: Comment out dead variables --- Diffs of the changes: (+2 -2) DAGCombiner.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.168 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.169 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.168 Fri May 12 00:01:37 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri May 12 12:57:54 2006 @@ -1775,7 +1775,7 @@ // Determine if the condition we're dealing with is constant SDOperand SCC = SimplifySetCC(TLI.getSetCCResultTy(), N0, N1, CC, false); - ConstantSDNode *SCCC = dyn_cast_or_null(SCC.Val); + //ConstantSDNode *SCCC = dyn_cast_or_null(SCC.Val); // fold select_cc lhs, rhs, x, x, cc -> x if (N2 == N3) @@ -3055,7 +3055,7 @@ ISD::CondCode CC) { MVT::ValueType VT = N2.getValueType(); - ConstantSDNode *N0C = dyn_cast(N0.Val); + //ConstantSDNode *N0C = dyn_cast(N0.Val); ConstantSDNode *N1C = dyn_cast(N1.Val); ConstantSDNode *N2C = dyn_cast(N2.Val); ConstantSDNode *N3C = dyn_cast(N3.Val); From lattner at cs.uiuc.edu Fri May 12 13:02:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:02:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200605121802.NAA08524@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.53 -> 1.54 --- Log message: Remove dead variable --- Diffs of the changes: (+0 -1) PrologEpilogInserter.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.53 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.54 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.53 Fri Apr 7 11:34:45 2006 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Fri May 12 13:02:04 2006 @@ -102,7 +102,6 @@ void PEI::calculateCallerSavedRegisters(MachineFunction &Fn) { const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); - const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); // Get the callee saved register list... const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); From lattner at cs.uiuc.edu Fri May 12 13:04:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:04:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200605121804.NAA08559@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.306 -> 1.307 --- Log message: remove dead vars --- Diffs of the changes: (+1 -2) SelectionDAG.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.306 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.307 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.306 Fri May 12 12:03:46 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri May 12 13:04:28 2006 @@ -1539,7 +1539,7 @@ // Perform various simplifications. ConstantSDNode *N1C = dyn_cast(N1.Val); ConstantSDNode *N2C = dyn_cast(N2.Val); - ConstantSDNode *N3C = dyn_cast(N3.Val); + //ConstantSDNode *N3C = dyn_cast(N3.Val); switch (Opcode) { case ISD::SETCC: { // Use SimplifySetCC to simplify SETCC's. @@ -1696,7 +1696,6 @@ default: break; } - ConstantSDNode *N1C = dyn_cast(Ops[1].Val); switch (Opcode) { default: break; case ISD::TRUNCSTORE: { From lattner at cs.uiuc.edu Fri May 12 13:06:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:06:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605121806.NAA08603@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.238 -> 1.239 --- Log message: Remove dead vars --- Diffs of the changes: (+0 -2) SelectionDAGISel.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.238 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.239 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.238 Thu May 11 18:55:42 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri May 12 13:06:45 2006 @@ -1199,7 +1199,6 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { SDOperand N = getValue(I.getOperand(0)); const Type *Ty = I.getOperand(0)->getType(); - const Type *UIntPtrTy = TD->getIntPtrType(); for (GetElementPtrInst::op_iterator OI = I.op_begin()+1, E = I.op_end(); OI != E; ++OI) { @@ -3456,7 +3455,6 @@ Ops.push_back(InOps[0]); // input chain. Ops.push_back(InOps[1]); // input asm string. - const char *AsmStr = cast(InOps[1])->getSymbol(); unsigned i = 2, e = InOps.size(); if (InOps[e-1].getValueType() == MVT::Flag) --e; // Don't process a flag operand if it is here. From lattner at cs.uiuc.edu Fri May 12 13:10:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:10:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200605121810.NAA08662@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JITEmitter.cpp updated: 1.100 -> 1.101 --- Log message: Fix a hypothetical memory leak, identified by Coverity. In practice, this object is never deleted though. --- Diffs of the changes: (+3 -1) JITEmitter.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.100 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.101 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.100 Thu May 11 19:03:12 2006 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Fri May 12 13:10:12 2006 @@ -392,12 +392,14 @@ // Allocate the GOT. GOTBase = NULL; - if (useGOT) GOTBase = (unsigned char*)malloc(sizeof(void*) * 8192); + if (useGOT) GOTBase = new unsigned char[sizeof(void*) * 8192]; } JITMemoryManager::~JITMemoryManager() { for (unsigned i = 0, e = Blocks.size(); i != e; ++i) sys::Memory::ReleaseRWX(Blocks[i]); + + delete[] GOTBase; Blocks.clear(); } From lattner at cs.uiuc.edu Fri May 12 13:13:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:13:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Process.inc Message-ID: <200605121813.NAA08704@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Process.inc updated: 1.13 -> 1.14 --- Log message: Fix iterator invalidation bug, identified by Coverity. --- Diffs of the changes: (+1 -1) Process.inc | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/System/Unix/Process.inc diff -u llvm/lib/System/Unix/Process.inc:1.13 llvm/lib/System/Unix/Process.inc:1.14 --- llvm/lib/System/Unix/Process.inc:1.13 Mon Nov 14 01:27:56 2005 +++ llvm/lib/System/Unix/Process.inc Fri May 12 13:13:11 2006 @@ -95,7 +95,7 @@ TimeValue& sys_time) { elapsed = TimeValue::now(); -#if defined(HAVE_GETRUSAGE) +#if 0 // defined(HAVE_GETRUSAGE) struct rusage usage; ::getrusage(RUSAGE_SELF, &usage); user_time = TimeValue( From lattner at cs.uiuc.edu Fri May 12 13:13:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:13:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/DynamicLibrary.cpp Message-ID: <200605121813.NAA08708@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: DynamicLibrary.cpp updated: 1.12 -> 1.13 --- Log message: Fix iterator invalidation bug, identified by Coverity. --- Diffs of the changes: (+1 -0) DynamicLibrary.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/System/DynamicLibrary.cpp diff -u llvm/lib/System/DynamicLibrary.cpp:1.12 llvm/lib/System/DynamicLibrary.cpp:1.13 --- llvm/lib/System/DynamicLibrary.cpp:1.12 Sun Jan 29 22:33:51 2006 +++ llvm/lib/System/DynamicLibrary.cpp Fri May 12 13:13:11 2006 @@ -93,6 +93,7 @@ if (*I == a_handle) { // Note: don't use the swap/pop_back trick here. Order is important. OpenedHandles.erase(I); + return; } } } From lattner at cs.uiuc.edu Fri May 12 13:17:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:17:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp Message-ID: <200605121817.NAA08809@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.47 -> 1.48 --- Log message: remove dead variable. --- Diffs of the changes: (+0 -1) AlphaISelLowering.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.47 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.48 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.47 Sat Apr 22 13:53:45 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Fri May 12 13:17:25 2006 @@ -325,7 +325,6 @@ { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock& BB = MF.front(); std::vector ArgValues; unsigned args_int[] = { From lattner at cs.uiuc.edu Fri May 12 13:19:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:19:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64TargetMachine.h Message-ID: <200605121819.NAA08867@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64TargetMachine.h updated: 1.9 -> 1.10 --- Log message: Actually override the right method. :) Bug identified by coverity. --- Diffs of the changes: (+1 -1) IA64TargetMachine.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64TargetMachine.h diff -u llvm/lib/Target/IA64/IA64TargetMachine.h:1.9 llvm/lib/Target/IA64/IA64TargetMachine.h:1.10 --- llvm/lib/Target/IA64/IA64TargetMachine.h:1.9 Fri May 12 01:33:48 2006 +++ llvm/lib/Target/IA64/IA64TargetMachine.h Fri May 12 13:19:25 2006 @@ -34,7 +34,7 @@ virtual const IA64InstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } - virtual IA64TargetLowering *getTargetLowering() { return &TLInfo; } + virtual IA64TargetLowering *getTargetLowering() const { return &TLInfo; } virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } From lattner at cs.uiuc.edu Fri May 12 13:20:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 13:20:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Process.inc Message-ID: <200605121820.NAA08910@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Process.inc updated: 1.14 -> 1.15 --- Log message: Fix accidentally committed patch. --- Diffs of the changes: (+1 -1) Process.inc | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/System/Unix/Process.inc diff -u llvm/lib/System/Unix/Process.inc:1.14 llvm/lib/System/Unix/Process.inc:1.15 --- llvm/lib/System/Unix/Process.inc:1.14 Fri May 12 13:13:11 2006 +++ llvm/lib/System/Unix/Process.inc Fri May 12 13:20:39 2006 @@ -95,7 +95,7 @@ TimeValue& sys_time) { elapsed = TimeValue::now(); -#if 0 // defined(HAVE_GETRUSAGE) +#if defined(HAVE_GETRUSAGE) struct rusage usage; ::getrusage(RUSAGE_SELF, &usage); user_time = TimeValue( From evan.cheng at apple.com Fri May 12 14:04:09 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 14:04:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200605121904.OAA09063@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.59 -> 1.60 --- Log message: Remove dead code --- Diffs of the changes: (+1 -4) X86ISelDAGToDAG.cpp | 5 +---- 1 files changed, 1 insertion(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.59 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.60 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.59 Mon May 8 03:01:26 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri May 12 14:03:56 2006 @@ -806,10 +806,7 @@ case MVT::i32: Opc = X86::MOV32to32_; VT = MVT::i32; - if (NVT == MVT::i16) - Opc2 = X86::TRUNC_R32_R16; - else - Opc2 = X86::TRUNC_R32_R8; + Opc2 = X86::TRUNC_R32_R8; break; } From evan.cheng at apple.com Fri May 12 14:07:58 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 12 May 2006 14:07:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200605121907.OAA09099@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.122 -> 1.123 --- Log message: If the register allocator cannot find a register to spill, try the aliases. If that still fails (because all the register spill weights are inf), just grab one. --- Diffs of the changes: (+19 -2) RegAllocLinearScan.cpp | 21 +++++++++++++++++++-- 1 files changed, 19 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.122 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.123 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.122 Thu May 11 02:28:16 2006 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Fri May 12 14:07:46 2006 @@ -551,15 +551,32 @@ } // If we didn't find a register that is spillable, try aliases? + if (!minReg) { + for (TargetRegisterClass::iterator i = RC->allocation_order_begin(*mf_), + e = RC->allocation_order_end(*mf_); i != e; ++i) { + unsigned reg = *i; + // No need to worry about if the alias register size < regsize of RC. + // We are going to spill all registers that alias it anyway. + for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) { + if (minWeight > SpillWeights[*as]) { + minWeight = SpillWeights[*as]; + minReg = *as; + } + } + } + + // All registers must have inf weight. Just grab one! + if (!minReg) + minReg = *RC->allocation_order_begin(*mf_); + } -// FIXME: assert(minReg && "Didn't find any reg!"); DEBUG(std::cerr << "\t\tregister with min weight: " << mri_->getName(minReg) << " (" << minWeight << ")\n"); // if the current has the minimum weight, we need to spill it and // add any added intervals back to unhandled, and restart // linearscan. - if (cur->weight <= minWeight) { + if (cur->weight != float(HUGE_VAL) && cur->weight <= minWeight) { DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';); int slot = vrm_->assignVirt2StackSlot(cur->reg); std::vector added = From reid at x10sys.com Fri May 12 14:21:08 2006 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 May 2006 14:21:08 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CommandLine.h Message-ID: <200605121921.OAA09216@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CommandLine.h updated: 1.52 -> 1.53 --- Log message: Don't use old-style casts. This prevents compiler warnings when CommandLine.h is used in projects that have stricter warning control than LLVM. This also helps us find casts more easily if we ever need to. --- Diffs of the changes: (+2 -2) CommandLine.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Support/CommandLine.h diff -u llvm/include/llvm/Support/CommandLine.h:1.52 llvm/include/llvm/Support/CommandLine.h:1.53 --- llvm/include/llvm/Support/CommandLine.h:1.52 Mon Oct 24 00:03:46 2005 +++ llvm/include/llvm/Support/CommandLine.h Fri May 12 14:20:55 2006 @@ -997,7 +997,7 @@ template static unsigned Bit(const T &V) { - unsigned BitPos = (unsigned)V; + unsigned BitPos = reinterpret_cast(V); assert(BitPos < sizeof(unsigned) * 8 && "enum exceeds width of bit vector!"); return 1 << BitPos; @@ -1038,7 +1038,7 @@ template static unsigned Bit(const T &V) { - unsigned BitPos = (unsigned)V; + unsigned BitPos = reinterpret_cast(V); assert(BitPos < sizeof(unsigned) * 8 && "enum exceeds width of bit vector!"); return 1 << BitPos; From lattner at cs.uiuc.edu Fri May 12 16:10:09 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 16:10:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCTargetMachine.h Message-ID: <200605122110.QAA09832@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.169 -> 1.170 PPCTargetMachine.h updated: 1.20 -> 1.21 --- Log message: Remove dead var, fix bad override. --- Diffs of the changes: (+3 -2) PPCISelLowering.cpp | 1 - PPCTargetMachine.h | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.169 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.170 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.169 Fri Apr 28 16:56:10 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Fri May 12 16:09:57 2006 @@ -1722,7 +1722,6 @@ // MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock& BB = MF.front(); SSARegMap *RegMap = MF.getSSARegMap(); std::vector ArgValues; Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.20 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.21 --- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.20 Fri May 12 01:33:48 2006 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.h Fri May 12 16:09:57 2006 @@ -41,7 +41,9 @@ virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } virtual TargetJITInfo *getJITInfo() { return &JITInfo; } virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; } - virtual PPCTargetLowering *getTargetLowering() { return &TLInfo; } + virtual PPCTargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } From lattner at cs.uiuc.edu Fri May 12 16:12:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 16:12:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605122112.QAA09869@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.200 -> 1.201 --- Log message: Dead variable --- Diffs of the changes: (+0 -2) X86ISelLowering.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.200 llvm/lib/Target/X86/X86ISelLowering.cpp:1.201 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.200 Fri May 5 19:29:37 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 12 16:12:22 2006 @@ -524,7 +524,6 @@ void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) { unsigned NumArgs = Op.Val->getNumValues(); MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); for (unsigned i = 0; i < NumArgs; ++i) { std::pair Loc = FormalArgLocs[i]; @@ -1046,7 +1045,6 @@ X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) { unsigned NumArgs = Op.Val->getNumValues(); MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); for (unsigned i = 0; i < NumArgs; ++i) { MVT::ValueType VT = Op.Val->getValueType(i); From lattner at cs.uiuc.edu Fri May 12 16:14:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 16:14:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86TargetMachine.h Message-ID: <200605122114.QAA09933@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.151 -> 1.152 X86TargetMachine.h updated: 1.35 -> 1.36 --- Log message: More coverity fixes --- Diffs of the changes: (+3 -2) X86RegisterInfo.cpp | 1 - X86TargetMachine.h | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.151 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.152 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.151 Mon May 8 03:01:26 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Fri May 12 16:14:20 2006 @@ -197,7 +197,6 @@ /// FIXME: This should obviously be autogenerated by tablegen when patterns /// are available! - MachineBasicBlock& MBB = *MI->getParent(); if (i == 0) { switch(MI->getOpcode()) { case X86::XCHG8rr: return MakeMRInst(X86::XCHG8mr ,FrameIndex, MI); Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.35 llvm/lib/Target/X86/X86TargetMachine.h:1.36 --- llvm/lib/Target/X86/X86TargetMachine.h:1.35 Fri May 12 01:33:48 2006 +++ llvm/lib/Target/X86/X86TargetMachine.h Fri May 12 16:14:20 2006 @@ -40,7 +40,9 @@ virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } virtual TargetJITInfo *getJITInfo() { return &JITInfo; } virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; } - virtual X86TargetLowering *getTargetLowering() { return &TLInfo; } + virtual X86TargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } From lattner at cs.uiuc.edu Fri May 12 18:26:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 18:26:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64TargetMachine.h Message-ID: <200605122326.SAA11135@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64TargetMachine.h updated: 1.10 -> 1.11 --- Log message: Fix build breakage :( --- Diffs of the changes: (+3 -1) IA64TargetMachine.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64TargetMachine.h diff -u llvm/lib/Target/IA64/IA64TargetMachine.h:1.10 llvm/lib/Target/IA64/IA64TargetMachine.h:1.11 --- llvm/lib/Target/IA64/IA64TargetMachine.h:1.10 Fri May 12 13:19:25 2006 +++ llvm/lib/Target/IA64/IA64TargetMachine.h Fri May 12 18:26:11 2006 @@ -34,7 +34,9 @@ virtual const IA64InstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } - virtual IA64TargetLowering *getTargetLowering() const { return &TLInfo; } + virtual IA64TargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } From lattner at cs.uiuc.edu Fri May 12 18:32:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 18:32:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp Message-ID: <200605122332.SAA11196@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.109 -> 1.110 --- Log message: Remove dead stuff --- Diffs of the changes: (+0 -4) ExprTypeConvert.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.109 llvm/lib/Transforms/ExprTypeConvert.cpp:1.110 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.109 Sun Jan 22 16:53:01 2006 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Fri May 12 18:32:01 2006 @@ -195,8 +195,6 @@ ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(V); if (VMCI != VMC.ExprMap.end()) { - const Value *GV = VMCI->second; - const Type *GTy = VMCI->second->getType(); assert(VMCI->second->getType() == Ty); if (Instruction *I = dyn_cast(V)) @@ -518,8 +516,6 @@ return false; case Instruction::Store: { - StoreInst *SI = cast(I); - if (V == I->getOperand(0)) { ValueTypeCache::iterator CTMI = CTMap.find(I->getOperand(1)); if (CTMI != CTMap.end()) { // Operand #1 is in the table already? From lattner at cs.uiuc.edu Fri May 12 18:35:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 18:35:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Inliner.cpp SimplifyLibCalls.cpp Message-ID: <200605122335.SAA11243@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Inliner.cpp updated: 1.27 -> 1.28 SimplifyLibCalls.cpp updated: 1.63 -> 1.64 --- Log message: Remove some dead variables. Fix a nasty bug in the memcmp optimizer where we used the wrong variable! --- Diffs of the changes: (+2 -7) Inliner.cpp | 1 - SimplifyLibCalls.cpp | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) Index: llvm/lib/Transforms/IPO/Inliner.cpp diff -u llvm/lib/Transforms/IPO/Inliner.cpp:1.27 llvm/lib/Transforms/IPO/Inliner.cpp:1.28 --- llvm/lib/Transforms/IPO/Inliner.cpp:1.27 Sun Jan 22 17:32:06 2006 +++ llvm/lib/Transforms/IPO/Inliner.cpp Fri May 12 18:35:26 2006 @@ -41,7 +41,6 @@ // do so and update the CallGraph for this operation. static bool InlineCallIfPossible(CallSite CS, CallGraph &CG, const std::set &SCCFunctions) { - Function *Caller = CS.getInstruction()->getParent()->getParent(); Function *Callee = CS.getCalledFunction(); if (!InlineFunction(CS, &CG)) return false; Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.63 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.64 --- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.63 Thu Mar 2 19:30:23 2006 +++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Fri May 12 18:35:26 2006 @@ -386,7 +386,7 @@ // Create a return instruction that we'll replace the call with. // Note that the argument of the return is the argument of the call // instruction. - ReturnInst* ri = new ReturnInst(ci->getOperand(1), ci); + new ReturnInst(ci->getOperand(1), ci); // Split the block at the call instruction which places it in a new // basic block. @@ -444,7 +444,6 @@ /// @brief Optimize the strcat library function virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) { // Extract some information from the instruction - Module* M = ci->getParent()->getParent()->getParent(); Value* dest = ci->getOperand(1); Value* src = ci->getOperand(2); @@ -807,9 +806,6 @@ // terminator as well. len++; - // Extract some information from the instruction - Module* M = ci->getParent()->getParent()->getParent(); - // We have enough information to now generate the memcpy call to // do the concatenation for us. std::vector vals; @@ -996,7 +992,7 @@ Value *G1 = new GetElementPtrInst(Op1Cast, One, "next1v", CI); Value *G2 = new GetElementPtrInst(Op2Cast, One, "next2v", CI); Value *S1V2 = new LoadInst(G1, LHS->getName()+".val2", CI); - Value *S2V2 = new LoadInst(G1, RHS->getName()+".val2", CI); + Value *S2V2 = new LoadInst(G2, RHS->getName()+".val2", CI); Value *D2 = BinaryOperator::createSub(S1V2, S2V2, CI->getName()+".d1", CI); Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI); From lattner at cs.uiuc.edu Fri May 12 20:53:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 20:53:58 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/197.parser.hacked/Makefile xa.c Message-ID: <200605130153.UAA11927@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/197.parser.hacked: Makefile (r1.6) removed xa.c (r1.1) removed --- Log message: remove this hack --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Fri May 12 20:54:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 20:54:48 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/197.parser/xa.c Message-ID: <200605130154.UAA12006@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/197.parser: xa.c (r1.1) removed --- Log message: remove dead file --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Fri May 12 21:00:21 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 21:00:21 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/cast.ll Message-ID: <200605130200.VAA12113@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: cast.ll updated: 1.28 -> 1.29 --- Log message: New testcase for instcombine --- Diffs of the changes: (+9 -0) cast.ll | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/cast.ll diff -u llvm/test/Regression/Transforms/InstCombine/cast.ll:1.28 llvm/test/Regression/Transforms/InstCombine/cast.ll:1.29 --- llvm/test/Regression/Transforms/InstCombine/cast.ll:1.28 Fri May 5 01:38:40 2006 +++ llvm/test/Regression/Transforms/InstCombine/cast.ll Fri May 12 21:00:07 2006 @@ -185,3 +185,12 @@ ret uint %tmp10 } +uint %test30(uint %c1) { + %c2 = cast uint %c1 to ubyte + %c3 = xor ubyte %c2, 1 + %c4 = cast ubyte %c3 to uint + ret uint %c4 +} + + + From lattner at cs.uiuc.edu Fri May 12 21:06:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 21:06:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605130206.VAA12186@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.479 -> 1.480 --- Log message: Implement simple promotion for cast elimination in instcombine. This is currently very limited, but can be extended in the future. For example, we now compile: uint %test30(uint %c1) { %c2 = cast uint %c1 to ubyte %c3 = xor ubyte %c2, 1 %c4 = cast ubyte %c3 to uint ret uint %c4 } to: _xor: movzbl 4(%esp), %eax xorl $1, %eax ret instead of: _xor: movb $1, %al xorb 4(%esp), %al movzbl %al, %eax ret More impressively, we now compile: struct B { unsigned bit : 1; }; void xor(struct B *b) { b->bit = b->bit ^ 1; } To (X86/PPC): _xor: movl 4(%esp), %eax xorl $-2147483648, (%eax) ret _xor: lwz r2, 0(r3) xoris r2, r2, 32768 stw r2, 0(r3) blr instead of (X86/PPC): _xor: movl 4(%esp), %eax movl (%eax), %ecx movl %ecx, %edx shrl $31, %edx # TRUNCATE movb %dl, %dl xorb $1, %dl movzbl %dl, %edx andl $2147483647, %ecx shll $31, %edx orl %ecx, %edx movl %edx, (%eax) ret _xor: lwz r2, 0(r3) srwi r4, r2, 31 xori r4, r4, 1 rlwimi r2, r4, 31, 0, 0 stw r2, 0(r3) blr This implements InstCombine/cast.ll:test30. --- Diffs of the changes: (+119 -0) InstructionCombining.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 119 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.479 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.480 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.479 Thu May 11 12:11:52 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri May 12 21:06:03 2006 @@ -256,6 +256,8 @@ Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, bool Inside, Instruction &IB); Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI); + + Value *EvaluateInDifferentType(Value *V, const Type *Ty); }; RegisterOpt X("instcombine", "Combine redundant instructions"); @@ -4779,6 +4781,71 @@ return ReplaceInstUsesWith(CI, New); } +/// CanEvaluateInDifferentType - Return true if we can take the specified value +/// and return it without inserting any new casts. This is used by code that +/// tries to decide whether promoting or shrinking integer operations to wider +/// or smaller types will allow us to eliminate a truncate or extend. +static bool CanEvaluateInDifferentType(Value *V, const Type *Ty, + int &NumCastsRemoved) { + if (isa(V)) return true; + + Instruction *I = dyn_cast(V); + if (!I || !I->hasOneUse()) return false; + + switch (I->getOpcode()) { + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + // These operators can all arbitrarily be extended or truncated. + return CanEvaluateInDifferentType(I->getOperand(0), Ty, NumCastsRemoved) && + CanEvaluateInDifferentType(I->getOperand(1), Ty, NumCastsRemoved); + case Instruction::Cast: + // If this is a cast from the destination type, we can trivially eliminate + // it, and this will remove a cast overall. + if (I->getOperand(0)->getType() == Ty) { + ++NumCastsRemoved; + return true; + } + // TODO: Can handle more cases here. + break; + } + + return false; +} + +/// EvaluateInDifferentType - Given an expression that +/// CanEvaluateInDifferentType returns true for, actually insert the code to +/// evaluate the expression. +Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty) { + if (Constant *C = dyn_cast(V)) + return ConstantExpr::getCast(C, Ty); + + // Otherwise, it must be an instruction. + Instruction *I = cast(V); + Instruction *Res; + switch (I->getOpcode()) { + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: { + Value *LHS = EvaluateInDifferentType(I->getOperand(0), Ty); + Value *RHS = EvaluateInDifferentType(I->getOperand(1), Ty); + Res = BinaryOperator::create((Instruction::BinaryOps)I->getOpcode(), + LHS, RHS, I->getName()); + break; + } + case Instruction::Cast: + // If this is a cast from the destination type, return the input. + if (I->getOperand(0)->getType() == Ty) + return I->getOperand(0); + + // TODO: Can handle more cases here. + assert(0 && "Unreachable!"); + break; + } + + return InsertNewInstBefore(Res, *I); +} + // CastInst simplification // @@ -4906,6 +4973,58 @@ if (Instruction *SrcI = dyn_cast(Src)) if (SrcI->hasOneUse() && Src->getType()->isIntegral() && CI.getType()->isInteger()) { // Don't mess with casts to bool here + + int NumCastsRemoved = 0; + if (CanEvaluateInDifferentType(SrcI, CI.getType(), NumCastsRemoved)) { + // If this cast is a truncate, evaluting in a different type always + // eliminates the cast, so it is always a win. If this is a noop-cast + // this just removes a noop cast which isn't pointful, but simplifies + // the code. If this is a zero-extension, we need to do an AND to + // maintain the clear top-part of the computation, so we require that + // the input have eliminated at least one cast. If this is a sign + // extension, we insert two new casts (to do the extension) so we + // require that two casts have been eliminated. + bool DoXForm; + switch (getCastType(Src->getType(), CI.getType())) { + default: assert(0 && "Unknown cast type!"); + case Noop: + case Truncate: + DoXForm = true; + break; + case Zeroext: + DoXForm = NumCastsRemoved >= 1; + break; + case Signext: + DoXForm = NumCastsRemoved >= 2; + break; + } + + if (DoXForm) { + Value *Res = EvaluateInDifferentType(SrcI, CI.getType()); + assert(Res->getType() == CI.getType()); + switch (getCastType(Src->getType(), CI.getType())) { + default: assert(0 && "Unknown cast type!"); + case Noop: + case Truncate: + // Just replace this cast with the result. + return ReplaceInstUsesWith(CI, Res); + case Zeroext: { + // We need to emit an AND to clear the high bits. + unsigned SrcBitSize = Src->getType()->getPrimitiveSizeInBits(); + unsigned DestBitSize = CI.getType()->getPrimitiveSizeInBits(); + assert(SrcBitSize < DestBitSize && "Not a zext?"); + Constant *C = ConstantUInt::get(Type::ULongTy, (1 << SrcBitSize)-1); + C = ConstantExpr::getCast(C, CI.getType()); + return BinaryOperator::createAnd(Res, C); + } + case Signext: + // We need to emit a cast to truncate, then a cast to sext. + return new CastInst(InsertCastBefore(Res, Src->getType(), CI), + CI.getType()); + } + } + } + const Type *DestTy = CI.getType(); unsigned SrcBitSize = Src->getType()->getPrimitiveSizeInBits(); unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); From lattner at cs.uiuc.edu Fri May 12 21:11:26 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 21:11:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200605130211.VAA12228@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.372 -> 1.373 --- Log message: Merge identical code. --- Diffs of the changes: (+0 -8) LegalizeDAG.cpp | 8 -------- 1 files changed, 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.372 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.373 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.372 Tue May 9 13:20:51 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri May 12 21:11:14 2006 @@ -3012,14 +3012,6 @@ case ISD::AND: case ISD::OR: case ISD::XOR: - // The input may have strange things in the top bits of the registers, but - // these operations don't care. They may have weird bits going out, but - // that too is okay if they are integer operations. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = PromoteOp(Node->getOperand(1)); - assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); - break; case ISD::ADD: case ISD::SUB: case ISD::MUL: From lattner at cs.uiuc.edu Fri May 12 21:16:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 12 May 2006 21:16:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605130216.VAA12314@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.480 -> 1.481 --- Log message: Add/Sub/Mul are safe to promote here as well. Incrementing a single-bit bitfield now gives this code: _plus: lwz r2, 0(r3) rlwimi r2, r2, 0, 1, 31 xoris r2, r2, 32768 stw r2, 0(r3) blr instead of this: _plus: lwz r2, 0(r3) srwi r4, r2, 31 slwi r4, r4, 31 addis r4, r4, -32768 rlwimi r2, r4, 0, 0, 0 stw r2, 0(r3) blr this can obviously still be improved. --- Diffs of the changes: (+6 -0) InstructionCombining.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.480 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.481 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.480 Fri May 12 21:06:03 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri May 12 21:16:08 2006 @@ -4793,6 +4793,9 @@ if (!I || !I->hasOneUse()) return false; switch (I->getOpcode()) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: case Instruction::And: case Instruction::Or: case Instruction::Xor: @@ -4824,6 +4827,9 @@ Instruction *I = cast(V); Instruction *Res; switch (I->getOpcode()) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: case Instruction::And: case Instruction::Or: case Instruction::Xor: { From reid at x10sys.com Fri May 12 21:22:15 2006 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 May 2006 21:22:15 -0500 Subject: [llvm-commits] CVS: llvm/docs/img/libdeps.gif objdeps.gif Message-ID: <200605130222.VAA12424@zion.cs.uiuc.edu> Changes in directory llvm/docs/img: libdeps.gif updated: 1.1 -> 1.2 objdeps.gif updated: 1.1 -> 1.2 --- Log message: For PR741: http://llvm.cs.uiuc.edu/PR741 : Update documentation to reflect current LLVM reality: + LLVMAlpha.o, LLVMIA64.o - Skeleton, execve, ProfilePaths Also, regenerate the library dependency information. --- Diffs of the changes: (+0 -0) libdeps.gif | 0 objdeps.gif | 0 2 files changed Index: llvm/docs/img/libdeps.gif Index: llvm/docs/img/objdeps.gif From reid at x10sys.com Fri May 12 21:22:14 2006 From: reid at x10sys.com (Reid Spencer) Date: Fri, 12 May 2006 21:22:14 -0500 Subject: [llvm-commits] CVS: llvm/docs/UsingLibraries.html Message-ID: <200605130222.VAA12418@zion.cs.uiuc.edu> Changes in directory llvm/docs: UsingLibraries.html updated: 1.22 -> 1.23 --- Log message: For PR741: http://llvm.cs.uiuc.edu/PR741 : Update documentation to reflect current LLVM reality: + LLVMAlpha.o, LLVMIA64.o - Skeleton, execve, ProfilePaths Also, regenerate the library dependency information. --- Diffs of the changes: (+30 -82) UsingLibraries.html | 112 +++++++++++++--------------------------------------- 1 files changed, 30 insertions(+), 82 deletions(-) Index: llvm/docs/UsingLibraries.html diff -u llvm/docs/UsingLibraries.html:1.22 llvm/docs/UsingLibraries.html:1.23 --- llvm/docs/UsingLibraries.html:1.22 Thu Apr 20 12:42:23 2006 +++ llvm/docs/UsingLibraries.html Fri May 12 21:22:01 2006 @@ -112,28 +112,28 @@ Uncategorized transformation passes. LLVMTransformUtils.a .o Transformation utilities. - LLVMProfilePaths.o - Profile paths for instrumentation. Code Generation Libraries LLVMCodeGen.o Native code generation infrastructure Target Libraries + LLVMAlpha.o + Code generation for Alpha architecture LLVMCBackend.o 'C' language code generator. + LLVMIA64.o + Code generation for IA64 architecture LLVMPowerPC.o - PowerPC code generation backend + Code generation for PowerPC architecture LLVMSelectionDAG.o - Aggressive instruction selector for directed acyclic graphs. - LLVMSkeleton.a .o - Skeleton for a code generation backend. + Aggressive instruction selector for directed acyclic graphs LLVMSparc.o - Code generation for Sparc. + Code generation for Sparc architecture LLVMTarget.a .o Generic code generation utilities. LLVMX86.o - Intel x86 code generation backend + Code generation for Intel x86 architecture Runtime Libraries LLVMInterpreter.o @@ -142,8 +142,6 @@ Bytecode JIT Compiler LLVMExecutionEngine.o Virtual machine engine - LLVMexecve.o - execve(2) replacement for llee @@ -175,25 +173,18 @@ alphabetically.

        libLLVMAnalysis.a
          -
        • libLLVMScalarOpts.a
        • libLLVMSupport.a
        • libLLVMTarget.a
        • -
        • libLLVMTransformUtils.a
        • LLVMCore.o
        libLLVMArchive.a
        • libLLVMSupport.a
        • libLLVMSystem.a
        • LLVMBCReader.o
        • -
        -
        libLLVMDataStructure.a
          -
        • libLLVMAnalysis.a
        • -
        • libLLVMSupport.a
        • -
        • libLLVMTarget.a
        • -
        • libLLVMTransformUtils.a
        • LLVMCore.o
        libLLVMInstrumentation.a
          +
        • libLLVMScalarOpts.a
        • libLLVMSupport.a
        • libLLVMTransformUtils.a
        • LLVMCore.o
        • @@ -215,19 +206,21 @@
        • libLLVMSystem.a
        • LLVMbzip2.o
        -
        libLLVMSystem.a
        +
        libLLVMSystem.a
          +
        libLLVMTarget.a
        • libLLVMSupport.a
        • LLVMCore.o
        • +
        • LLVMSelectionDAG.o
        libLLVMTransformUtils.a
        • libLLVMAnalysis.a
        • +
        • libLLVMipa.a
        • libLLVMScalarOpts.a
        • libLLVMSupport.a
        • LLVMCore.o
        libLLVMTransforms.a
          -
        • libLLVMAnalysis.a
        • libLLVMSupport.a
        • libLLVMTarget.a
        • libLLVMTransformUtils.a
        • @@ -241,18 +234,18 @@
          libLLVMipo.a
          • libLLVMAnalysis.a
          • libLLVMipa.a
          • -
          • libLLVMScalarOpts.a
          • libLLVMSupport.a
          • libLLVMTarget.a
          • libLLVMTransformUtils.a
          • LLVMCore.o
          -
          LLVMAnalysis.o
            +
            LLVMAlpha.o
            • libLLVMScalarOpts.a
            • libLLVMSupport.a
            • libLLVMTarget.a
            • -
            • libLLVMTransformUtils.a
            • +
            • LLVMCodeGen.o
            • LLVMCore.o
            • +
            • LLVMSelectionDAG.o
            LLVMAsmParser.o
            • LLVMCore.o
            • @@ -272,6 +265,7 @@
            • libLLVMScalarOpts.a
            • libLLVMSupport.a
            • libLLVMTarget.a
            • +
            • LLVMCodeGen.o
            • LLVMCore.o
            LLVMCodeGen.o
              @@ -287,29 +281,27 @@
            • libLLVMAnalysis.a
            • libLLVMSupport.a
            • libLLVMTarget.a
            • -
            • libLLVMTransformUtils.a
            • LLVMCore.o
            LLVMDebugger.o
            • libLLVMSupport.a
            • libLLVMSystem.a
            • LLVMBCReader.o
            • -
            • LLVMCodeGen.o
            • LLVMCore.o
            • -
            • LLVMExecutionEngine.o
            LLVMExecutionEngine.o
            • libLLVMSupport.a
            • libLLVMSystem.a
            • libLLVMTarget.a
            • LLVMCore.o
            • -
            • LLVMInterpreter.o
            • -
            • LLVMJIT.o
            -
            LLVMInstrumentation.o
              +
              LLVMIA64.o
                +
              • libLLVMScalarOpts.a
              • libLLVMSupport.a
              • -
              • libLLVMTransformUtils.a
              • +
              • libLLVMTarget.a
              • +
              • LLVMCodeGen.o
              • LLVMCore.o
              • +
              • LLVMSelectionDAG.o
              LLVMInterpreter.o
              • libLLVMSupport.a
              • @@ -322,6 +314,7 @@
              • libLLVMSupport.a
              • libLLVMSystem.a
              • libLLVMTarget.a
              • +
              • LLVMCodeGen.o
              • LLVMCore.o
              • LLVMExecutionEngine.o
              @@ -331,25 +324,13 @@
            • libLLVMTarget.a
            • LLVMCodeGen.o
            • LLVMCore.o
            • +
            • LLVMSelectionDAG.o
            -
            LLVMProfilePaths.o
              -
            • libLLVMInstrumentation.a
            • -
            • libLLVMSupport.a
            • -
            • LLVMCore.o
            • -
            -
            LLVMScalarOpts.o
              -
            • libLLVMAnalysis.a
            • +
              LLVMSelectionDAG.o
              • libLLVMSupport.a
              • +
              • libLLVMSystem.a
              • libLLVMTarget.a
              • libLLVMTransformUtils.a
              • -
              • LLVMCore.o
              • -
              -
              LLVMSelectionDAG.o
                -
              • LLVMCodeGen.o
              • -
              • LLVMCore.o
              • -
              -
              LLVMSkeleton.o
                -
              • libLLVMTarget.a
              • LLVMCodeGen.o
              • LLVMCore.o
              @@ -359,28 +340,7 @@
            • libLLVMTarget.a
            • LLVMCodeGen.o
            • LLVMCore.o
            • -
            -
            LLVMSupport.o
              -
            • libLLVMSystem.a
            • -
            • LLVMbzip2.o
            • -
            -
            LLVMSystem.o
            -
            LLVMTarget.o
              -
            • libLLVMSupport.a
            • -
            • LLVMCore.o
            • -
            -
            LLVMTransformUtils.o
              -
            • libLLVMAnalysis.a
            • -
            • libLLVMScalarOpts.a
            • -
            • libLLVMSupport.a
            • -
            • LLVMCore.o
            • -
            -
            LLVMTransforms.o
              -
            • libLLVMAnalysis.a
            • -
            • libLLVMSupport.a
            • -
            • libLLVMTarget.a
            • -
            • libLLVMTransformUtils.a
            • -
            • LLVMCore.o
            • +
            • LLVMSelectionDAG.o
            LLVMX86.o
            • libLLVMScalarOpts.a
            • @@ -388,21 +348,9 @@
            • libLLVMTarget.a
            • LLVMCodeGen.o
            • LLVMCore.o
            • +
            • LLVMSelectionDAG.o
            -
            LLVMbzip2.o
            -
            LLVMipa.o
              -
            • libLLVMAnalysis.a
            • -
            • libLLVMSupport.a
            • -
            • LLVMCore.o
            • -
            -
            LLVMipo.o
              -
            • libLLVMAnalysis.a
            • -
            • libLLVMipa.a
            • -
            • libLLVMScalarOpts.a
            • -
            • libLLVMSupport.a
            • -
            • libLLVMTarget.a
            • -
            • libLLVMTransformUtils.a
            • -
            • LLVMCore.o
            • +
              LLVMbzip2.o
        @@ -443,7 +391,7 @@ Reid Spencer The LLVM Compiler Infrastructure -
        Last modified: $Date: 2006/04/20 17:42:23 $ +
        Last modified: $Date: 2006/05/13 02:22:01 $