From lattner at cs.uiuc.edu Mon Jan 17 00:26:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 00:26:13 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2005-01-17-CycleInDAG.ll Message-ID: <200501170626.j0H6QDPQ023443@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2005-01-17-CycleInDAG.ll added (r1.1) --- Log message: New testcase for a problem that occurred in 132.ijpeg --- Diffs of the changes: (+16 -0) Index: llvm/test/Regression/CodeGen/X86/2005-01-17-CycleInDAG.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2005-01-17-CycleInDAG.ll:1.1 *** /dev/null Mon Jan 17 00:26:09 2005 --- llvm/test/Regression/CodeGen/X86/2005-01-17-CycleInDAG.ll Mon Jan 17 00:25:59 2005 *************** *** 0 **** --- 1,16 ---- + ; This testcase was distilled from 132.ijpeg. Bsaically we cannot fold the + ; load into the sub instruction here as it induces a cycle in the dag, which + ; is invalid code (there is no correct way to order the instruction). Check + ; that we do not fold the load into the sub. + + ; RUN: llvm-as < %s | llc -march=x86 -disable-pattern-isel=0 | not grep 'sub.*GLOBAL' + + %GLOBAL = external global int + + int %test(int* %P1, int* %P2, int* %P3) { + %L = load int* %GLOBAL + store int 12, int* %P2 + %Y = load int* %P3 + %Z = sub int %Y, %L + ret int %Z + } From lattner at cs.uiuc.edu Mon Jan 17 00:27:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 00:27:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501170627.j0H6RBoS023455@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.60 -> 1.61 --- Log message: Fix test/Regression/CodeGen/X86/2005-01-17-CycleInDAG.ll and 132.ijpeg. Do not fold a load into an operation if it will induce a cycle in the DAG. Repeat after me: dAg. --- Diffs of the changes: (+62 -17) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.60 llvm/lib/Target/X86/X86ISelPattern.cpp:1.61 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.60 Sun Jan 16 19:34:14 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 00:26:58 2005 @@ -343,7 +343,7 @@ /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); - bool isFoldableLoad(SDOperand Op); + bool isFoldableLoad(SDOperand Op, SDOperand OtherOp); void EmitFoldedLoad(SDOperand Op, X86AddressMode &AM); @@ -920,7 +920,7 @@ unsigned Opc; if (ConstantSDNode *CN = dyn_cast(RHS)) { Opc = 0; - if (HasOneUse && isFoldableLoad(LHS)) { + if (HasOneUse && isFoldableLoad(LHS, RHS)) { switch (RHS.getValueType()) { default: break; case MVT::i1: @@ -959,7 +959,7 @@ } Opc = 0; - if (HasOneUse && isFoldableLoad(LHS)) { + if (HasOneUse && isFoldableLoad(LHS, RHS)) { switch (RHS.getValueType()) { default: break; case MVT::i1: @@ -996,9 +996,30 @@ BuildMI(BB, Opc, 2).addReg(Tmp1).addReg(Tmp2); } +/// NodeTransitivelyUsesValue - Return true if N or any of its uses uses Op. +/// The DAG cannot have cycles in it, by definition, so the visited set is not +/// needed to prevent infinite loops. The DAG CAN, however, have unbounded +/// reuse, so it prevents exponential cases. +/// +static bool NodeTransitivelyUsesValue(SDOperand N, SDOperand Op, + std::set &Visited) { + if (N == Op) return true; // Found it. + SDNode *Node = N.Val; + if (Node->getNumOperands() == 0) return false; // Leaf? + if (!Visited.insert(Node).second) return false; // Already visited? + + // Recurse for the first N-1 operands. + for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) + if (NodeTransitivelyUsesValue(Node->getOperand(i), Op, Visited)) + return true; + + // Tail recurse for the last operand. + return NodeTransitivelyUsesValue(Node->getOperand(0), Op, Visited); +} + /// isFoldableLoad - Return true if this is a load instruction that can safely /// be folded into an operation that uses it. -bool ISel::isFoldableLoad(SDOperand Op) { +bool ISel::isFoldableLoad(SDOperand Op, SDOperand OtherOp) { if (Op.getOpcode() != ISD::LOAD || // FIXME: currently can't fold constant pool indexes. isa(Op.getOperand(1))) @@ -1011,10 +1032,22 @@ assert(!LoweredTokens.count(Op.getValue(1)) && "Token lowered but value not in map?"); - // Finally, there can only be one use of its value. - return Op.Val->hasNUsesOfValue(1, 0); + // If there is not just one use of its value, we cannot fold. + if (!Op.Val->hasNUsesOfValue(1, 0)) return false; + + // Finally, we cannot fold the load into the operation if this would induce a + // cycle into the resultant dag. To check for this, see if OtherOp (the other + // operand of the operation we are folding the load into) can possible use the + // chain node defined by the load. + if (OtherOp.Val && !Op.Val->hasNUsesOfValue(0, 1)) { // Has uses of chain? + std::set Visited; + if (NodeTransitivelyUsesValue(OtherOp, Op.getValue(1), Visited)) + return false; + } + return true; } + /// EmitFoldedLoad - Ensure that the arguments of the load are code generated, /// and compute the address being loaded into AM. void ISel::EmitFoldedLoad(SDOperand Op, X86AddressMode &AM) { @@ -1136,7 +1169,7 @@ return Result; } - if (isFoldableLoad(N.getOperand(0))) { + if (isFoldableLoad(N.getOperand(0), SDOperand())) { static const unsigned Opc[3] = { X86::MOVZX32rm8, X86::MOVZX32rm16, X86::MOVZX16rm8 }; @@ -1163,7 +1196,7 @@ assert(N.getOperand(0).getValueType() != MVT::i1 && "Sign extend from bool not implemented!"); - if (isFoldableLoad(N.getOperand(0))) { + if (isFoldableLoad(N.getOperand(0), SDOperand())) { static const unsigned Opc[3] = { X86::MOVSX32rm8, X86::MOVSX32rm16, X86::MOVSX16rm8 }; @@ -1183,7 +1216,7 @@ } case ISD::TRUNCATE: // Fold TRUNCATE (LOAD P) into a smaller load from P. - if (isFoldableLoad(N.getOperand(0))) { + if (isFoldableLoad(N.getOperand(0), SDOperand())) { switch (N.getValueType()) { default: assert(0 && "Unknown truncate!"); case MVT::i1: @@ -1442,10 +1475,13 @@ Op0 = N.getOperand(0); Op1 = N.getOperand(1); - if (isFoldableLoad(Op0)) + if (isFoldableLoad(Op0, Op1)) { std::swap(Op0, Op1); + goto FoldAdd; + } - if (isFoldableLoad(Op1)) { + if (isFoldableLoad(Op1, Op0)) { + FoldAdd: switch (N.getValueType()) { default: assert(0 && "Cannot add this type!"); case MVT::i1: @@ -1622,9 +1658,10 @@ } } - if (isFoldableLoad(Op0)) + if (isFoldableLoad(Op0, Op1)) if (Node->getOpcode() != ISD::SUB) { std::swap(Op0, Op1); + goto FoldOps; } else { // Emit 'reverse' subract, with a memory operand. switch (N.getValueType()) { @@ -1641,7 +1678,8 @@ } } - if (isFoldableLoad(Op1)) { + if (isFoldableLoad(Op1, Op0)) { + FoldOps: switch (N.getValueType()) { default: assert(0 && "Cannot operate on this type!"); case MVT::i1: @@ -2433,16 +2471,17 @@ // Check to see if this is a load/op/store combination. if (N.getOperand(1).Val->hasOneUse() && - isFoldableLoad(N.getOperand(0).getValue(0)) && - !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType())) { + N.getOperand(1).Val->getNumOperands() == 2 && + !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType()) && + isFoldableLoad(N.getOperand(0).getValue(0), + N.getOperand(0).getValue(1))) { SDOperand TheLoad = N.getOperand(0).getValue(0); // Check to see if we are loading the same pointer that we're storing to. if (TheLoad.getOperand(1) == N.getOperand(2)) { // See if the stored value is a simple binary operator that uses the // load as one of its operands. SDOperand Op = N.getOperand(1); - if (Op.Val->getNumOperands() == 2 && - (Op.getOperand(0) == TheLoad || Op.getOperand(1) == TheLoad)) { + if ((Op.getOperand(0) == TheLoad || Op.getOperand(1) == TheLoad)) { // Finally, check to see if this is one of the ops we can handle! static const unsigned ADDTAB[] = { X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, @@ -2480,6 +2519,12 @@ const unsigned *TabPtr = 0; switch (Op.getOpcode()) { default: std::cerr << "CANNOT [mem] op= val: "; Op.Val->dump(); std::cerr << "\n"; break; + case ISD::MUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::SREM: + case ISD::UREM: break; + case ISD::ADD: TabPtr = ADDTAB; break; case ISD::SUB: TabPtr = SUBTAB; break; case ISD::AND: TabPtr = ANDTAB; break; From tbrethou at cs.uiuc.edu Mon Jan 17 00:47:43 2005 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Mon, 17 Jan 2005 00:47:43 -0600 (CST) Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Message-ID: <200501170647.AAA00004@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9BurgISel.cpp updated: 1.13 -> 1.14 --- Log message: Added tmp instructions to preserve ssa. --- Diffs of the changes: (+25 -7) Index: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp diff -u llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.13 llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.14 --- llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.13 Sun Jan 16 02:51:10 2005 +++ llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Mon Jan 17 00:47:26 2005 @@ -626,9 +626,13 @@ int32_t sC = (int32_t) C; bool smallNegValue =isSigned && sC < 0 && sC != -sC && -sC < (int32_t)MAXSIMM; + //Create TmpInstruction for intermediate values + TmpInstruction *tmpReg; + // Set the high 22 bits in dest if non-zero and simm13 field of OR not enough if (!smallNegValue && (C & ~MAXLO) && C > MAXSIMM) { - miSETHI = BuildMI(V9::SETHI, 2).addZImm(C).addRegDef(dest); + tmpReg = new TmpInstruction(mcfi, PointerType::get(val->getType()), (Instruction*) val); + miSETHI = BuildMI(V9::SETHI, 2).addZImm(C).addRegDef(tmpReg); miSETHI->getOperand(0).markHi32(); mvec.push_back(miSETHI); } @@ -638,7 +642,7 @@ if (miSETHI==NULL || C & MAXLO) { if (miSETHI) { // unsigned value with high-order bits set using SETHI - miOR = BuildMI(V9::ORi,3).addReg(dest).addZImm(C).addRegDef(dest); + miOR = BuildMI(V9::ORi,3).addReg(tmpReg).addZImm(C).addRegDef(dest); miOR->getOperand(1).markLo32(); } else { // unsigned or small signed value that fits in simm13 field of OR @@ -648,6 +652,8 @@ } mvec.push_back(miOR); } + else + mvec.push_back(BuildMI(V9::ORr,3).addReg(tmpReg).addMReg(SparcV9::g0).addRegDef(dest)); assert((miSETHI || miOR) && "Oops, no code was generated!"); } @@ -662,13 +668,19 @@ CreateSETSWConst(int32_t C, Instruction* dest, std::vector& mvec, MachineCodeForInstruction& mcfi, Value* val) { + + //TmpInstruction for intermediate values + TmpInstruction *tmpReg = new TmpInstruction(mcfi, (Instruction*) val); + // Set the low 32 bits of dest - CreateSETUWConst((uint32_t) C, dest, mvec, mcfi, val, /*isSigned*/true); + CreateSETUWConst((uint32_t) C, tmpReg, mvec, mcfi, val, /*isSigned*/true); // Sign-extend to the high 32 bits if needed. // NOTE: The value C = 0x80000000 is bad: -C == C and so -C is < MAXSIMM if (C < 0 && (C == -C || -C > (int32_t) MAXSIMM)) - mvec.push_back(BuildMI(V9::SRAi5,3).addReg(dest).addZImm(0).addRegDef(dest)); + mvec.push_back(BuildMI(V9::SRAi5,3).addReg(tmpReg).addZImm(0).addRegDef(dest)); + else + mvec.push_back(BuildMI(V9::ORr,3).addReg(tmpReg).addMReg(SparcV9::g0).addRegDef(dest)); } /// CreateSETXConst - Set a 64-bit signed or unsigned constant in the @@ -689,15 +701,21 @@ // Code to set the upper 32 bits of the value in register `tmpReg' CreateSETUWConst((C >> 32), tmpReg, mvec, mcfi, val); + //TmpInstruction for intermediate values + TmpInstruction *tmpReg2 = new TmpInstruction(mcfi, (Instruction*) val); + // Shift tmpReg left by 32 bits mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpReg).addZImm(32) - .addRegDef(tmpReg)); + .addRegDef(tmpReg2)); + //TmpInstruction for intermediate values + TmpInstruction *tmpReg3 = new TmpInstruction(mcfi, (Instruction*) val); + // Code to set the low 32 bits of the value in register `dest' - CreateSETUWConst(C, dest, mvec, mcfi, val); + CreateSETUWConst(C, tmpReg3, mvec, mcfi, val); // dest = OR(tmpReg, dest) - mvec.push_back(BuildMI(V9::ORr,3).addReg(dest).addReg(tmpReg).addRegDef(dest)); + mvec.push_back(BuildMI(V9::ORr,3).addReg(tmpReg3).addReg(tmpReg2).addRegDef(dest)); } /// CreateSETUWLabel - Set a 32-bit constant (given by a symbolic label) in From lattner at cs.uiuc.edu Mon Jan 17 00:48:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 00:48:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501170648.j0H6mH6Q024926@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.61 -> 1.62 --- Log message: Codegen this: int %foo(int %X) { %T = add int %X, 13 %S = mul int %T, 3 ret int %S } as this: mov %ECX, DWORD PTR [%ESP + 4] lea %EAX, DWORD PTR [%ECX + 2*%ECX + 39] ret instead of this: mov %ECX, DWORD PTR [%ESP + 4] mov %EAX, %ECX add %EAX, 13 imul %EAX, %EAX, 3 ret --- Diffs of the changes: (+18 -0) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.61 llvm/lib/Target/X86/X86ISelPattern.cpp:1.62 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.61 Mon Jan 17 00:26:58 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 00:48:02 2005 @@ -1636,6 +1636,24 @@ } } + // Fold common multiplies into LEA instructions. + if (Node->getOpcode() == ISD::MUL && N.getValueType() == MVT::i32) { + switch ((int)CN->getValue()) { + default: break; + case 3: + case 5: + case 9: + X86AddressMode AM; + // Remove N from exprmap so SelectAddress doesn't get confused. + ExprMap.erase(N); + SelectAddress(N, AM); + // Restore it to the map. + ExprMap[N] = Result; + addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), AM); + return Result; + } + } + switch (N.getValueType()) { default: assert(0 && "Cannot xor this type!"); case MVT::i1: From alkis at cs.uiuc.edu Mon Jan 17 07:16:56 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 07:16:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp In-Reply-To: <200501170648.j0H6mH6Q024926@apoc.cs.uiuc.edu> References: <200501170648.j0H6mH6Q024926@apoc.cs.uiuc.edu> Message-ID: <200501170716.56858.alkis@cs.uiuc.edu> On Monday 17 January 2005 00:48, Chris Lattner wrote: > Changes in directory llvm/lib/Target/X86: > > X86ISelPattern.cpp updated: 1.61 -> 1.62 > --- > Log message: > > Codegen this: > > int %foo(int %X) { > %T = add int %X, 13 > %S = mul int %T, 3 > ret int %S > } > > as this: > > mov %ECX, DWORD PTR [%ESP + 4] > lea %EAX, DWORD PTR [%ECX + 2*%ECX + 39] > ret > > instead of this: > > mov %ECX, DWORD PTR [%ESP + 4] > mov %EAX, %ECX > add %EAX, 13 > imul %EAX, %EAX, 3 > ret This doesn't look good: we should have coalesced the load with the move and everything should use %EAX. Any idea what is going on? -- Alkis From sabre at nondot.org Mon Jan 17 10:15:30 2005 From: sabre at nondot.org (Chris Lattner) Date: Mon, 17 Jan 2005 10:15:30 -0600 (CST) Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp In-Reply-To: <200501170716.56858.alkis@cs.uiuc.edu> References: <200501170648.j0H6mH6Q024926@apoc.cs.uiuc.edu> <200501170716.56858.alkis@cs.uiuc.edu> Message-ID: On Mon, 17 Jan 2005, Alkis Evlogimenos wrote: > On Monday 17 January 2005 00:48, Chris Lattner wrote: >> Changes in directory llvm/lib/Target/X86: >> >> X86ISelPattern.cpp updated: 1.61 -> 1.62 >> --- >> Log message: >> >> Codegen this: >> >> int %foo(int %X) { >> %T = add int %X, 13 >> %S = mul int %T, 3 >> ret int %S >> } >> >> as this: >> >> mov %ECX, DWORD PTR [%ESP + 4] >> lea %EAX, DWORD PTR [%ECX + 2*%ECX + 39] >> ret >> >> instead of this: >> >> mov %ECX, DWORD PTR [%ESP + 4] >> mov %EAX, %ECX >> add %EAX, 13 >> imul %EAX, %EAX, 3 >> ret > > This doesn't look good: we should have coalesced the load with the move and > everything should use %EAX. Any idea what is going on? Yes, currently argument loads cannot be folded into other operations because the isel assumes they can be used in other BB's. I plan to eventually add an optimization for arguments that have a single use. For them, I will emit the load only into the BB that uses the argument, allowing it to be folded. -Chris -- http://nondot.org/sabre/ http://llvm.cs.uiuc.edu/ From lattner at cs.uiuc.edu Mon Jan 17 11:14:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 11:14:58 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGISel.h Message-ID: <200501171714.j0HHEwIj026379@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGISel.h updated: 1.2 -> 1.3 --- Log message: Make methods private, add a method. --- Diffs of the changes: (+3 -0) Index: llvm/include/llvm/CodeGen/SelectionDAGISel.h diff -u llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.2 llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.3 --- llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.2 Thu Jan 13 11:58:35 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGISel.h Mon Jan 17 11:14:43 2005 @@ -50,6 +50,7 @@ virtual void InstructionSelectBasicBlock(SelectionDAG &SD) = 0; +private: SDOperand CopyValueToVirtualRegister(SelectionDAGLowering &SDL, Value *V, unsigned Reg); void SelectBasicBlock(BasicBlock *BB, MachineFunction &MF, @@ -58,6 +59,8 @@ void BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, std::vector > &PHINodesToUpdate, FunctionLoweringInfo &FuncInfo); + void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL, + std::vector &UnorderedChains); }; } From lattner at cs.uiuc.edu Mon Jan 17 11:15:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 11:15:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200501171715.j0HHFFHm026395@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.37 -> 1.38 SelectionDAGISel.cpp updated: 1.21 -> 1.22 --- Log message: Refactor code into a new method. --- Diffs of the changes: (+23 -13) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.37 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.38 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.37 Sat Jan 15 20:23:22 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Jan 17 11:15:02 2005 @@ -567,8 +567,7 @@ assert(VT == N1.getValueType() && "Shift operators return type must be the same as their first arg"); assert(MVT::isInteger(VT) && MVT::isInteger(N2.getValueType()) && - "Shifts only work on integers"); - assert(VT >= MVT::i8 && "Shift amount cannot be a MVT::i1"); + VT != MVT::i1 && "Shifts only work on integers"); break; default: break; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.21 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.22 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.21 Sun Jan 16 01:28:41 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 17 11:15:02 2005 @@ -806,30 +806,41 @@ return DAG.getCopyToReg(DAG.getRoot(), Op, Reg); } -void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, - std::vector > &PHINodesToUpdate, - FunctionLoweringInfo &FuncInfo) { - SelectionDAGLowering SDL(DAG, TLI, FuncInfo); - - std::vector UnorderedChains; - +void SelectionDAGISel:: +LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL, + std::vector &UnorderedChains) { // If this is the entry block, emit arguments. - Function *F = LLVMBB->getParent(); - if (LLVMBB == &F->front()) { + Function &F = *BB->getParent(); + + if (BB == &F.front()) { // FIXME: If an argument is only used in one basic block, we could directly // emit it (ONLY) into that block, not emitting the COPY_TO_VREG node. This // would improve codegen in several cases on X86 by allowing the loads to be // folded into the user operation. - std::vector Args = TLI.LowerArguments(*LLVMBB->getParent(), DAG); + std::vector Args = TLI.LowerArguments(F, SDL.DAG); + + FunctionLoweringInfo &FuncInfo = SDL.FuncInfo; unsigned a = 0; - for (Function::aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI,++a) + for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI,++a) if (!AI->use_empty()) { SDL.setValue(AI, Args[a]); UnorderedChains.push_back( CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI])); } } +} + + +void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, + std::vector > &PHINodesToUpdate, + FunctionLoweringInfo &FuncInfo) { + SelectionDAGLowering SDL(DAG, TLI, FuncInfo); + + std::vector UnorderedChains; + + // Lower any arguments needed in this block. + LowerArguments(LLVMBB, SDL, UnorderedChains); BB = FuncInfo.MBBMap[LLVMBB]; SDL.setCurrentBasicBlock(BB); From alkis at cs.uiuc.edu Mon Jan 17 11:34:10 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 11:34:10 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Makefile.test Message-ID: <200501171734.LAA32454@zion.cs.uiuc.edu> Changes in directory llvm-java/test: Makefile.test updated: 1.34 -> 1.35 --- Log message: Use -classpath instead of -cp as this works for Sun's javac as well. --- Diffs of the changes: (+1 -1) Index: llvm-java/test/Makefile.test diff -u llvm-java/test/Makefile.test:1.34 llvm-java/test/Makefile.test:1.35 --- llvm-java/test/Makefile.test:1.34 Tue Jan 11 00:33:59 2005 +++ llvm-java/test/Makefile.test Mon Jan 17 11:33:59 2005 @@ -27,7 +27,7 @@ $(PREFIXED_CLASS_FILES): $(addsuffix .java,$(JAVA_TESTS)) $(Echo) Compiling $? $(Verb)mkdir -p Output - $(Verb)$(JAVAC) -cp Output -d Output $? + $(Verb)$(JAVAC) -classpath Output -d Output $? $(Verb)touch $@ # Compiled bytecode for tests From alkis at cs.uiuc.edu Mon Jan 17 11:34:45 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 11:34:45 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Makefile Message-ID: <200501171734.LAA32466@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Makefile updated: 1.33 -> 1.34 --- Log message: Change BUILD_SRC_ROOT to PROJ_SRC_ROOT as per recent makefile improvements. --- Diffs of the changes: (+1 -1) Index: llvm-java/test/Programs/SingleSource/UnitTests/Makefile diff -u llvm-java/test/Programs/SingleSource/UnitTests/Makefile:1.33 llvm-java/test/Programs/SingleSource/UnitTests/Makefile:1.34 --- llvm-java/test/Programs/SingleSource/UnitTests/Makefile:1.33 Thu Dec 16 16:52:02 2004 +++ llvm-java/test/Programs/SingleSource/UnitTests/Makefile Mon Jan 17 11:34:34 2005 @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL := ../../../.. -CPPFLAGS+=-I$(BUILD_SRC_ROOT)/include/llvm/Java +CPPFLAGS+=-I$(PROJ_SRC_ROOT)/include/llvm/Java BYTECODE_LIBRARY=1 SHARED_LIBRARY=1 LIBRARYNAME=test From lattner at cs.uiuc.edu Mon Jan 17 11:49:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 11:49:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501171749.j0HHnTPt028434@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.62 -> 1.63 --- Log message: Fix a major regression last night that prevented us from producing [mem] op= reg operations. The body of the if is less indented but unmodified in this patch. --- Diffs of the changes: (+111 -109) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.62 llvm/lib/Target/X86/X86ISelPattern.cpp:1.63 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.62 Mon Jan 17 00:48:02 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 11:49:14 2005 @@ -2489,128 +2489,130 @@ // Check to see if this is a load/op/store combination. if (N.getOperand(1).Val->hasOneUse() && + N.getOperand(0).getOpcode() == ISD::LOAD && N.getOperand(1).Val->getNumOperands() == 2 && - !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType()) && - isFoldableLoad(N.getOperand(0).getValue(0), - N.getOperand(0).getValue(1))) { + !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType())) { SDOperand TheLoad = N.getOperand(0).getValue(0); + + // See if the stored value is a simple binary operator that uses the load + // as one of its operands. + SDOperand Op = N.getOperand(1); + // Check to see if we are loading the same pointer that we're storing to. - if (TheLoad.getOperand(1) == N.getOperand(2)) { - // See if the stored value is a simple binary operator that uses the - // load as one of its operands. - SDOperand Op = N.getOperand(1); - if ((Op.getOperand(0) == TheLoad || Op.getOperand(1) == TheLoad)) { - // Finally, check to see if this is one of the ops we can handle! - static const unsigned ADDTAB[] = { - X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, - X86::ADD8mr, X86::ADD16mr, X86::ADD32mr, - }; - static const unsigned SUBTAB[] = { - X86::SUB8mi, X86::SUB16mi, X86::SUB32mi, - X86::SUB8mr, X86::SUB16mr, X86::SUB32mr, - }; - static const unsigned ANDTAB[] = { - X86::AND8mi, X86::AND16mi, X86::AND32mi, - X86::AND8mr, X86::AND16mr, X86::AND32mr, - }; - static const unsigned ORTAB[] = { - X86::OR8mi, X86::OR16mi, X86::OR32mi, - X86::OR8mr, X86::OR16mr, X86::OR32mr, - }; - static const unsigned XORTAB[] = { - X86::XOR8mi, X86::XOR16mi, X86::XOR32mi, - X86::XOR8mr, X86::XOR16mr, X86::XOR32mr, - }; - static const unsigned SHLTAB[] = { - X86::SHL8mi, X86::SHL16mi, X86::SHL32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - static const unsigned SARTAB[] = { - X86::SAR8mi, X86::SAR16mi, X86::SAR32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - static const unsigned SHRTAB[] = { - X86::SHR8mi, X86::SHR16mi, X86::SHR32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - - const unsigned *TabPtr = 0; - switch (Op.getOpcode()) { - default: std::cerr << "CANNOT [mem] op= val: "; Op.Val->dump(); std::cerr << "\n"; break; - case ISD::MUL: - case ISD::SDIV: - case ISD::UDIV: - case ISD::SREM: - case ISD::UREM: break; - - case ISD::ADD: TabPtr = ADDTAB; break; - case ISD::SUB: TabPtr = SUBTAB; break; - case ISD::AND: TabPtr = ANDTAB; break; - case ISD:: OR: TabPtr = ORTAB; break; - case ISD::XOR: TabPtr = XORTAB; break; - case ISD::SHL: TabPtr = SHLTAB; break; - case ISD::SRA: TabPtr = SARTAB; break; - case ISD::SRL: TabPtr = SHRTAB; break; - } + if (TheLoad.getOperand(1) == N.getOperand(2) && + ((Op.getOperand(0) == TheLoad && + isFoldableLoad(TheLoad, Op.getOperand(1))) || + (Op.getOperand(1) == TheLoad && + isFoldableLoad(TheLoad, Op.getOperand(0))))) { + // Finally, check to see if this is one of the ops we can handle! + static const unsigned ADDTAB[] = { + X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, + X86::ADD8mr, X86::ADD16mr, X86::ADD32mr, + }; + static const unsigned SUBTAB[] = { + X86::SUB8mi, X86::SUB16mi, X86::SUB32mi, + X86::SUB8mr, X86::SUB16mr, X86::SUB32mr, + }; + static const unsigned ANDTAB[] = { + X86::AND8mi, X86::AND16mi, X86::AND32mi, + X86::AND8mr, X86::AND16mr, X86::AND32mr, + }; + static const unsigned ORTAB[] = { + X86::OR8mi, X86::OR16mi, X86::OR32mi, + X86::OR8mr, X86::OR16mr, X86::OR32mr, + }; + static const unsigned XORTAB[] = { + X86::XOR8mi, X86::XOR16mi, X86::XOR32mi, + X86::XOR8mr, X86::XOR16mr, X86::XOR32mr, + }; + static const unsigned SHLTAB[] = { + X86::SHL8mi, X86::SHL16mi, X86::SHL32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + static const unsigned SARTAB[] = { + X86::SAR8mi, X86::SAR16mi, X86::SAR32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + static const unsigned SHRTAB[] = { + X86::SHR8mi, X86::SHR16mi, X86::SHR32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + + const unsigned *TabPtr = 0; + switch (Op.getOpcode()) { + default: std::cerr << "CANNOT [mem] op= val: "; Op.Val->dump(); std::cerr << "\n"; break; + case ISD::MUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::SREM: + case ISD::UREM: break; + + case ISD::ADD: TabPtr = ADDTAB; break; + case ISD::SUB: TabPtr = SUBTAB; break; + case ISD::AND: TabPtr = ANDTAB; break; + case ISD:: OR: TabPtr = ORTAB; break; + case ISD::XOR: TabPtr = XORTAB; break; + case ISD::SHL: TabPtr = SHLTAB; break; + case ISD::SRA: TabPtr = SARTAB; break; + case ISD::SRL: TabPtr = SHRTAB; break; + } - if (TabPtr) { - // Handle: [mem] op= CST - SDOperand Op0 = Op.getOperand(0); - SDOperand Op1 = Op.getOperand(1); - if (ConstantSDNode *CN = dyn_cast(Op1)) { - switch (Op0.getValueType()) { // Use Op0's type because of shifts. - default: break; - case MVT::i1: - case MVT::i8: Opc = TabPtr[0]; break; - case MVT::i16: Opc = TabPtr[1]; break; - case MVT::i32: Opc = TabPtr[2]; break; - } - - if (Opc) { - if (getRegPressure(TheLoad.getOperand(0)) > - getRegPressure(TheLoad.getOperand(1))) { - Select(TheLoad.getOperand(0)); - SelectAddress(TheLoad.getOperand(1), AM); - } else { - SelectAddress(TheLoad.getOperand(1), AM); - Select(TheLoad.getOperand(0)); - } - - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); - return; - } + if (TabPtr) { + // Handle: [mem] op= CST + SDOperand Op0 = Op.getOperand(0); + SDOperand Op1 = Op.getOperand(1); + if (ConstantSDNode *CN = dyn_cast(Op1)) { + switch (Op0.getValueType()) { // Use Op0's type because of shifts. + default: break; + case MVT::i1: + case MVT::i8: Opc = TabPtr[0]; break; + case MVT::i16: Opc = TabPtr[1]; break; + case MVT::i32: Opc = TabPtr[2]; break; } - - // If we have [mem] = V op [mem], try to turn it into: - // [mem] = [mem] op V. - if (Op1 == TheLoad && Op.getOpcode() != ISD::SUB && - Op.getOpcode() != ISD::SHL && Op.getOpcode() != ISD::SRA && - Op.getOpcode() != ISD::SRL) - std::swap(Op0, Op1); - - if (Op0 == TheLoad) { - switch (Op0.getValueType()) { - default: break; - case MVT::i1: - case MVT::i8: Opc = TabPtr[3]; break; - case MVT::i16: Opc = TabPtr[4]; break; - case MVT::i32: Opc = TabPtr[5]; break; - } - - if (Opc) { + + if (Opc) { + if (getRegPressure(TheLoad.getOperand(0)) > + getRegPressure(TheLoad.getOperand(1))) { Select(TheLoad.getOperand(0)); SelectAddress(TheLoad.getOperand(1), AM); - unsigned Reg = SelectExpr(Op1); - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); - return; - } + } else { + SelectAddress(TheLoad.getOperand(1), AM); + Select(TheLoad.getOperand(0)); + } + + addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); + return; + } + } + + // If we have [mem] = V op [mem], try to turn it into: + // [mem] = [mem] op V. + if (Op1 == TheLoad && Op.getOpcode() != ISD::SUB && + Op.getOpcode() != ISD::SHL && Op.getOpcode() != ISD::SRA && + Op.getOpcode() != ISD::SRL) + std::swap(Op0, Op1); + + if (Op0 == TheLoad) { + switch (Op0.getValueType()) { + default: break; + case MVT::i1: + case MVT::i8: Opc = TabPtr[3]; break; + case MVT::i16: Opc = TabPtr[4]; break; + case MVT::i32: Opc = TabPtr[5]; break; + } + + if (Opc) { + Select(TheLoad.getOperand(0)); + SelectAddress(TheLoad.getOperand(1), AM); + unsigned Reg = SelectExpr(Op1); + addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); + return; } } } } } - switch (N.getOperand(1).getValueType()) { default: assert(0 && "Cannot store this type!"); case MVT::i1: From lattner at cs.uiuc.edu Mon Jan 17 11:55:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 11:55:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200501171755.j0HHtVrN028459@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.22 -> 1.23 --- Log message: Implement a target independent optimization to codegen arguments only into the basic block that uses them if possible. This is a big win on X86, as it lets us fold the argument loads into instructions and reduce register pressure (by not loading all of the arguments in the entry block). For this (contrived to show the optimization) testcase: int %argtest(int %A, int %B) { %X = sub int 12345, %A br label %L L: %Y = add int %X, %B ret int %Y } we used to produce: argtest: mov %ECX, DWORD PTR [%ESP + 4] mov %EAX, 12345 sub %EAX, %ECX mov %EDX, DWORD PTR [%ESP + 8] .LBBargtest_1: # L add %EAX, %EDX ret now we produce: argtest: mov %EAX, 12345 sub %EAX, DWORD PTR [%ESP + 4] .LBBargtest_1: # L add %EAX, DWORD PTR [%ESP + 8] ret This also fixes the FIXME in the code. BTW, this occurs in real code. 164.gzip shrinks from 8623 to 8608 lines of .s file. The stack frame in huft_build shrinks from 1644->1628 bytes, inflate_codes shrinks from 116->108 bytes, and inflate_block from 2620->2612, due to fewer spills. Take that alkis. :-) --- Diffs of the changes: (+69 -12) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.22 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.23 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.22 Mon Jan 17 11:15:02 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 17 11:55:19 2005 @@ -68,6 +68,14 @@ /// anywhere in the function. std::map StaticAllocaMap; + /// BlockLocalArguments - If any arguments are only used in a single basic + /// block, and if the target can access the arguments without side-effects, + /// avoid emitting CopyToReg nodes for those arguments. This map keeps + /// track of which arguments are local to each BB. + std::multimap > BlockLocalArguments; + + unsigned MakeReg(MVT::ValueType VT) { return RegMap->createVirtualRegister(TLI.getRegClassFor(VT)); } @@ -806,28 +814,77 @@ return DAG.getCopyToReg(DAG.getRoot(), Op, Reg); } +/// IsOnlyUsedInOneBasicBlock - If the specified argument is only used in a +/// single basic block, return that block. Otherwise, return a null pointer. +static BasicBlock *IsOnlyUsedInOneBasicBlock(Argument *A) { + if (A->use_empty()) return 0; + BasicBlock *BB = cast(A->use_back())->getParent(); + for (Argument::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E; + ++UI) + if (isa(*UI) || cast(*UI)->getParent() != BB) + return 0; // Disagreement among the users? + return BB; +} + void SelectionDAGISel:: LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL, std::vector &UnorderedChains) { // If this is the entry block, emit arguments. Function &F = *BB->getParent(); + FunctionLoweringInfo &FuncInfo = SDL.FuncInfo; if (BB == &F.front()) { - // FIXME: If an argument is only used in one basic block, we could directly - // emit it (ONLY) into that block, not emitting the COPY_TO_VREG node. This - // would improve codegen in several cases on X86 by allowing the loads to be - // folded into the user operation. + SDOperand OldRoot = SDL.DAG.getRoot(); + std::vector Args = TLI.LowerArguments(F, SDL.DAG); - FunctionLoweringInfo &FuncInfo = SDL.FuncInfo; + // If there were side effects accessing the argument list, do not do + // anything special. + if (OldRoot != SDL.DAG.getRoot()) { + unsigned a = 0; + for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI,++a) + if (!AI->use_empty()) { + SDL.setValue(AI, Args[a]); + SDOperand Copy = + CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]); + UnorderedChains.push_back(Copy); + } + } else { + // Otherwise, if any argument is only accessed in a single basic block, + // emit that argument only to that basic block. + unsigned a = 0; + for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI,++a) + if (!AI->use_empty()) { + if (BasicBlock *BBU = IsOnlyUsedInOneBasicBlock(AI)) { + FuncInfo.BlockLocalArguments.insert(std::make_pair(BBU, + std::make_pair(AI, a))); + } else { + SDL.setValue(AI, Args[a]); + SDOperand Copy = + CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]); + UnorderedChains.push_back(Copy); + } + } + } + } - unsigned a = 0; - for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI,++a) - if (!AI->use_empty()) { - SDL.setValue(AI, Args[a]); - UnorderedChains.push_back( - CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI])); - } + // See if there are any block-local arguments that need to be emitted in this + // block. + + if (!FuncInfo.BlockLocalArguments.empty()) { + std::multimap >::iterator BLAI = + FuncInfo.BlockLocalArguments.lower_bound(BB); + if (BLAI != FuncInfo.BlockLocalArguments.end() && BLAI->first == BB) { + // Lower the arguments into this block. + std::vector Args = TLI.LowerArguments(F, SDL.DAG); + + // Set up the value mapping for the local arguments. + for (; BLAI != FuncInfo.BlockLocalArguments.end() && BLAI->first == BB; + ++BLAI) + SDL.setValue(BLAI->second.first, Args[BLAI->second.second]); + + // Any dead arguments will just be ignored here. + } } } From alkis at cs.uiuc.edu Mon Jan 17 12:21:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 12:21:14 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/OperandStack.cpp Locals.cpp Compiler.cpp Message-ID: <200501171821.MAA00529@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: OperandStack.cpp updated: 1.6 -> 1.7 Locals.cpp updated: 1.4 -> 1.5 Compiler.cpp updated: 1.183 -> 1.184 --- Log message: Pull ObjectBaseTy and ObjectBaseRefTy out of Compiler::ClassInfo class. Also use ObjectBaseRefTy for all types in function signatures. --- Diffs of the changes: (+47 -68) Index: llvm-java/lib/Compiler/OperandStack.cpp diff -u llvm-java/lib/Compiler/OperandStack.cpp:1.6 llvm-java/lib/Compiler/OperandStack.cpp:1.7 --- llvm-java/lib/Compiler/OperandStack.cpp:1.6 Tue Jan 11 07:55:29 2005 +++ llvm-java/lib/Compiler/OperandStack.cpp Mon Jan 17 12:21:03 2005 @@ -30,7 +30,7 @@ // All pointer types are cast to a pointer to // llvm_java_lang_object_base. if (isa(valueTy)) - value = new CastInst(value, java_lang_Object_RefType, + value = new CastInst(value, ObjectBaseRefTy, "to-object-base", insertAtEnd); // Values of jboolean, jbyte, jchar and jshort are extended to a // jint when pushed on the operand stack. Index: llvm-java/lib/Compiler/Locals.cpp diff -u llvm-java/lib/Compiler/Locals.cpp:1.4 llvm-java/lib/Compiler/Locals.cpp:1.5 --- llvm-java/lib/Compiler/Locals.cpp:1.4 Tue Jan 11 07:55:29 2005 +++ llvm-java/lib/Compiler/Locals.cpp Mon Jan 17 12:21:03 2005 @@ -34,7 +34,7 @@ // All pointer types are cast to a pointer to // llvm_java_lang_object_base. if (isa(valueTy)) - value = new CastInst(value, java_lang_Object_RefType, + value = new CastInst(value, ObjectBaseRefTy, "to-object-base", insertAtEnd); if (!TheLocals[i] || Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.183 llvm-java/lib/Compiler/Compiler.cpp:1.184 --- llvm-java/lib/Compiler/Compiler.cpp:1.183 Tue Jan 11 07:55:29 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Mon Jan 17 12:21:03 2005 @@ -48,8 +48,8 @@ using namespace llvm; using namespace llvm::Java; -Type* llvm::Java::java_lang_Object_Type; -Type* llvm::Java::java_lang_Object_RefType; +Type* llvm::Java::ObjectBaseTy = OpaqueType::get(); +Type* llvm::Java::ObjectBaseRefTy = PointerType::get(ObjectBaseTy); namespace llvm { namespace Java { namespace { @@ -101,7 +101,6 @@ Field2IndexMap f2iMap; static unsigned InterfaceCount; - static Type* ObjectBaseTy; }; typedef std::map Class2ClassInfoMap; Class2ClassInfoMap c2ciMap_; @@ -220,25 +219,16 @@ case 'V': return Type::VoidTy; case 'L': { unsigned e = descr.find(';', i); - std::string className = descr.substr(i, e - i); i = e + 1; - return PointerType::get(getClassInfo(ClassFile::get(className)).type); + return ObjectBaseRefTy; } case '[': - if (descr[i] == '[') { + // Skip '['s. + if (descr[i] == '[') do { ++i; } while (descr[i] == '['); - getTypeHelper(descr, i, NULL); - return PointerType::get(getObjectArrayInfo().type); - } - else if (descr[i] == 'L') { - getTypeHelper(descr, i, NULL); - return PointerType::get(getObjectArrayInfo().type); - } - else { - return PointerType::get( - getPrimitiveArrayInfo(getTypeHelper(descr, i, NULL)).type); - } - break; + // Consume the element type + getTypeHelper(descr, i, NULL); + return ObjectBaseRefTy; case '(': { std::vector params; if (self) @@ -248,7 +238,7 @@ return FunctionType::get(getTypeHelper(descr, ++i, NULL),params, false); } // FIXME: Throw something - default: return NULL; + default: assert(0 && "Cannot parse type descriptor!"); } } @@ -273,26 +263,27 @@ // Both array and object types are pointers to llvm_object_base case 'L': { unsigned e = descr.find(';', i); - std::string className = descr.substr(i, e - i); i = e + 1; - return PointerType::get(ClassInfo::ObjectBaseTy); + return ObjectBaseRefTy; } case '[': + // Skip '['s. if (descr[i] == '[') do { ++i; } while (descr[i] == '['); - getJNITypeHelper(descr, i); - return PointerType::get(ClassInfo::ObjectBaseTy); + // Consume the element type + getTypeHelper(descr, i, NULL); + return ObjectBaseRefTy; case '(': { std::vector params; // JNIEnv* params.push_back(JNIEnvPtr_->getType()); - params.push_back(PointerType::get(ClassInfo::ObjectBaseTy)); + params.push_back(ObjectBaseRefTy); while (descr[i] != ')') params.push_back(getJNITypeHelper(descr, i)); return FunctionType::get(getJNITypeHelper(descr, ++i), params, false); } // FIXME: Throw something - default: return NULL; + default: assert(0 && "Cannot parse type descriptor!"); } } @@ -303,18 +294,19 @@ ClassFile* cf = ClassFile::get("java/lang/Object"); ClassInfo& ci = c2ciMap_[cf]; + module_.addTypeName(LLVM_JAVA_OBJECT_BASE, ObjectBaseTy); + assert(!ci.type && ci.f2iMap.empty() && "java/lang/Object ClassInfo should not be initialized!"); + ci.type = OpaqueType::get(); std::vector elements; // Because this is java/lang/Object, we add the opaque // llvm_java_object_base type first. - ClassInfo::ObjectBaseTy = OpaqueType::get(); - module_.addTypeName(LLVM_JAVA_OBJECT_BASE, ClassInfo::ObjectBaseTy); ci.f2iMap.insert(std::make_pair(LLVM_JAVA_OBJECT_BASE, elements.size())); - elements.push_back(ClassInfo::ObjectBaseTy); + elements.push_back(ObjectBaseTy); const Fields& fields = cf->getFields(); for (unsigned i = 0, e = fields.size(); i != e; ++i) { @@ -325,16 +317,16 @@ elements.push_back(getType(field->getDescriptor())); } } + PATypeHolder holder = ci.type; - cast(ci.type)->refineAbstractTypeTo(StructType::get(elements)); + cast(ci.type)-> + refineAbstractTypeTo(StructType::get(elements)); ci.type = holder.get(); + DEBUG(std::cerr << "Adding java/lang/Object = " << *ci.type << " to type map\n"); module_.addTypeName("java/lang/Object", ci.type); - java_lang_Object_Type = ci.type; - java_lang_Object_RefType = PointerType::get(ci.type); - assert(ci.type && "ClassInfo not initialized properly!"); emitStaticInitializers(cf); DEBUG(std::cerr << "Built ClassInfo for: java/lang/Object\n"); @@ -405,7 +397,7 @@ std::string funcName = "java/lang/Object/" + methodDescr; const FunctionType* funcTy = cast( - getType(method->getDescriptor(), ClassInfo::ObjectBaseTy)); + getType(method->getDescriptor(), ObjectBaseTy)); Function* vfun = module_.getOrInsertFunction(funcName, funcTy); scheduleFunction(vfun); @@ -495,7 +487,7 @@ std::vector elements; elements.reserve(3); - elements.push_back(getClassInfo(ClassFile::get("java/lang/Object")).type); + elements.push_back(ObjectBaseTy); elements.push_back(Type::UIntTy); arrayInfo.f2iMap.insert(std::make_pair("", elements.size())); elements.push_back(ArrayType::get(elementTy, 0)); @@ -564,9 +556,8 @@ /// Returns the ClassInfo object associated with an array of the /// specified element type. const ClassInfo& getObjectArrayInfo() { - static ClassInfo arrayInfo = buildArrayClassInfo( - PointerType::get( - getClassInfo(ClassFile::get("java/lang/Object")).type)); + static ClassInfo arrayInfo = + buildArrayClassInfo(ObjectBaseRefTy); return arrayInfo; } @@ -792,7 +783,7 @@ std::string funcName = className + '/' + methodDescr; const FunctionType* funcTy = cast( - getType(method->getDescriptor(), ClassInfo::ObjectBaseTy)); + getType(method->getDescriptor(), ObjectBaseTy)); llvm::Constant* vfun = llvm::Constant::getNullValue(PointerType::get(funcTy)); if (!cf->isInterface() && !method->isAbstract()) { @@ -1251,8 +1242,7 @@ std::vector params; params.push_back(JNIEnvPtr_); if (method->isStatic()) - params.push_back(llvm::Constant::getNullValue( - PointerType::get(ClassInfo::ObjectBaseTy))); + params.push_back(llvm::Constant::getNullValue(ObjectBaseRefTy)); for (Function::aiterator A = function->abegin(), E = function->aend(); A != E; ++A) { params.push_back( @@ -1440,7 +1430,7 @@ FunctionType* funcTy = cast( getType(method->getDescriptor(), - method->isStatic() ? NULL : ClassInfo::ObjectBaseTy)); + method->isStatic() ? NULL : ObjectBaseTy)); std::string funcName = clazz->getThisClass()->getName()->str() + '/' + method->getName()->str() + method->getDescriptor()->str(); @@ -1509,9 +1499,7 @@ } void do_aconst_null() { - ClassFile* root = ClassFile::get("java/lang/Object"); - push(llvm::Constant::getNullValue( - PointerType::get(getClassInfo(root).type))); + push(llvm::Constant::getNullValue(ObjectBaseRefTy)); } void do_iconst(int value) { @@ -2123,7 +2111,7 @@ FunctionType* funTy = cast(getType(nameAndType->getDescriptor(), - ClassInfo::ObjectBaseTy)); + ObjectBaseTy)); std::vector params(getParams(funTy)); @@ -2131,8 +2119,7 @@ objRef = new CastInst(objRef, PointerType::get(ci->type), "this", currentBB_); Value* objBase = - new CastInst(objRef, PointerType::get(ClassInfo::ObjectBaseTy), - TMP, currentBB_); + new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_GETOBJECTCLASS, PointerType::get(VTableInfo::VTableBaseTy), objBase->getType(), NULL); @@ -2165,7 +2152,7 @@ FunctionType* funcTy = cast(getType(nameAndType->getDescriptor(), - ClassInfo::ObjectBaseTy)); + ObjectBaseTy)); Function* function = module_.getOrInsertFunction(funcName, funcTy); scheduleFunction(function); makeCall(function, getParams(funcTy)); @@ -2207,7 +2194,7 @@ FunctionType* funTy = cast(getType(nameAndType->getDescriptor(), - ClassInfo::ObjectBaseTy)); + ObjectBaseTy)); std::vector params(getParams(funTy)); @@ -2215,8 +2202,7 @@ objRef = new CastInst(objRef, PointerType::get(ci->type), "this", currentBB_); Value* objBase = - new CastInst(objRef, PointerType::get(ClassInfo::ObjectBaseTy), - TMP, currentBB_); + new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_GETOBJECTCLASS, PointerType::get(VTableInfo::VTableBaseTy), objBase->getType(), NULL); @@ -2260,15 +2246,13 @@ const VTableInfo& vi = getVTableInfo(cf); Value* objRef = new MallocInst(ci.type, NULL, TMP, currentBB_); - Value* objBase = new CastInst(objRef, - PointerType::get(ClassInfo::ObjectBaseTy), - TMP, currentBB_); + Value* objBase = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Value* vtable = new CastInst(vi.vtable, PointerType::get(VTableInfo::VTableBaseTy), TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_SETOBJECTCLASS, Type::VoidTy, - PointerType::get(ClassInfo::ObjectBaseTy), + ObjectBaseRefTy, PointerType::get(VTableInfo::VTableBaseTy), NULL); new CallInst(f, objBase, vtable, "", currentBB_); push(objRef); @@ -2341,15 +2325,14 @@ Value* lengthPtr = getArrayLengthPtr(objRef); new StoreInst(count, lengthPtr, currentBB_); // Install the vtable pointer. - Value* objBase = new CastInst(objRef, - PointerType::get(ClassInfo::ObjectBaseTy), + Value* objBase = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Value* vtable = new CastInst(vi.vtable, PointerType::get(VTableInfo::VTableBaseTy), TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_SETOBJECTCLASS, Type::VoidTy, - PointerType::get(ClassInfo::ObjectBaseTy), + ObjectBaseRefTy, PointerType::get(VTableInfo::VTableBaseTy), NULL); new CallInst(f, objBase, vtable, "", currentBB_); push(objRef); @@ -2368,11 +2351,10 @@ void do_athrow() { Value* objRef = pop(); - objRef = new CastInst(objRef, PointerType::get(ClassInfo::ObjectBaseTy), - TMP, currentBB_); + objRef = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_THROW, Type::IntTy, - PointerType::get(ClassInfo::ObjectBaseTy), NULL); + ObjectBaseRefTy, NULL); new CallInst(f, objRef, TMP, currentBB_); new UnreachableInst(currentBB_); } @@ -2386,8 +2368,7 @@ Value* objRef = pop(); Value* objBase = - new CastInst(objRef, PointerType::get(ClassInfo::ObjectBaseTy), - TMP, currentBB_); + new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_ISINSTANCEOF, Type::IntTy, objBase->getType(), PointerType::get(VTableInfo::VTableBaseTy), NULL); @@ -2414,8 +2395,7 @@ Value* objRef = pop(); Value* objBase = - new CastInst(objRef, PointerType::get(ClassInfo::ObjectBaseTy), - TMP, currentBB_); + new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_ISINSTANCEOF, Type::IntTy, objBase->getType(), PointerType::get(VTableInfo::VTableBaseTy), NULL); @@ -2440,7 +2420,6 @@ }; unsigned Compiler::ClassInfo::InterfaceCount = 0; - Type* Compiler::ClassInfo::ObjectBaseTy; Type* Compiler::VTableInfo::VTableBaseTy; StructType* Compiler::VTableInfo::VTableTy; StructType* Compiler::VTableInfo::TypeInfoTy; From alkis at cs.uiuc.edu Mon Jan 17 12:21:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 12:21:14 -0600 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/Compiler.h Message-ID: <200501171821.MAA00532@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: Compiler.h updated: 1.11 -> 1.12 --- Log message: Pull ObjectBaseTy and ObjectBaseRefTy out of Compiler::ClassInfo class. Also use ObjectBaseRefTy for all types in function signatures. --- Diffs of the changes: (+2 -2) Index: llvm-java/include/llvm/Java/Compiler.h diff -u llvm-java/include/llvm/Java/Compiler.h:1.11 llvm-java/include/llvm/Java/Compiler.h:1.12 --- llvm-java/include/llvm/Java/Compiler.h:1.11 Tue Jan 11 07:55:29 2005 +++ llvm-java/include/llvm/Java/Compiler.h Mon Jan 17 12:21:03 2005 @@ -21,8 +21,8 @@ std::auto_ptr compile(const std::string& className); - extern Type* java_lang_Object_Type; - extern Type* java_lang_Object_RefType; + extern Type* ObjectBaseTy; + extern Type* ObjectBaseRefTy; } } // namespace llvm::Java From lattner at cs.uiuc.edu Mon Jan 17 13:25:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 13:25:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501171925.j0HJPfgj029197@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.63 -> 1.64 --- Log message: Refactor load/op/store folding into it's own method, no functionality changes. --- Diffs of the changes: (+141 -125) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.63 llvm/lib/Target/X86/X86ISelPattern.cpp:1.64 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.63 Mon Jan 17 11:49:14 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 13:25:26 2005 @@ -345,7 +345,7 @@ bool isFoldableLoad(SDOperand Op, SDOperand OtherOp); void EmitFoldedLoad(SDOperand Op, X86AddressMode &AM); - + bool TryToFoldLoadOpStore(SDNode *Node); void EmitCMP(SDOperand LHS, SDOperand RHS, bool isOnlyUse); bool EmitBranchCC(MachineBasicBlock *Dest, SDOperand Chain, SDOperand Cond); @@ -2236,6 +2236,144 @@ return 0; } +/// TryToFoldLoadOpStore - Given a store node, try to fold together a +/// load/op/store instruction. If successful return true. +bool ISel::TryToFoldLoadOpStore(SDNode *Node) { + assert(Node->getOpcode() == ISD::STORE && "Can only do this for stores!"); + SDOperand Chain = Node->getOperand(0); + SDOperand StVal = Node->getOperand(1); + + // The chain has to be a load, the stored value must be an integer binary + // operation with one use. + if (Chain.getOpcode() != ISD::LOAD || !StVal.Val->hasOneUse() || + StVal.Val->getNumOperands() != 2 || + MVT::isFloatingPoint(StVal.getValueType())) + return false; + + SDOperand TheLoad = Chain.getValue(0); + + // Check to see if we are loading the same pointer that we're storing to. + if (TheLoad.getOperand(1) != Node->getOperand(2)) + return false; + + // Make sure that one of the operands of the binop is the load, and that the + // load folds into the binop. + if (((StVal.getOperand(0) != TheLoad || + !isFoldableLoad(TheLoad, StVal.getOperand(1))) && + (StVal.getOperand(1) != TheLoad || + !isFoldableLoad(TheLoad, StVal.getOperand(0))))) + return false; + + // Finally, check to see if this is one of the ops we can handle! + static const unsigned ADDTAB[] = { + X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, + X86::ADD8mr, X86::ADD16mr, X86::ADD32mr, + }; + static const unsigned SUBTAB[] = { + X86::SUB8mi, X86::SUB16mi, X86::SUB32mi, + X86::SUB8mr, X86::SUB16mr, X86::SUB32mr, + }; + static const unsigned ANDTAB[] = { + X86::AND8mi, X86::AND16mi, X86::AND32mi, + X86::AND8mr, X86::AND16mr, X86::AND32mr, + }; + static const unsigned ORTAB[] = { + X86::OR8mi, X86::OR16mi, X86::OR32mi, + X86::OR8mr, X86::OR16mr, X86::OR32mr, + }; + static const unsigned XORTAB[] = { + X86::XOR8mi, X86::XOR16mi, X86::XOR32mi, + X86::XOR8mr, X86::XOR16mr, X86::XOR32mr, + }; + static const unsigned SHLTAB[] = { + X86::SHL8mi, X86::SHL16mi, X86::SHL32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + static const unsigned SARTAB[] = { + X86::SAR8mi, X86::SAR16mi, X86::SAR32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + static const unsigned SHRTAB[] = { + X86::SHR8mi, X86::SHR16mi, X86::SHR32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + + const unsigned *TabPtr = 0; + switch (StVal.getOpcode()) { + default: + std::cerr << "CANNOT [mem] op= val: "; + StVal.Val->dump(); std::cerr << "\n"; + case ISD::MUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::SREM: + case ISD::UREM: return false; + + case ISD::ADD: TabPtr = ADDTAB; break; + case ISD::SUB: TabPtr = SUBTAB; break; + case ISD::AND: TabPtr = ANDTAB; break; + case ISD:: OR: TabPtr = ORTAB; break; + case ISD::XOR: TabPtr = XORTAB; break; + case ISD::SHL: TabPtr = SHLTAB; break; + case ISD::SRA: TabPtr = SARTAB; break; + case ISD::SRL: TabPtr = SHRTAB; break; + } + + // Handle: [mem] op= CST + SDOperand Op0 = StVal.getOperand(0); + SDOperand Op1 = StVal.getOperand(1); + unsigned Opc; + if (ConstantSDNode *CN = dyn_cast(Op1)) { + switch (Op0.getValueType()) { // Use Op0's type because of shifts. + default: break; + case MVT::i1: + case MVT::i8: Opc = TabPtr[0]; break; + case MVT::i16: Opc = TabPtr[1]; break; + case MVT::i32: Opc = TabPtr[2]; break; + } + + if (Opc) { + X86AddressMode AM; + if (getRegPressure(TheLoad.getOperand(0)) > + getRegPressure(TheLoad.getOperand(1))) { + Select(TheLoad.getOperand(0)); + SelectAddress(TheLoad.getOperand(1), AM); + } else { + SelectAddress(TheLoad.getOperand(1), AM); + Select(TheLoad.getOperand(0)); + } + + addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); + return true; + } + } + + // If we have [mem] = V op [mem], try to turn it into: + // [mem] = [mem] op V. + if (Op1 == TheLoad && StVal.getOpcode() != ISD::SUB && + StVal.getOpcode() != ISD::SHL && StVal.getOpcode() != ISD::SRA && + StVal.getOpcode() != ISD::SRL) + std::swap(Op0, Op1); + + if (Op0 != TheLoad) return false; + + switch (Op0.getValueType()) { + default: return false; + case MVT::i1: + case MVT::i8: Opc = TabPtr[3]; break; + case MVT::i16: Opc = TabPtr[4]; break; + case MVT::i32: Opc = TabPtr[5]; break; + } + + Select(TheLoad.getOperand(0)); + X86AddressMode AM; + SelectAddress(TheLoad.getOperand(1), AM); + unsigned Reg = SelectExpr(Op1); + addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); + return true; +} + + void ISel::Select(SDOperand N) { unsigned Tmp1, Tmp2, Opc; @@ -2488,130 +2626,8 @@ } // Check to see if this is a load/op/store combination. - if (N.getOperand(1).Val->hasOneUse() && - N.getOperand(0).getOpcode() == ISD::LOAD && - N.getOperand(1).Val->getNumOperands() == 2 && - !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType())) { - SDOperand TheLoad = N.getOperand(0).getValue(0); - - // See if the stored value is a simple binary operator that uses the load - // as one of its operands. - SDOperand Op = N.getOperand(1); - - // Check to see if we are loading the same pointer that we're storing to. - if (TheLoad.getOperand(1) == N.getOperand(2) && - ((Op.getOperand(0) == TheLoad && - isFoldableLoad(TheLoad, Op.getOperand(1))) || - (Op.getOperand(1) == TheLoad && - isFoldableLoad(TheLoad, Op.getOperand(0))))) { - // Finally, check to see if this is one of the ops we can handle! - static const unsigned ADDTAB[] = { - X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, - X86::ADD8mr, X86::ADD16mr, X86::ADD32mr, - }; - static const unsigned SUBTAB[] = { - X86::SUB8mi, X86::SUB16mi, X86::SUB32mi, - X86::SUB8mr, X86::SUB16mr, X86::SUB32mr, - }; - static const unsigned ANDTAB[] = { - X86::AND8mi, X86::AND16mi, X86::AND32mi, - X86::AND8mr, X86::AND16mr, X86::AND32mr, - }; - static const unsigned ORTAB[] = { - X86::OR8mi, X86::OR16mi, X86::OR32mi, - X86::OR8mr, X86::OR16mr, X86::OR32mr, - }; - static const unsigned XORTAB[] = { - X86::XOR8mi, X86::XOR16mi, X86::XOR32mi, - X86::XOR8mr, X86::XOR16mr, X86::XOR32mr, - }; - static const unsigned SHLTAB[] = { - X86::SHL8mi, X86::SHL16mi, X86::SHL32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - static const unsigned SARTAB[] = { - X86::SAR8mi, X86::SAR16mi, X86::SAR32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - static const unsigned SHRTAB[] = { - X86::SHR8mi, X86::SHR16mi, X86::SHR32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - - const unsigned *TabPtr = 0; - switch (Op.getOpcode()) { - default: std::cerr << "CANNOT [mem] op= val: "; Op.Val->dump(); std::cerr << "\n"; break; - case ISD::MUL: - case ISD::SDIV: - case ISD::UDIV: - case ISD::SREM: - case ISD::UREM: break; - - case ISD::ADD: TabPtr = ADDTAB; break; - case ISD::SUB: TabPtr = SUBTAB; break; - case ISD::AND: TabPtr = ANDTAB; break; - case ISD:: OR: TabPtr = ORTAB; break; - case ISD::XOR: TabPtr = XORTAB; break; - case ISD::SHL: TabPtr = SHLTAB; break; - case ISD::SRA: TabPtr = SARTAB; break; - case ISD::SRL: TabPtr = SHRTAB; break; - } - - if (TabPtr) { - // Handle: [mem] op= CST - SDOperand Op0 = Op.getOperand(0); - SDOperand Op1 = Op.getOperand(1); - if (ConstantSDNode *CN = dyn_cast(Op1)) { - switch (Op0.getValueType()) { // Use Op0's type because of shifts. - default: break; - case MVT::i1: - case MVT::i8: Opc = TabPtr[0]; break; - case MVT::i16: Opc = TabPtr[1]; break; - case MVT::i32: Opc = TabPtr[2]; break; - } - - if (Opc) { - if (getRegPressure(TheLoad.getOperand(0)) > - getRegPressure(TheLoad.getOperand(1))) { - Select(TheLoad.getOperand(0)); - SelectAddress(TheLoad.getOperand(1), AM); - } else { - SelectAddress(TheLoad.getOperand(1), AM); - Select(TheLoad.getOperand(0)); - } - - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); - return; - } - } - - // If we have [mem] = V op [mem], try to turn it into: - // [mem] = [mem] op V. - if (Op1 == TheLoad && Op.getOpcode() != ISD::SUB && - Op.getOpcode() != ISD::SHL && Op.getOpcode() != ISD::SRA && - Op.getOpcode() != ISD::SRL) - std::swap(Op0, Op1); - - if (Op0 == TheLoad) { - switch (Op0.getValueType()) { - default: break; - case MVT::i1: - case MVT::i8: Opc = TabPtr[3]; break; - case MVT::i16: Opc = TabPtr[4]; break; - case MVT::i32: Opc = TabPtr[5]; break; - } - - if (Opc) { - Select(TheLoad.getOperand(0)); - SelectAddress(TheLoad.getOperand(1), AM); - unsigned Reg = SelectExpr(Op1); - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); - return; - } - } - } - } - } + if (TryToFoldLoadOpStore(Node)) + return; switch (N.getOperand(1).getValueType()) { default: assert(0 && "Cannot store this type!"); From lattner at cs.uiuc.edu Mon Jan 17 13:43:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 13:43:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200501171943.j0HJhpYe029901@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.23 -> 1.24 --- Log message: Don't call SelectionDAG.getRoot() directly, go through a forwarding method. --- Diffs of the changes: (+30 -21) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.23 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.24 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.23 Mon Jan 17 11:55:19 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 17 13:43:36 2005 @@ -205,6 +205,12 @@ FuncInfo(funcinfo) { } + /// getRoot - Return the current virtual root of the Selection DAG. + /// + SDOperand getRoot() { + return DAG.getRoot(); + } + void visit(Instruction &I) { visit(I.getOpcode(), I); } void visit(unsigned Opcode, User &I) { @@ -359,7 +365,7 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) { if (I.getNumOperands() == 0) { - DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, DAG.getRoot())); + DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot())); return; } @@ -385,7 +391,7 @@ break; // No extension needed! } - DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, DAG.getRoot(), Op1)); + DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot(), Op1)); } void SelectionDAGLowering::visitBr(BranchInst &I) { @@ -402,7 +408,7 @@ if (I.isUnconditional()) { // If this is not a fall-through branch, emit the branch. if (Succ0MBB != NextBlock) - DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, DAG.getRoot(), + DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(), DAG.getBasicBlock(Succ0MBB))); } else { MachineBasicBlock *Succ1MBB = FuncInfo.MBBMap[I.getSuccessor(1)]; @@ -413,21 +419,21 @@ if (Succ1MBB == NextBlock) { // If the condition is false, fall through. This means we should branch // if the condition is true to Succ #0. - DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, DAG.getRoot(), + DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), Cond, DAG.getBasicBlock(Succ0MBB))); } else if (Succ0MBB == NextBlock) { // If the condition is true, fall through. This means we should branch if // the condition is false to Succ #1. Invert the condition first. SDOperand True = DAG.getConstant(1, Cond.getValueType()); Cond = DAG.getNode(ISD::XOR, Cond.getValueType(), Cond, True); - DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, DAG.getRoot(), + DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), Cond, DAG.getBasicBlock(Succ1MBB))); } else { // Neither edge is a fall through. If the comparison is true, jump to // Succ#0, otherwise branch unconditionally to succ #1. - DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, DAG.getRoot(), + DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), Cond, DAG.getBasicBlock(Succ0MBB))); - DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, DAG.getRoot(), + DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(), DAG.getBasicBlock(Succ1MBB))); } } @@ -572,7 +578,7 @@ } SDOperand DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, AllocSize.getValueType(), - DAG.getRoot(), AllocSize, + getRoot(), AllocSize, getIntPtrConstant(Align)); DAG.setRoot(setValue(&I, DSA).getValue(1)); @@ -584,7 +590,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { SDOperand Ptr = getValue(I.getOperand(0)); - SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), DAG.getRoot(), Ptr); + SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), getRoot(), Ptr); DAG.setRoot(setValue(&I, L).getValue(1)); } @@ -593,7 +599,7 @@ Value *SrcV = I.getOperand(0); SDOperand Src = getValue(SrcV); SDOperand Ptr = getValue(I.getOperand(1)); - DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), Src, Ptr)); + DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, getRoot(), Src, Ptr)); } void SelectionDAGLowering::visitCall(CallInst &I) { @@ -637,7 +643,7 @@ } std::pair Result = - TLI.LowerCallTo(DAG.getRoot(), I.getType(), Callee, Args, DAG); + TLI.LowerCallTo(getRoot(), I.getType(), Callee, Args, DAG); if (I.getType() != Type::VoidTy) setValue(&I, Result.first); DAG.setRoot(Result.second); @@ -659,7 +665,7 @@ Args.push_back(std::make_pair(Src, TLI.getTargetData().getIntPtrType())); std::pair Result = - TLI.LowerCallTo(DAG.getRoot(), I.getType(), + TLI.LowerCallTo(getRoot(), I.getType(), DAG.getExternalSymbol("malloc", IntPtr), Args, DAG); setValue(&I, Result.first); // Pointers always fit in registers @@ -672,7 +678,7 @@ TLI.getTargetData().getIntPtrType())); MVT::ValueType IntPtr = TLI.getPointerTy(); std::pair Result = - TLI.LowerCallTo(DAG.getRoot(), Type::VoidTy, + TLI.LowerCallTo(getRoot(), Type::VoidTy, DAG.getExternalSymbol("free", IntPtr), Args, DAG); DAG.setRoot(Result.second); } @@ -708,14 +714,14 @@ void SelectionDAGLowering::visitVAStart(CallInst &I) { - std::pair Result = TLI.LowerVAStart(DAG.getRoot(), DAG); + std::pair Result = TLI.LowerVAStart(getRoot(), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } void SelectionDAGLowering::visitVAArg(VAArgInst &I) { std::pair Result = - TLI.LowerVAArgNext(false, DAG.getRoot(), getValue(I.getOperand(0)), + TLI.LowerVAArgNext(false, getRoot(), getValue(I.getOperand(0)), I.getType(), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); @@ -723,19 +729,19 @@ void SelectionDAGLowering::visitVANext(VANextInst &I) { std::pair Result = - TLI.LowerVAArgNext(true, DAG.getRoot(), getValue(I.getOperand(0)), + TLI.LowerVAArgNext(true, getRoot(), getValue(I.getOperand(0)), I.getArgType(), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } void SelectionDAGLowering::visitVAEnd(CallInst &I) { - DAG.setRoot(TLI.LowerVAEnd(DAG.getRoot(), getValue(I.getOperand(1)), DAG)); + DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)), DAG)); } void SelectionDAGLowering::visitVACopy(CallInst &I) { std::pair Result = - TLI.LowerVACopy(DAG.getRoot(), getValue(I.getOperand(1)), DAG); + TLI.LowerVACopy(getRoot(), getValue(I.getOperand(1)), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } @@ -757,14 +763,14 @@ void SelectionDAGLowering::visitFrameReturnAddress(CallInst &I, bool isFrame) { unsigned Depth = (unsigned)cast(I.getOperand(1))->getValue(); std::pair Result = - TLI.LowerFrameReturnAddress(isFrame, DAG.getRoot(), Depth, DAG); + TLI.LowerFrameReturnAddress(isFrame, getRoot(), Depth, DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { std::vector Ops; - Ops.push_back(DAG.getRoot()); + Ops.push_back(getRoot()); Ops.push_back(getValue(I.getOperand(1))); Ops.push_back(getValue(I.getOperand(2))); Ops.push_back(getValue(I.getOperand(3))); @@ -811,7 +817,7 @@ Op = DAG.getNode(ISD::ZERO_EXTEND, TLI.getTypeToTransformTo(VT), Op); } - return DAG.getCopyToReg(DAG.getRoot(), Op, Reg); + return DAG.getCopyToReg(SDL.getRoot(), Op, Reg); } /// IsOnlyUsedInOneBasicBlock - If the specified argument is only used in a @@ -982,6 +988,9 @@ // Lower the terminator after the copies are emitted. SDL.visit(*LLVMBB->getTerminator()); + + // Make sure the root of the DAG is up-to-date. + DAG.setRoot(SDL.getRoot()); } void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, From lattner at cs.uiuc.edu Mon Jan 17 16:10:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 16:10:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501172210.j0HMAvc6032014@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.64 -> 1.65 --- Log message: Two changes: 1. Fold [mem] += (1|-1) into inc [mem]/dec [mem] to save some icache space. 2. Do not let token factor nodes prevent forming '[mem] op= val' folds. --- Diffs of the changes: (+74 -5) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.64 llvm/lib/Target/X86/X86ISelPattern.cpp:1.65 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.64 Mon Jan 17 13:25:26 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 16:10:42 2005 @@ -2242,18 +2242,51 @@ assert(Node->getOpcode() == ISD::STORE && "Can only do this for stores!"); SDOperand Chain = Node->getOperand(0); SDOperand StVal = Node->getOperand(1); + SDOperand StPtr = Node->getOperand(2); // The chain has to be a load, the stored value must be an integer binary // operation with one use. - if (Chain.getOpcode() != ISD::LOAD || !StVal.Val->hasOneUse() || - StVal.Val->getNumOperands() != 2 || + if (!StVal.Val->hasOneUse() || StVal.Val->getNumOperands() != 2 || MVT::isFloatingPoint(StVal.getValueType())) return false; - SDOperand TheLoad = Chain.getValue(0); + // Token chain must either be a factor node or the load to fold. + if (Chain.getOpcode() != ISD::LOAD && Chain.getOpcode() != ISD::TokenFactor) + return false; + + SDOperand TheLoad; + + // Check to see if there is a load from the same pointer that we're storing + // to in either operand of the binop. + if (StVal.getOperand(0).getOpcode() == ISD::LOAD && + StVal.getOperand(0).getOperand(1) == StPtr) + TheLoad = StVal.getOperand(0); + else if (StVal.getOperand(1).getOpcode() == ISD::LOAD && + StVal.getOperand(1).getOperand(1) == StPtr) + TheLoad = StVal.getOperand(1); + else + return false; // No matching load operand. + + // We can only fold the load if there are no intervening side-effecting + // operations. This means that the store uses the load as its token chain, or + // there are only token factor nodes in between the store and load. + if (Chain != TheLoad.getValue(1)) { + // Okay, the other option is that we have a store referring to (possibly + // nested) token factor nodes. For now, just try peeking through one level + // of token factors to see if this is the case. + bool ChainOk = false; + if (Chain.getOpcode() == ISD::TokenFactor) { + for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i) + if (Chain.getOperand(i) == TheLoad.getValue(1)) { + ChainOk = true; + break; + } + } + + if (!ChainOk) return false; + } - // Check to see if we are loading the same pointer that we're storing to. - if (TheLoad.getOperand(1) != Node->getOperand(2)) + if (TheLoad.getOperand(1) != StPtr) return false; // Make sure that one of the operands of the binop is the load, and that the @@ -2333,6 +2366,9 @@ } if (Opc) { + LoweredTokens.insert(TheLoad.getValue(1)); + Select(Chain); + X86AddressMode AM; if (getRegPressure(TheLoad.getOperand(0)) > getRegPressure(TheLoad.getOperand(1))) { @@ -2342,6 +2378,36 @@ SelectAddress(TheLoad.getOperand(1), AM); Select(TheLoad.getOperand(0)); } + + if (StVal.getOpcode() == ISD::ADD) { + if (CN->getValue() == 1) { + switch (Op0.getValueType()) { + default: break; + case MVT::i8: + addFullAddress(BuildMI(BB, X86::INC8m, 4), AM); + return true; + case MVT::i16: Opc = TabPtr[1]; + addFullAddress(BuildMI(BB, X86::INC16m, 4), AM); + return true; + case MVT::i32: Opc = TabPtr[2]; + addFullAddress(BuildMI(BB, X86::INC32m, 4), AM); + return true; + } + } else if (CN->getValue()+1 == 0) { // [X] += -1 -> DEC [X] + switch (Op0.getValueType()) { + default: break; + case MVT::i8: + addFullAddress(BuildMI(BB, X86::DEC8m, 4), AM); + return true; + case MVT::i16: Opc = TabPtr[1]; + addFullAddress(BuildMI(BB, X86::DEC16m, 4), AM); + return true; + case MVT::i32: Opc = TabPtr[2]; + addFullAddress(BuildMI(BB, X86::DEC32m, 4), AM); + return true; + } + } + } addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); return true; @@ -2364,6 +2430,9 @@ case MVT::i16: Opc = TabPtr[4]; break; case MVT::i32: Opc = TabPtr[5]; break; } + + LoweredTokens.insert(TheLoad.getValue(1)); + Select(Chain); Select(TheLoad.getOperand(0)); X86AddressMode AM; From lattner at cs.uiuc.edu Mon Jan 17 16:19:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 16:19:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200501172219.j0HMJeKc032069@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.24 -> 1.25 --- Log message: Non-volatile loads can be freely reordered against each other. This fixes X86/reg-pressure.ll again, and allows us to do nice things in other cases. For example, we now codegen this sort of thing: int %loadload(int *%X, int* %Y) { %Z = load int* %Y %Y = load int* %X ;; load between %Z and store %Q = add int %Z, 1 store int %Q, int* %Y ret int %Y } Into this: loadload: mov %EAX, DWORD PTR [%ESP + 4] mov %EAX, DWORD PTR [%EAX] mov %ECX, DWORD PTR [%ESP + 8] inc DWORD PTR [%ECX] ret where we weren't able to form the 'inc [mem]' before. This also lets the instruction selector emit loads in any order it wants to, which can be good for register pressure as well. --- Diffs of the changes: (+38 -4) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.24 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.25 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.24 Mon Jan 17 13:43:36 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 17 16:19:26 2005 @@ -187,6 +187,12 @@ std::map NodeMap; + /// PendingLoads - Loads are not emitted to the program immediately. We bunch + /// them up and then emit token factor nodes when possible. This allows us to + /// get simple disambiguation between loads without worrying about alias + /// analysis. + std::vector PendingLoads; + public: // TLI - This is information that describes the available target features we // need for lowering. This indicates when operations are unavailable, @@ -208,7 +214,21 @@ /// getRoot - Return the current virtual root of the Selection DAG. /// SDOperand getRoot() { - return DAG.getRoot(); + if (PendingLoads.empty()) + return DAG.getRoot(); + + if (PendingLoads.size() == 1) { + SDOperand Root = PendingLoads[0]; + DAG.setRoot(Root); + PendingLoads.clear(); + return Root; + } + + // Otherwise, we have to make a token factor node. + SDOperand Root = DAG.getNode(ISD::TokenFactor, MVT::Other, PendingLoads); + PendingLoads.clear(); + DAG.setRoot(Root); + return Root; } void visit(Instruction &I) { visit(I.getOpcode(), I); } @@ -590,8 +610,22 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { SDOperand Ptr = getValue(I.getOperand(0)); - SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), getRoot(), Ptr); - DAG.setRoot(setValue(&I, L).getValue(1)); + + SDOperand Root; + if (I.isVolatile()) + Root = getRoot(); + else { + // Do not serialize non-volatile loads against each other. + Root = DAG.getRoot(); + } + + SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr); + setValue(&I, L); + + if (I.isVolatile()) + DAG.setRoot(L.getValue(1)); + else + PendingLoads.push_back(L.getValue(1)); } @@ -982,7 +1016,7 @@ // Turn all of the unordered chains into one factored node. if (!UnorderedChains.empty()) { - UnorderedChains.push_back(DAG.getRoot()); + UnorderedChains.push_back(SDL.getRoot()); DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, UnorderedChains)); } From lattner at cs.uiuc.edu Mon Jan 17 16:56:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 16:56:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501172256.j0HMuOms002175@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.65 -> 1.66 --- Log message: Do not give token factor nodes outrageous weights --- Diffs of the changes: (+5 -2) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.65 llvm/lib/Target/X86/X86ISelPattern.cpp:1.66 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.65 Mon Jan 17 16:10:42 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 16:56:09 2005 @@ -453,8 +453,11 @@ ++NumExtraMaxRegUsers; } } - - Result = MaxRegUse+NumExtraMaxRegUsers; + + if (O.getOpcode() != ISD::TokenFactor) + Result = MaxRegUse+NumExtraMaxRegUsers; + else + Result = std::max(MaxRegUse-1, 1); } //std::cerr << " WEIGHT: " << Result << " "; N->dump(); std::cerr << "\n"; From alkis at cs.uiuc.edu Mon Jan 17 17:00:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 17:00:14 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Locals.h Locals.cpp Compiler.cpp Message-ID: <200501172300.RAA04515@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Locals.h updated: 1.1 -> 1.2 Locals.cpp updated: 1.5 -> 1.6 Compiler.cpp updated: 1.184 -> 1.185 --- Log message: Make each java local variable slot be a map of type->alloca's. This allows us to compile java bytecode correctly when a local used in a block when it was previously defined in two different predecessors. We now compile Lists1 and Lists2 correctly. --- Diffs of the changes: (+69 -36) Index: llvm-java/lib/Compiler/Locals.h diff -u llvm-java/lib/Compiler/Locals.h:1.1 llvm-java/lib/Compiler/Locals.h:1.2 --- llvm-java/lib/Compiler/Locals.h:1.1 Fri Oct 15 21:38:07 2004 +++ llvm-java/lib/Compiler/Locals.h Mon Jan 17 17:00:04 2005 @@ -16,12 +16,14 @@ #define LLVM_JAVA_LOCALS_H #include +#include #include namespace llvm { class AllocaInst; class BasicBlock; + class Type; class Value; } // namespace llvm @@ -29,7 +31,8 @@ namespace llvm { namespace Java { class Locals { - std::vector TheLocals; + typedef std::map SlotMap; + std::vector TheLocals; public: explicit Locals(unsigned maxLocals); @@ -42,7 +45,7 @@ /// @brief - Loads the value of the \c i'th local variable and /// appends any instructions to implement this to \c insertAtEnd /// BasicBlock - Value* load(unsigned i, BasicBlock* insertAtEnd); + Value* load(unsigned i, const Type* type, BasicBlock* insertAtEnd); }; } } // namespace llvm::Java Index: llvm-java/lib/Compiler/Locals.cpp diff -u llvm-java/lib/Compiler/Locals.cpp:1.5 llvm-java/lib/Compiler/Locals.cpp:1.6 --- llvm-java/lib/Compiler/Locals.cpp:1.5 Mon Jan 17 12:21:03 2005 +++ llvm-java/lib/Compiler/Locals.cpp Mon Jan 17 17:00:04 2005 @@ -37,29 +37,46 @@ value = new CastInst(value, ObjectBaseRefTy, "to-object-base", insertAtEnd); - if (!TheLocals[i] || - TheLocals[i]->getType()->getElementType() != value->getType()) { + // Values of jboolean, jbyte, jchar and jshort are extended to a + // jint when stored in a local slot. + else if (valueTy == Type::BoolTy || + valueTy == Type::SByteTy || + valueTy == Type::UShortTy || + valueTy == Type::ShortTy) + value = new CastInst(value, Type::IntTy, "int-extend", insertAtEnd); + + valueTy = value->getType(); + + SlotMap& slotMap = TheLocals[i]; + SlotMap::iterator it = slotMap.find(valueTy); + + if (it == slotMap.end()) { // Insert the alloca at the beginning of the entry block. BasicBlock* entry = &insertAtEnd->getParent()->getEntryBlock(); + AllocaInst* alloca; if (entry->empty()) - TheLocals[i] = new AllocaInst( + alloca = new AllocaInst( value->getType(), NULL, "local" + utostr(i), entry); else - TheLocals[i] = new AllocaInst( + alloca = new AllocaInst( value->getType(), NULL, "local" + utostr(i), &entry->front()); + it = slotMap.insert(it, std::make_pair(valueTy, alloca)); } - new StoreInst(value, TheLocals[i], insertAtEnd); + new StoreInst(value, it->second, insertAtEnd); } -llvm::Value* Locals::load(unsigned i, BasicBlock* insertAtEnd) +llvm::Value* Locals::load(unsigned i, const Type* type, BasicBlock* insertAtEnd) { - assert(TheLocals[i] && "Attempt to load a non initialized global!"); - return new LoadInst(TheLocals[i], "load", insertAtEnd); + SlotMap& slotMap = TheLocals[i]; + SlotMap::iterator it = slotMap.find(type); + + assert(it != slotMap.end() && "Attempt to load a non initialized global!"); + return new LoadInst(it->second, "load", insertAtEnd); } Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.184 llvm-java/lib/Compiler/Compiler.cpp:1.185 --- llvm-java/lib/Compiler/Compiler.cpp:1.184 Mon Jan 17 12:21:03 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Mon Jan 17 17:00:04 2005 @@ -77,8 +77,8 @@ ClassFile* cf_; std::auto_ptr bbBuilder_; std::list bbWorkList_; - typedef std::map > BBInfoMap; - BBInfoMap bbInfoMap_; + typedef std::map OpStackMap; + OpStackMap opStackMap_; BasicBlock* currentBB_; Locals* currentLocals_; OperandStack* currentOpStack_; @@ -1270,6 +1270,8 @@ classMethodDesc.find("java/lang/Integer") != 0 && classMethodDesc.find("java/lang/Long") != 0 && classMethodDesc.find("java/lang/Short") != 0 && + classMethodDesc.find("java/lang/StringBuffer") != 0 && + classMethodDesc.find("java/util/IndexOutOfBoundsException") != 0 && classMethodDesc.find("java/util/NoSuchElementException") != 0 && classMethodDesc.find("java/util/AbstractCollection") != 0 && classMethodDesc.find("java/util/AbstractList") != 0 && @@ -1284,7 +1286,7 @@ Java::CodeAttribute* codeAttr = method->getCodeAttribute(); - bbInfoMap_.clear(); + opStackMap_.clear(); bbBuilder_.reset(new BasicBlockBuilder(function, codeAttr)); // Put arguments into locals. @@ -1302,10 +1304,10 @@ // NOTE: We create an operand stack one size too big because we // push extra values on the stack to simplify code generation // (see implementation of ifne). - bbInfoMap_.insert( + currentLocals_ = &locals; + opStackMap_.insert( std::make_pair(&function->getEntryBlock(), - std::make_pair(locals, - OperandStack(codeAttr->getMaxStack()+1)))); + OperandStack(codeAttr->getMaxStack()+1))); // Insert the entry block to the work list. bbWorkList_.push_back(&function->getEntryBlock()); @@ -1315,13 +1317,11 @@ currentBB_ = bbWorkList_.front(); bbWorkList_.pop_front(); - BBInfoMap::iterator bbInfo = bbInfoMap_.find(currentBB_); - assert(bbInfo != bbInfoMap_.end() && - "Unknown entry operand stack and locals for basic block in " - "work list!"); + OpStackMap::iterator opStack = opStackMap_.find(currentBB_); + assert(opStack != opStackMap_.end() && + "Unknown operand stack for basic block in work list!"); - currentLocals_ = &bbInfo->second.first; - currentOpStack_ = &bbInfo->second.second; + currentOpStack_ = &opStack->second; unsigned start, end; tie(start, end) = bbBuilder_->getBytecodeIndices(currentBB_); @@ -1344,12 +1344,10 @@ SI = succ_begin(currentBB_), SE = succ_end(currentBB_); SI != SE; ++SI) { BasicBlock* Succ = *SI; - BBInfoMap::iterator bbSuccInfo = bbInfoMap_.lower_bound(Succ); - if (bbSuccInfo == bbInfoMap_.end() || bbSuccInfo->first != Succ) { - bbInfoMap_.insert(bbSuccInfo, - std::make_pair(Succ, - std::make_pair(*currentLocals_, - *currentOpStack_))); + OpStackMap::iterator succOpStack = opStackMap_.lower_bound(Succ); + if (succOpStack == opStackMap_.end() || succOpStack->first != Succ) { + opStackMap_.insert(succOpStack, + std::make_pair(Succ, *currentOpStack_)); bbWorkList_.push_back(Succ); } } @@ -1528,14 +1526,14 @@ do_ldc(index); } - void do_iload(unsigned index) { do_load_common(index); } - void do_lload(unsigned index) { do_load_common(index); } - void do_fload(unsigned index) { do_load_common(index); } - void do_dload(unsigned index) { do_load_common(index); } - void do_aload(unsigned index) { do_load_common(index); } + void do_iload(unsigned index) { do_load_common(index, Type::IntTy); } + void do_lload(unsigned index) { do_load_common(index, Type::LongTy); } + void do_fload(unsigned index) { do_load_common(index, Type::FloatTy); } + void do_dload(unsigned index) { do_load_common(index, Type::DoubleTy); } + void do_aload(unsigned index) { do_load_common(index, ObjectBaseRefTy); } - void do_load_common(unsigned index) { - Value* val = currentLocals_->load(index, currentBB_); + void do_load_common(unsigned index, Type* type) { + Value* val = currentLocals_->load(index, type, currentBB_); push(val); } @@ -1806,7 +1804,7 @@ } void do_iinc(unsigned index, int amount) { - Value* v = currentLocals_->load(index, currentBB_); + Value* v = currentLocals_->load(index, Type::IntTy, currentBB_); Value* a = ConstantSInt::get(Type::IntTy, amount); v = BinaryOperator::createAdd(v, a, TMP, currentBB_); currentLocals_->store(index, v, currentBB_); @@ -2019,6 +2017,21 @@ const FunctionType* funTy = cast(funPtrTy->getElementType()); + // Trace function calls. +// llvm::Constant* functionNameArray = ConstantArray::get(fun->getName()); +// GlobalVariable* functionName = +// new GlobalVariable(functionNameArray->getType(), +// true, +// GlobalVariable::ExternalLinkage, +// functionNameArray, +// fun->getName() + "name", +// &module_); +// Function* puts = +// module_.getOrInsertFunction("puts", +// Type::VoidTy, +// functionName->getType(), NULL); +// new CallInst(puts, std::vector(1, functionName), "", currentBB_); + if (funTy->getReturnType() == Type::VoidTy) new CallInst(fun, params, "", currentBB_); else { From lattner at cs.uiuc.edu Mon Jan 17 17:02:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 17:02:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501172302.j0HN2SMm002618@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.66 -> 1.67 --- Log message: Don't bother using max here. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.66 llvm/lib/Target/X86/X86ISelPattern.cpp:1.67 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.66 Mon Jan 17 16:56:09 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 17:02:13 2005 @@ -457,7 +457,7 @@ if (O.getOpcode() != ISD::TokenFactor) Result = MaxRegUse+NumExtraMaxRegUsers; else - Result = std::max(MaxRegUse-1, 1); + Result = MaxRegUse == 1 ? 0 : MaxRegUse-1; } //std::cerr << " WEIGHT: " << Result << " "; N->dump(); std::cerr << "\n"; From lattner at cs.uiuc.edu Mon Jan 17 17:16:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 17:16:16 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/regpressure.ll Message-ID: <200501172316.j0HNGGub002816@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: regpressure.ll updated: 1.1 -> 1.2 --- Log message: This is a carefully contrived testcase where the X86 ISel is emitting all loads before other ops, causing it to spill like mad. This occurs in 164.gzip:flush_block. --- Diffs of the changes: (+45 -0) Index: llvm/test/Regression/CodeGen/X86/regpressure.ll diff -u llvm/test/Regression/CodeGen/X86/regpressure.ll:1.1 llvm/test/Regression/CodeGen/X86/regpressure.ll:1.2 --- llvm/test/Regression/CodeGen/X86/regpressure.ll:1.1 Mon Jan 10 21:05:03 2005 +++ llvm/test/Regression/CodeGen/X86/regpressure.ll Mon Jan 17 17:16:01 2005 @@ -70,3 +70,48 @@ ret int %s9 } +;; adds should be the same as muls. +int %regpressure3(short* %P, bool %Cond, int* %Other) { + %A = load short* %P + %Bp = getelementptr short* %P, int 1 + %B = load short* %Bp + %Cp = getelementptr short* %P, int 2 + %C = load short* %Cp + %Dp = getelementptr short* %P, int 3 + %D = load short* %Dp + %Ep = getelementptr short* %P, int 4 + %E = load short* %Ep + %Fp = getelementptr short* %P, int 5 + %F = load short* %Fp + %Gp = getelementptr short* %P, int 6 + %G = load short* %Gp + %Hp = getelementptr short* %P, int 7 + %H = load short* %Hp + %Ip = getelementptr short* %P, int 8 + %I = load short* %Ip + %Jp = getelementptr short* %P, int 9 + %J = load short* %Jp + + ;; These casts prevent folding the loads into the adds. + %A = cast short %A to int + %B = cast short %B to int + %D = cast short %D to int + %C = cast short %C to int + %E = cast short %E to int + %F = cast short %F to int + %G = cast short %G to int + %H = cast short %H to int + %I = cast short %I to int + %J = cast short %J to int + %s1 = add int %A, %B + %s2 = add int %C, %s1 + %s3 = add int %D, %s2 + %s4 = add int %E, %s3 + %s5 = add int %F, %s4 + %s6 = add int %G, %s5 + %s7 = add int %H, %s6 + %s8 = add int %I, %s7 + %s9 = add int %J, %s8 + ret int %s9 +} + From lattner at cs.uiuc.edu Mon Jan 17 17:25:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 17:25:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrBuilder.h Message-ID: <200501172325.j0HNPwtj002835@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrBuilder.h updated: 1.15 -> 1.16 --- Log message: Fix indentation. --- Diffs of the changes: (+18 -19) Index: llvm/lib/Target/X86/X86InstrBuilder.h diff -u llvm/lib/Target/X86/X86InstrBuilder.h:1.15 llvm/lib/Target/X86/X86InstrBuilder.h:1.16 --- llvm/lib/Target/X86/X86InstrBuilder.h:1.15 Sat Jan 1 20:38:18 2005 +++ llvm/lib/Target/X86/X86InstrBuilder.h Mon Jan 17 17:25:45 2005 @@ -33,25 +33,24 @@ /// with BP or SP and Disp being offsetted accordingly. The displacement may /// also include the offset of a global value. struct X86AddressMode { - enum { - RegBase, - FrameIndexBase, - } BaseType; - - union { - unsigned Reg; - int FrameIndex; - } Base; - - unsigned Scale; - unsigned IndexReg; - unsigned Disp; - GlobalValue *GV; - - X86AddressMode() : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), - GV(NULL) { - Base.Reg = 0; - } + enum { + RegBase, + FrameIndexBase, + } BaseType; + + union { + unsigned Reg; + int FrameIndex; + } Base; + + unsigned Scale; + unsigned IndexReg; + unsigned Disp; + GlobalValue *GV; + + X86AddressMode() : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), GV(0) { + Base.Reg = 0; + } }; /// addDirectMem - This function is used to add a direct memory reference to the From lattner at cs.uiuc.edu Mon Jan 17 19:06:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 19:06:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501180106.j0I16eaK003564@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.67 -> 1.68 --- Log message: Fix a problem where probing for addressing modes caused expressions to be emitted too early. In particular, this fixes Regression/CodeGen/X86/regpressure.ll:regpressure3. This also improves the 2nd basic block in 164.gzip:flush_block, which went from .LBBflush_block_1: # loopentry.1.i movzx %EAX, WORD PTR [dyn_ltree + 20] movzx %ECX, WORD PTR [dyn_ltree + 16] mov DWORD PTR [%ESP + 32], %ECX movzx %ECX, WORD PTR [dyn_ltree + 12] movzx %EDX, WORD PTR [dyn_ltree + 8] movzx %EBX, WORD PTR [dyn_ltree + 4] mov DWORD PTR [%ESP + 36], %EBX movzx %EBX, WORD PTR [dyn_ltree] add DWORD PTR [%ESP + 36], %EBX add %EDX, DWORD PTR [%ESP + 36] add %ECX, %EDX add DWORD PTR [%ESP + 32], %ECX add %EAX, DWORD PTR [%ESP + 32] movzx %ECX, WORD PTR [dyn_ltree + 24] add %EAX, %ECX mov %ECX, 0 mov %EDX, %ECX to .LBBflush_block_1: # loopentry.1.i movzx %EAX, WORD PTR [dyn_ltree] movzx %ECX, WORD PTR [dyn_ltree + 4] add %ECX, %EAX movzx %EAX, WORD PTR [dyn_ltree + 8] add %EAX, %ECX movzx %ECX, WORD PTR [dyn_ltree + 12] add %ECX, %EAX movzx %EAX, WORD PTR [dyn_ltree + 16] add %EAX, %ECX movzx %ECX, WORD PTR [dyn_ltree + 20] add %ECX, %EAX movzx %EAX, WORD PTR [dyn_ltree + 24] add %ECX, %EAX mov %EAX, 0 mov %EDX, %EAX ... which results in less spilling in the function. This change alone speeds up 164.gzip from 37.23s to 36.24s on apoc. The default isel takes 37.31s. --- Diffs of the changes: (+110 -33) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.67 llvm/lib/Target/X86/X86ISelPattern.cpp:1.68 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.67 Mon Jan 17 17:02:13 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 19:06:26 2005 @@ -300,7 +300,31 @@ } - +namespace { + /// X86ISelAddressMode - This corresponds to X86AddressMode, but uses + /// SDOperand's instead of register numbers for the leaves of the matched + /// tree. + struct X86ISelAddressMode { + enum { + RegBase, + FrameIndexBase, + } BaseType; + + struct { // This is really a union, discriminated by BaseType! + SDOperand Reg; + int FrameIndex; + } Base; + + unsigned Scale; + SDOperand IndexReg; + unsigned Disp; + GlobalValue *GV; + + X86ISelAddressMode() + : BaseType(RegBase), Scale(1), IndexReg(), Disp(), GV(0) { + } + }; +} namespace { @@ -352,7 +376,10 @@ void EmitSelectCC(SDOperand Cond, MVT::ValueType SVT, unsigned RTrue, unsigned RFalse, unsigned RDest); unsigned SelectExpr(SDOperand N); - bool SelectAddress(SDOperand N, X86AddressMode &AM); + + X86AddressMode SelectAddrExprs(const X86ISelAddressMode &IAM); + bool MatchAddress(SDOperand N, X86ISelAddressMode &AM); + void SelectAddress(SDOperand N, X86AddressMode &AM); void Select(SDOperand N); }; } @@ -464,14 +491,62 @@ return Result; } -/// SelectAddress - Add the specified node to the specified addressing mode, -/// returning true if it cannot be done. -bool ISel::SelectAddress(SDOperand N, X86AddressMode &AM) { +X86AddressMode ISel::SelectAddrExprs(const X86ISelAddressMode &IAM) { + X86AddressMode Result; + + // If we need to emit two register operands, emit the one with the highest + // register pressure first. + if (IAM.BaseType == X86ISelAddressMode::RegBase && + IAM.Base.Reg.Val && IAM.IndexReg.Val) { + if (getRegPressure(IAM.Base.Reg) > getRegPressure(IAM.IndexReg)) { + Result.Base.Reg = SelectExpr(IAM.Base.Reg); + Result.IndexReg = SelectExpr(IAM.IndexReg); + } else { + Result.IndexReg = SelectExpr(IAM.IndexReg); + Result.Base.Reg = SelectExpr(IAM.Base.Reg); + } + } else if (IAM.BaseType == X86ISelAddressMode::RegBase && IAM.Base.Reg.Val) { + Result.Base.Reg = SelectExpr(IAM.Base.Reg); + } else if (IAM.IndexReg.Val) { + Result.IndexReg = SelectExpr(IAM.IndexReg); + } + + switch (IAM.BaseType) { + case X86ISelAddressMode::RegBase: + Result.BaseType = X86AddressMode::RegBase; + break; + case X86ISelAddressMode::FrameIndexBase: + Result.BaseType = X86AddressMode::FrameIndexBase; + Result.Base.FrameIndex = IAM.Base.FrameIndex; + break; + default: + assert(0 && "Unknown base type!"); + break; + } + Result.Scale = IAM.Scale; + Result.Disp = IAM.Disp; + Result.GV = IAM.GV; + return Result; +} + +/// SelectAddress - Pattern match the maximal addressing mode for this node and +/// emit all of the leaf registers. +void ISel::SelectAddress(SDOperand N, X86AddressMode &AM) { + X86ISelAddressMode IAM; + MatchAddress(N, IAM); + AM = SelectAddrExprs(IAM); +} + +/// MatchAddress - Add the specified node to the specified addressing mode, +/// returning true if it cannot be done. This just pattern matches for the +/// addressing mode, it does not cause any code to be emitted. For that, use +/// SelectAddress. +bool ISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) { switch (N.getOpcode()) { default: break; case ISD::FrameIndex: - if (AM.BaseType == X86AddressMode::RegBase && AM.Base.Reg == 0) { - AM.BaseType = X86AddressMode::FrameIndexBase; + if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { + AM.BaseType = X86ISelAddressMode::FrameIndexBase; AM.Base.FrameIndex = cast(N)->getIndex(); return false; } @@ -490,7 +565,7 @@ // if so. if (ExprMap.count(N)) break; - if (AM.IndexReg == 0 && AM.Scale == 1) + if (AM.IndexReg.Val == 0 && AM.Scale == 1) if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) { unsigned Val = CN->getValue(); if (Val == 1 || Val == 2 || Val == 3) { @@ -502,12 +577,12 @@ // constant into the disp field here. if (ShVal.Val->getOpcode() == ISD::ADD && !ExprMap.count(ShVal) && isa(ShVal.Val->getOperand(1))) { - AM.IndexReg = SelectExpr(ShVal.Val->getOperand(0)); + AM.IndexReg = ShVal.Val->getOperand(0); ConstantSDNode *AddVal = cast(ShVal.Val->getOperand(1)); AM.Disp += AddVal->getValue() << Val; } else { - AM.IndexReg = SelectExpr(ShVal); + AM.IndexReg = ShVal; } return false; } @@ -519,26 +594,26 @@ if (ExprMap.count(N)) break; // X*[3,5,9] -> X+X*[2,4,8] - if (AM.IndexReg == 0 && AM.BaseType == X86AddressMode::RegBase && - AM.Base.Reg == 0) + if (AM.IndexReg.Val == 0 && AM.BaseType == X86ISelAddressMode::RegBase && + AM.Base.Reg.Val == 0) if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) { AM.Scale = unsigned(CN->getValue())-1; SDOperand MulVal = N.Val->getOperand(0); - unsigned Reg; + SDOperand Reg; // Okay, we know that we have a scale by now. However, if the scaled // value is an add of something and a constant, we can fold the // constant into the disp field here. if (MulVal.Val->getOpcode() == ISD::ADD && !ExprMap.count(MulVal) && isa(MulVal.Val->getOperand(1))) { - Reg = SelectExpr(MulVal.Val->getOperand(0)); + Reg = MulVal.Val->getOperand(0); ConstantSDNode *AddVal = cast(MulVal.Val->getOperand(1)); AM.Disp += AddVal->getValue() * CN->getValue(); } else { - Reg = SelectExpr(N.Val->getOperand(0)); + Reg = N.Val->getOperand(0); } AM.IndexReg = AM.Base.Reg = Reg; @@ -551,13 +626,13 @@ // so. if (ExprMap.count(N)) break; - X86AddressMode Backup = AM; - if (!SelectAddress(N.Val->getOperand(0), AM) && - !SelectAddress(N.Val->getOperand(1), AM)) + X86ISelAddressMode Backup = AM; + if (!MatchAddress(N.Val->getOperand(0), AM) && + !MatchAddress(N.Val->getOperand(1), AM)) return false; AM = Backup; - if (!SelectAddress(N.Val->getOperand(1), AM) && - !SelectAddress(N.Val->getOperand(0), AM)) + if (!MatchAddress(N.Val->getOperand(1), AM) && + !MatchAddress(N.Val->getOperand(0), AM)) return false; AM = Backup; break; @@ -565,10 +640,10 @@ } // Is the base register already occupied? - if (AM.BaseType != X86AddressMode::RegBase || AM.Base.Reg) { + if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) { // If so, check to see if the scale index register is set. - if (AM.IndexReg == 0) { - AM.IndexReg = SelectExpr(N); + if (AM.IndexReg.Val == 0) { + AM.IndexReg = N; AM.Scale = 1; return false; } @@ -578,8 +653,8 @@ } // Default, generate it as a register. - AM.BaseType = X86AddressMode::RegBase; - AM.Base.Reg = SelectExpr(N); + AM.BaseType = X86ISelAddressMode::RegBase; + AM.Base.Reg = N; return false; } @@ -1056,6 +1131,7 @@ void ISel::EmitFoldedLoad(SDOperand Op, X86AddressMode &AM) { SDOperand Chain = Op.getOperand(0); SDOperand Address = Op.getOperand(1); + if (getRegPressure(Chain) > getRegPressure(Address)) { Select(Chain); SelectAddress(Address, AM); @@ -1503,15 +1579,16 @@ // See if we can codegen this as an LEA to fold operations together. if (N.getValueType() == MVT::i32) { - X86AddressMode AM; - if (!SelectAddress(Op0, AM) && !SelectAddress(Op1, AM)) { + X86ISelAddressMode AM; + if (!MatchAddress(Op0, AM) && !MatchAddress(Op1, AM)) { // If this is not just an add, emit the LEA. For a simple add (like // reg+reg or reg+imm), we just emit an add. It might be a good idea to // leave this as LEA, then peephole it to 'ADD' after two address elim // happens. - if (AM.Scale != 1 || AM.BaseType == X86AddressMode::FrameIndexBase || - AM.GV || (AM.Base.Reg && AM.IndexReg && AM.Disp)) { - addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), AM); + if (AM.Scale != 1 || AM.BaseType == X86ISelAddressMode::FrameIndexBase|| + AM.GV || (AM.Base.Reg.Val && AM.IndexReg.Val && AM.Disp)) { + X86AddressMode XAM = SelectAddrExprs(AM); + addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), XAM); return Result; } } @@ -1646,9 +1723,9 @@ case 3: case 5: case 9: - X86AddressMode AM; // Remove N from exprmap so SelectAddress doesn't get confused. ExprMap.erase(N); + X86AddressMode AM; SelectAddress(N, AM); // Restore it to the map. ExprMap[N] = Result; @@ -2436,12 +2513,12 @@ LoweredTokens.insert(TheLoad.getValue(1)); Select(Chain); - Select(TheLoad.getOperand(0)); + X86AddressMode AM; SelectAddress(TheLoad.getOperand(1), AM); unsigned Reg = SelectExpr(Op1); - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); + addFullAddress(BuildMI(BB, Opc, 4+1), AM).addReg(Reg); return true; } From lattner at cs.uiuc.edu Mon Jan 17 20:12:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 20:12:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501180212.j0I2CAl0004658@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.38 -> 1.39 --- Log message: Fix the completely broken FP constant folds for setcc's. --- Diffs of the changes: (+4 -4) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.38 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.39 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.38 Mon Jan 17 11:15:02 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Jan 17 20:11:55 2005 @@ -389,10 +389,10 @@ default: break; // FIXME: Implement the rest of these! case ISD::SETEQ: return getConstant(C1 == C2, MVT::i1); case ISD::SETNE: return getConstant(C1 != C2, MVT::i1); - case ISD::SETLT: return getConstant((int64_t)C1 < (int64_t)C2, MVT::i1); - case ISD::SETGT: return getConstant((int64_t)C1 < (int64_t)C2, MVT::i1); - case ISD::SETLE: return getConstant((int64_t)C1 < (int64_t)C2, MVT::i1); - case ISD::SETGE: return getConstant((int64_t)C1 < (int64_t)C2, MVT::i1); + case ISD::SETLT: return getConstant(C1 < C2, MVT::i1); + case ISD::SETGT: return getConstant(C1 > C2, MVT::i1); + case ISD::SETLE: return getConstant(C1 <= C2, MVT::i1); + case ISD::SETGE: return getConstant(C1 > C2, MVT::i1); } } else { // Ensure that the constant occurs on the RHS. From lattner at cs.uiuc.edu Mon Jan 17 20:26:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 20:26:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501180226.j0I2Q5gU005360@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.68 -> 1.69 --- Log message: Rely on the code in MatchAddress to do this work. Otherwise we fail to match (X+Y)+(Z << 1), because we match the X+Y first, consuming the index register, then there is no place to put the Z. --- Diffs of the changes: (+13 -11) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.68 llvm/lib/Target/X86/X86ISelPattern.cpp:1.69 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.68 Mon Jan 17 19:06:26 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 20:25:52 2005 @@ -1579,18 +1579,20 @@ // See if we can codegen this as an LEA to fold operations together. if (N.getValueType() == MVT::i32) { + ExprMap.erase(N); X86ISelAddressMode AM; - if (!MatchAddress(Op0, AM) && !MatchAddress(Op1, AM)) { - // If this is not just an add, emit the LEA. For a simple add (like - // reg+reg or reg+imm), we just emit an add. It might be a good idea to - // leave this as LEA, then peephole it to 'ADD' after two address elim - // happens. - if (AM.Scale != 1 || AM.BaseType == X86ISelAddressMode::FrameIndexBase|| - AM.GV || (AM.Base.Reg.Val && AM.IndexReg.Val && AM.Disp)) { - X86AddressMode XAM = SelectAddrExprs(AM); - addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), XAM); - return Result; - } + MatchAddress(N, AM); + ExprMap[N] = Result; + + // If this is not just an add, emit the LEA. For a simple add (like + // reg+reg or reg+imm), we just emit an add. It might be a good idea to + // leave this as LEA, then peephole it to 'ADD' after two address elim + // happens. + if (AM.Scale != 1 || AM.BaseType == X86ISelAddressMode::FrameIndexBase|| + AM.GV || (AM.Base.Reg.Val && AM.IndexReg.Val && AM.Disp)) { + X86AddressMode XAM = SelectAddrExprs(AM); + addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), XAM); + return Result; } } From alkis at cs.uiuc.edu Mon Jan 17 20:30:59 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 20:30:59 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java Message-ID: <200501180230.UAA07830@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Lists3.java added (r1.1) --- Log message: New test --- Diffs of the changes: (+24 -0) Index: llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java diff -c /dev/null llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java:1.1 *** /dev/null Mon Jan 17 20:30:59 2005 --- llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java Mon Jan 17 20:30:49 2005 *************** *** 0 **** --- 1,24 ---- + import java.util.*; + + public class Lists3 + { + public static void main(String[] args) { + LinkedList llist = new LinkedList(); + for (int i = 0; i < 10; ++i) { + llist.add(new Integer(i)); + } + + Test.println(llist.contains(new Integer(5))); + Test.println(llist.getFirst().equals(new Integer(0))); + Test.println(llist.getLast().equals(new Integer(9))); + Test.println(llist.indexOf(new Integer(3))); + Test.println(llist.remove(new Integer(3))); + Test.println(llist.indexOf(new Integer(3))); + Test.println(((Integer)llist.removeFirst()).intValue()); + Test.println(((Integer)llist.removeLast()).intValue()); + Test.println(llist.size()); + + for (Iterator i = llist.iterator(); i.hasNext(); ) + Test.println(((Integer)i.next()).intValue()); + } + } From alkis at cs.uiuc.edu Mon Jan 17 20:36:25 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 17 Jan 2005 20:36:25 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Equals.java Message-ID: <200501180236.UAA07885@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Equals.java added (r1.1) --- Log message: New test --- Diffs of the changes: (+20 -0) Index: llvm-java/test/Programs/SingleSource/UnitTests/Equals.java diff -c /dev/null llvm-java/test/Programs/SingleSource/UnitTests/Equals.java:1.1 *** /dev/null Mon Jan 17 20:36:23 2005 --- llvm-java/test/Programs/SingleSource/UnitTests/Equals.java Mon Jan 17 20:36:13 2005 *************** *** 0 **** --- 1,20 ---- + public class Equals + { + public static void main(String[] args) { + Integer i1 = new Integer(123); + Integer i2 = new Integer(234); + Integer i3 = new Integer(123); + + Test.println(i1.equals(i1)); + Test.println(i1 == i1); + + Test.println(i1.equals(i2)); + Test.println(i1 == i2); + + Test.println(i1.equals(i3)); + Test.println(i1 == i3); + + Test.println(i1.equals(new Integer(123))); + Test.println(i1 == new Integer(123)); + } + } From lattner at cs.uiuc.edu Mon Jan 17 20:51:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 20:51:56 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h SelectionDAGNodes.h Message-ID: <200501180251.j0I2puvo006353@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.14 -> 1.15 SelectionDAGNodes.h updated: 1.18 -> 1.19 --- Log message: Allow setcc operations to have non-bool types. --- Diffs of the changes: (+2 -2) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.14 llvm/include/llvm/CodeGen/SelectionDAG.h:1.15 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.14 Sat Jan 15 00:16:35 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Mon Jan 17 20:51:41 2005 @@ -131,7 +131,8 @@ return NN; } - SDOperand getSetCC(ISD::CondCode, SDOperand LHS, SDOperand RHS); + SDOperand getSetCC(ISD::CondCode, MVT::ValueType VT, + SDOperand LHS, SDOperand RHS); /// getNode - Gets or creates the specified node. /// Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.18 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.19 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.18 Sun Jan 16 20:24:59 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Mon Jan 17 20:51:41 2005 @@ -707,7 +707,6 @@ friend class SelectionDAG; SetCCSDNode(ISD::CondCode Cond, SDOperand LHS, SDOperand RHS) : SDNode(ISD::SETCC, LHS, RHS), Condition(Cond) { - setValueTypes(MVT::i1); } public: From lattner at cs.uiuc.edu Mon Jan 17 20:52:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 20:52:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200501180252.j0I2qGT3006367@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.38 -> 1.39 SelectionDAG.cpp updated: 1.39 -> 1.40 SelectionDAGISel.cpp updated: 1.25 -> 1.26 --- Log message: Allow setcc operations to have nonbool types. --- Diffs of the changes: (+46 -42) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.38 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.39 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.38 Sun Jan 16 13:46:48 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Jan 17 20:52:03 2005 @@ -565,7 +565,7 @@ Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) Result = DAG.getSetCC(cast(Node)->getCondition(), - Tmp1, Tmp2); + Node->getValueType(0), Tmp1, Tmp2); break; case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); // LHS @@ -605,7 +605,7 @@ } Result = DAG.getSetCC(cast(Node)->getCondition(), - Tmp1, Tmp2); + Node->getValueType(0), Tmp1, Tmp2); break; case Expand: SDOperand LHSLo, LHSHi, RHSLo, RHSHi; @@ -617,7 +617,8 @@ Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); - Result = DAG.getSetCC(cast(Node)->getCondition(), Tmp1, + Result = DAG.getSetCC(cast(Node)->getCondition(), + Node->getValueType(0), Tmp1, DAG.getConstant(0, Tmp1.getValueType())); break; default: @@ -641,11 +642,12 @@ // NOTE: on targets without efficient SELECT of bools, we can always use // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) - Tmp1 = DAG.getSetCC(LowCC, LHSLo, RHSLo); + Tmp1 = DAG.getSetCC(LowCC, Node->getValueType(0), LHSLo, RHSLo); Tmp2 = DAG.getSetCC(cast(Node)->getCondition(), - LHSHi, RHSHi); - Result = DAG.getSetCC(ISD::SETEQ, LHSHi, RHSHi); - Result = DAG.getNode(ISD::SELECT, MVT::i1, Result, Tmp1, Tmp2); + Node->getValueType(0), LHSHi, RHSHi); + Result = DAG.getSetCC(ISD::SETEQ, Node->getValueType(0), LHSHi, RHSHi); + Result = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), + Result, Tmp1, Tmp2); break; } } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.39 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.40 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.39 Mon Jan 17 20:11:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Jan 17 20:52:03 2005 @@ -341,15 +341,15 @@ return SDOperand(N, 0); } -SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, - SDOperand N2) { +SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, + SDOperand N1, SDOperand N2) { // These setcc operations always fold. switch (Cond) { default: break; case ISD::SETFALSE: - case ISD::SETFALSE2: return getConstant(0, MVT::i1); + case ISD::SETFALSE2: return getConstant(0, VT); case ISD::SETTRUE: - case ISD::SETTRUE2: return getConstant(1, MVT::i1); + case ISD::SETTRUE2: return getConstant(1, VT); } if (ConstantSDNode *N1C = dyn_cast(N1.Val)) @@ -364,16 +364,16 @@ switch (Cond) { default: assert(0 && "Unknown integer setcc!"); - case ISD::SETEQ: return getConstant(C1 == C2, MVT::i1); - case ISD::SETNE: return getConstant(C1 != C2, MVT::i1); - case ISD::SETULT: return getConstant(C1 < C2, MVT::i1); - case ISD::SETUGT: return getConstant(C1 > C2, MVT::i1); - case ISD::SETULE: return getConstant(C1 <= C2, MVT::i1); - case ISD::SETUGE: return getConstant(C1 >= C2, MVT::i1); - case ISD::SETLT: return getConstant((int64_t)C1 < (int64_t)C2, MVT::i1); - case ISD::SETGT: return getConstant((int64_t)C1 > (int64_t)C2, MVT::i1); - case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, MVT::i1); - case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, MVT::i1); + case ISD::SETEQ: return getConstant(C1 == C2, VT); + case ISD::SETNE: return getConstant(C1 != C2, VT); + case ISD::SETULT: return getConstant(C1 < C2, VT); + case ISD::SETUGT: return getConstant(C1 > C2, VT); + case ISD::SETULE: return getConstant(C1 <= C2, VT); + case ISD::SETUGE: return getConstant(C1 >= C2, VT); + case ISD::SETLT: return getConstant((int64_t)C1 < (int64_t)C2, VT); + case ISD::SETGT: return getConstant((int64_t)C1 > (int64_t)C2, VT); + case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, VT); + case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, VT); } } else { // Ensure that the constant occurs on the RHS. @@ -387,12 +387,12 @@ switch (Cond) { default: break; // FIXME: Implement the rest of these! - case ISD::SETEQ: return getConstant(C1 == C2, MVT::i1); - case ISD::SETNE: return getConstant(C1 != C2, MVT::i1); - case ISD::SETLT: return getConstant(C1 < C2, MVT::i1); - case ISD::SETGT: return getConstant(C1 > C2, MVT::i1); - case ISD::SETLE: return getConstant(C1 <= C2, MVT::i1); - case ISD::SETGE: return getConstant(C1 > C2, MVT::i1); + case ISD::SETEQ: return getConstant(C1 == C2, VT); + case ISD::SETNE: return getConstant(C1 != C2, VT); + case ISD::SETLT: return getConstant(C1 < C2, VT); + case ISD::SETGT: return getConstant(C1 > C2, VT); + case ISD::SETLE: return getConstant(C1 <= C2, VT); + case ISD::SETGE: return getConstant(C1 >= C2, VT); } } else { // Ensure that the constant occurs on the RHS. @@ -403,12 +403,12 @@ if (N1 == N2) { // We can always fold X == Y for integer setcc's. if (MVT::isInteger(N1.getValueType())) - return getConstant(ISD::isTrueWhenEqual(Cond), MVT::i1); + return getConstant(ISD::isTrueWhenEqual(Cond), VT); unsigned UOF = ISD::getUnorderedFlavor(Cond); if (UOF == 2) // FP operators that are undefined on NaNs. - return getConstant(ISD::isTrueWhenEqual(Cond), MVT::i1); + return getConstant(ISD::isTrueWhenEqual(Cond), VT); if (UOF == ISD::isTrueWhenEqual(Cond)) - return getConstant(UOF, MVT::i1); + return getConstant(UOF, VT); // Otherwise, we can't fold it. However, we can simplify it to SETUO/SETO // if it is not already. Cond = UOF == 0 ? ISD::SETUO : ISD::SETO; @@ -421,30 +421,30 @@ // Simplify (X+Y) == (X+Z) --> Y == Z if (N1.getOpcode() == N2.getOpcode()) { if (N1.getOperand(0) == N2.getOperand(0)) - return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1)); + return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); if (N1.getOperand(1) == N2.getOperand(1)) - return getSetCC(Cond, N1.getOperand(0), N2.getOperand(0)); + return getSetCC(Cond, VT, N1.getOperand(0), N2.getOperand(0)); if (isCommutativeBinOp(N1.getOpcode())) { // If X op Y == Y op X, try other combinations. if (N1.getOperand(0) == N2.getOperand(1)) - return getSetCC(Cond, N1.getOperand(1), N2.getOperand(0)); + return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(0)); if (N1.getOperand(1) == N2.getOperand(0)) - return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1)); + return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); } } // Simplify (X+Z) == X --> Z == 0 if (N1.getOperand(0) == N2) - return getSetCC(Cond, N1.getOperand(1), + return getSetCC(Cond, VT, N1.getOperand(1), getConstant(0, N1.getValueType())); if (N1.getOperand(1) == N2) { if (isCommutativeBinOp(N1.getOpcode())) - return getSetCC(Cond, N1.getOperand(0), + return getSetCC(Cond, VT, N1.getOperand(0), getConstant(0, N1.getValueType())); else { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 - return getSetCC(Cond, N1.getOperand(0), + return getSetCC(Cond, VT, N1.getOperand(0), getNode(ISD::SHL, N2.getValueType(), N2, getConstant(1, MVT::i8))); } @@ -455,10 +455,10 @@ N2.getOpcode() == ISD::XOR) { // Simplify X == (X+Z) --> Z == 0 if (N2.getOperand(0) == N1) - return getSetCC(Cond, N2.getOperand(1), + return getSetCC(Cond, VT, N2.getOperand(1), getConstant(0, N2.getValueType())); else if (N2.getOperand(1) == N1) - return getSetCC(Cond, N2.getOperand(0), + return getSetCC(Cond, VT, N2.getOperand(0), getConstant(0, N2.getValueType())); } } @@ -466,6 +466,7 @@ SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)]; if (N) return SDOperand(N, 0); N = new SetCCSDNode(Cond, N1, N2); + N->setValueTypes(VT); AllNodes.push_back(N); return SDOperand(N, 0); } @@ -668,6 +669,7 @@ // !(X op Y) -> (X !op Y) bool isInteger = MVT::isInteger(SetCC->getOperand(0).getValueType()); return getSetCC(ISD::getSetCCInverse(SetCC->getCondition(),isInteger), + SetCC->getValueType(0), SetCC->getOperand(0), SetCC->getOperand(1)); } else if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) { SDNode *Op = N1.Val; @@ -746,7 +748,7 @@ Result = ISD::getSetCCAndOperation(LHS->getCondition(), Op2, isInteger); if (Result != ISD::SETCC_INVALID) - return getSetCC(Result, LL, LR); + return getSetCC(Result, LHS->getValueType(0), LL, LR); } } break; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.25 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.26 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.25 Mon Jan 17 16:19:26 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 17 20:52:03 2005 @@ -472,7 +472,7 @@ ISD::CondCode Opcode = SignedOpcode; if (I.getOperand(0)->getType()->isUnsigned()) Opcode = UnsignedOpcode; - setValue(&I, DAG.getSetCC(Opcode, Op1, Op2)); + setValue(&I, DAG.getSetCC(Opcode, MVT::i1, Op1, Op2)); } void SelectionDAGLowering::visitSelect(User &I) { @@ -658,7 +658,7 @@ case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return; case Intrinsic::isunordered: - setValue(&I, DAG.getSetCC(ISD::SETUO, getValue(I.getOperand(1)), + setValue(&I, DAG.getSetCC(ISD::SETUO, MVT::i1, getValue(I.getOperand(1)), getValue(I.getOperand(2)))); return; } From lattner at cs.uiuc.edu Mon Jan 17 21:00:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 21:00:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501180300.j0I305PO006735@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.39 -> 1.40 --- Log message: Teach legalize to promote SetCC results. --- Diffs of the changes: (+8 -0) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.39 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.40 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.39 Mon Jan 17 20:52:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Jan 17 20:59:52 2005 @@ -917,6 +917,14 @@ Result = DAG.getNode(ISD::FP_EXTEND, NVT, Op); assert(isa(Result) && "Didn't constant fold fp_extend?"); break; + case ISD::SETCC: + assert(getTypeAction(TLI.getSetCCResultTy()) == Legal && + "SetCC type is not legal??"); + Result = DAG.getSetCC(cast(Node)->getCondition(), + TLI.getSetCCResultTy(), Node->getOperand(0), + Node->getOperand(1)); + Result = LegalizeOp(Result); + break; case ISD::TRUNCATE: switch (getTypeAction(Node->getOperand(0).getValueType())) { From lattner at cs.uiuc.edu Mon Jan 17 21:52:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 21:52:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501180352.j0I3qCE8007957@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.69 -> 1.70 --- Log message: * Eliminate the TokenSet and just use the ExprMap for both tokens and values. * Insert some really pedantic assertions that will notice when we emit the same loads more than one time, exposing bugs. This turns a miscompilation in bzip2 into a compile-fail. yaay. --- Diffs of the changes: (+13 -14) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.69 llvm/lib/Target/X86/X86ISelPattern.cpp:1.70 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.69 Mon Jan 17 20:25:52 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 21:51:59 2005 @@ -352,7 +352,6 @@ /// vreg the value is produced in, so we only emit one copy of each compiled /// tree. std::map ExprMap; - std::set LoweredTokens; public: ISel(TargetMachine &TM) : SelectionDAGISel(X86Lowering), X86Lowering(TM) { @@ -445,7 +444,6 @@ // Clear state used for selection. ExprMap.clear(); - LoweredTokens.clear(); RegPressureMap.clear(); } @@ -1107,8 +1105,7 @@ assert(Op.ResNo == 0 && "Not a use of the value of the load?"); if (ExprMap.count(Op.getValue(1))) return false; assert(!ExprMap.count(Op.getValue(0)) && "Value in map but not token chain?"); - assert(!LoweredTokens.count(Op.getValue(1)) && - "Token lowered but value not in map?"); + assert(!ExprMap.count(Op.getValue(1))&&"Token lowered but value not in map?"); // If there is not just one use of its value, we cannot fold. if (!Op.Val->hasNUsesOfValue(1, 0)) return false; @@ -1143,8 +1140,7 @@ // The chain for this load is now lowered. assert(ExprMap.count(SDOperand(Op.Val, 1)) == 0 && "Load emitted more than once?"); - ExprMap[SDOperand(Op.Val, 1)] = 1; - if (!LoweredTokens.insert(Op.getValue(1)).second) + if (!ExprMap.insert(std::make_pair(Op.getValue(1), 1)).second) assert(0 && "Load emitted more than once!"); } @@ -2091,9 +2087,10 @@ return Result; case ISD::LOAD: // Make sure we generate both values. - if (Result != 1) - ExprMap[N.getValue(1)] = 1; // Generate the token - else + if (Result != 1) { // Generate the token + if (!ExprMap.insert(std::make_pair(N.getValue(1), 1)).second) + assert(0 && "Load already emitted!?"); + } else Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); switch (Node->getValueType(0)) { @@ -2269,7 +2266,7 @@ case ISD::CALL: // The chain for this call is now lowered. - LoweredTokens.insert(N.getValue(Node->getNumValues()-1)); + ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1)); if (GlobalAddressSDNode *GASD = dyn_cast(N.getOperand(1))) { @@ -2448,7 +2445,8 @@ } if (Opc) { - LoweredTokens.insert(TheLoad.getValue(1)); + if (!ExprMap.insert(std::make_pair(TheLoad.getValue(1), 1)).second) + assert(0 && "Already emitted?"); Select(Chain); X86AddressMode AM; @@ -2513,7 +2511,8 @@ case MVT::i32: Opc = TabPtr[5]; break; } - LoweredTokens.insert(TheLoad.getValue(1)); + if (!ExprMap.insert(std::make_pair(TheLoad.getValue(1), 1)).second) + assert(0 && "Already emitted?"); Select(Chain); Select(TheLoad.getOperand(0)); @@ -2529,7 +2528,7 @@ unsigned Tmp1, Tmp2, Opc; // FIXME: Disable for our current expansion model! - if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second) + if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, 1)).second) return; // Already selected. SDNode *Node = N.Val; @@ -2675,7 +2674,7 @@ FoundIt: // Only handle unary operators right now. if (User->getNumOperands() == 1) { - LoweredTokens.erase(N); + ExprMap.erase(N); SelectExpr(SDOperand(User, 0)); return; } From lattner at cs.uiuc.edu Mon Jan 17 22:01:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 22:01:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501180401.j0I417lH009178@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.70 -> 1.71 --- Log message: Eliminate bad assertions. --- Diffs of the changes: (+2 -0) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.70 llvm/lib/Target/X86/X86ISelPattern.cpp:1.71 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.70 Mon Jan 17 21:51:59 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 22:00:54 2005 @@ -2679,6 +2679,7 @@ return; } } + ExprMap.erase(N); SelectExpr(N); return; @@ -2687,6 +2688,7 @@ case ISD::ZEXTLOAD: case ISD::CALL: case ISD::DYNAMIC_STACKALLOC: + ExprMap.erase(N); SelectExpr(N); return; From tbrethou at cs.uiuc.edu Mon Jan 17 22:15:58 2005 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Mon, 17 Jan 2005 22:15:58 -0600 (CST) Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp Message-ID: <200501180415.WAA23206@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/ModuloScheduling: ModuloScheduling.cpp updated: 1.39 -> 1.40 --- Log message: Minor changes. --- Diffs of the changes: (+22 -12) Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.39 llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.40 --- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.39 Thu Dec 2 23:25:22 2004 +++ llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp Mon Jan 17 22:15:41 2005 @@ -169,7 +169,7 @@ int RecMII = calculateRecMII(MSG, ResMII); //Our starting initiation interval is the maximum of RecMII and ResMII - II = std::max(RecMII, ResMII); + /*II = std::max(RecMII, ResMII); //Print out II, RecMII, and ResMII DEBUG(std::cerr << "II starts out as " << II << " ( RecMII=" << RecMII << " and ResMII=" << ResMII << ")\n"); @@ -227,7 +227,7 @@ } else DEBUG(std::cerr << "Max stage is 0, so no change in loop or reached cap\n"); - + */ //Clear out our maps for the next basic block that is processed nodeToAttributesMap.clear(); partialOrder.clear(); @@ -681,6 +681,8 @@ void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node, std::vector &visitedNodes, int II) { + if(node) + DEBUG(std::cerr << *(node->getInst()) << "\n"); if(std::find(visitedNodes.begin(), visitedNodes.end(), node) != visitedNodes.end()) { std::vector recurrence; @@ -741,10 +743,13 @@ return; } + unsigned count = 0; for(MSchedGraphNode::succ_iterator I = node->succ_begin(), E = node->succ_end(); I != E; ++I) { visitedNodes.push_back(node); + //if(!edgesToIgnore.count(std::make_pair(node, count))) findAllReccurrences(*I, visitedNodes, II); visitedNodes.pop_back(); + count++; } } @@ -1178,24 +1183,24 @@ for(std::vector::iterator schedNode = nodesByCycle->second.begin(), SNE = nodesByCycle->second.end(); schedNode != SNE; ++schedNode) { if((*I)->isPredecessor(*schedNode)) { - if(!ignoreEdge(*schedNode, *I)) { + //if(!ignoreEdge(*schedNode, *I)) { int diff = (*I)->getInEdge(*schedNode).getIteDiff(); int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II; DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n"); DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n"); EarlyStart = std::max(EarlyStart, ES_Temp); hasPred = true; - } + //} } if((*I)->isSuccessor(*schedNode)) { - if(!ignoreEdge(*I,*schedNode)) { + //if(!ignoreEdge(*I,*schedNode)) { int diff = (*schedNode)->getInEdge(*I).getIteDiff(); int LS_Temp = nodesByCycle->first - (*I)->getLatency() + diff * II; DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n"); DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n"); LateStart = std::min(LateStart, LS_Temp); hasSucc = true; - } + //} } } } @@ -1209,19 +1214,19 @@ branchLS = 0; } else { - EarlyStart = branchES; - LateStart = branchLS; + EarlyStart = branchLS; + LateStart = branchES; assert( (EarlyStart >= 0) && (LateStart >=0) && "EarlyStart and LateStart must be greater then 0"); --branchES; } - hasPred = 1; + hasPred = 0; hasSucc = 1; } - DEBUG(std::cerr << "Has Successors: " << hasSucc << ", Has Pred: " << hasPred << "\n"); DEBUG(std::cerr << "EarlyStart: " << EarlyStart << ", LateStart: " << LateStart << "\n"); + //Check if the node has no pred or successors and set Early Start to its ASAP if(!hasSucc && !hasPred) EarlyStart = nodeToAttributesMap.find(*I)->second.ASAP; @@ -1232,8 +1237,12 @@ success = scheduleNode(*I, EarlyStart, (EarlyStart + II -1)); else if(!hasPred && hasSucc) success = scheduleNode(*I, LateStart, (LateStart - II +1)); - else if(hasPred && hasSucc) - success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1))); + else if(hasPred && hasSucc) { + if(EarlyStart > LateStart) + success = false; + else + success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1))); + } else success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1); @@ -1555,6 +1564,7 @@ const MachineInstr *inst = I->first->getInst(); MachineInstr *instClone = inst->clone(); branches.push_back(instClone); + continue; } //Clone instruction From lattner at cs.uiuc.edu Mon Jan 17 22:18:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 17 Jan 2005 22:18:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501180418.j0I4IlxH009806@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.71 -> 1.72 --- Log message: Do not emit loads multiple times, potentially in the wrong places. --- Diffs of the changes: (+2 -2) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.71 llvm/lib/Target/X86/X86ISelPattern.cpp:1.72 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.71 Mon Jan 17 22:00:54 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 22:18:32 2005 @@ -573,7 +573,7 @@ // Okay, we know that we have a scale by now. However, if the scaled // value is an add of something and a constant, we can fold the // constant into the disp field here. - if (ShVal.Val->getOpcode() == ISD::ADD && !ExprMap.count(ShVal) && + if (ShVal.Val->getOpcode() == ISD::ADD && ShVal.hasOneUse() && isa(ShVal.Val->getOperand(1))) { AM.IndexReg = ShVal.Val->getOperand(0); ConstantSDNode *AddVal = @@ -604,7 +604,7 @@ // Okay, we know that we have a scale by now. However, if the scaled // value is an add of something and a constant, we can fold the // constant into the disp field here. - if (MulVal.Val->getOpcode() == ISD::ADD && !ExprMap.count(MulVal) && + if (MulVal.Val->getOpcode() == ISD::ADD && MulVal.hasOneUse() && isa(MulVal.Val->getOperand(1))) { Reg = MulVal.Val->getOperand(0); ConstantSDNode *AddVal = From llvm at cs.uiuc.edu Mon Jan 17 23:30:54 2005 From: llvm at cs.uiuc.edu (LLVM) Date: Mon, 17 Jan 2005 23:30:54 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-bcanalyzer/ Message-ID: <200501180530.XAA09557@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-bcanalyzer: --- Log message: Directory /var/cvs/llvm/llvm/win32/llvm-bcanalyzer added to the repository --- Diffs of the changes: (+0 -0) From jeffc at jolt-lang.org Mon Jan 17 23:31:26 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 17 Jan 2005 23:31:26 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj Message-ID: <200501180531.XAA09576@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-bcanalyzer: llvm-bcanalyzer.vcproj added (r1.1) --- Log message: Add llvm-bcanalyzer project to Visual Studio --- Diffs of the changes: (+137 -0) Index: llvm/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj diff -c /dev/null llvm/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj:1.1 *** /dev/null Mon Jan 17 23:31:25 2005 --- llvm/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj Mon Jan 17 23:31:15 2005 *************** *** 0 **** --- 1,137 ---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From jeffc at jolt-lang.org Mon Jan 17 23:31:45 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 17 Jan 2005 23:31:45 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200501180531.XAA09588@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.17 -> 1.18 --- Log message: Add llvm-bcanalyzer project to Visual Studio --- Diffs of the changes: (+13 -0) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.17 llvm/win32/llvm.sln:1.18 --- llvm/win32/llvm.sln:1.17 Sun Jan 9 21:56:27 2005 +++ llvm/win32/llvm.sln Mon Jan 17 23:31:34 2005 @@ -175,6 +175,15 @@ {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-bcanalyzer", "llvm-bcanalyzer\llvm-bcanalyzer.vcproj", "{E0B1E329-BE3E-456D-B372-5F397BE42C84}" + ProjectSection(ProjectDependencies) = postProject + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -277,6 +286,10 @@ {006D8B41-C3C7-4448-85E1-AF8907E591E5}.Debug.Build.0 = Debug|Win32 {006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release.ActiveCfg = Release|Win32 {006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release.Build.0 = Release|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug.ActiveCfg = Debug|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug.Build.0 = Debug|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release.ActiveCfg = Release|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From llvm at cs.uiuc.edu Mon Jan 17 23:39:14 2005 From: llvm at cs.uiuc.edu (LLVM) Date: Mon, 17 Jan 2005 23:39:14 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-ld/ Message-ID: <200501180539.XAA09719@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-ld: --- Log message: Directory /var/cvs/llvm/llvm/win32/llvm-ld added to the repository --- Diffs of the changes: (+0 -0) From jeffc at jolt-lang.org Mon Jan 17 23:39:47 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 17 Jan 2005 23:39:47 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200501180539.XAA09739@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.18 -> 1.19 --- Log message: Add project llvm-ld to Visual Studio --- Diffs of the changes: (+17 -0) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.18 llvm/win32/llvm.sln:1.19 --- llvm/win32/llvm.sln:1.18 Mon Jan 17 23:31:34 2005 +++ llvm/win32/llvm.sln Mon Jan 17 23:39:37 2005 @@ -184,6 +184,19 @@ {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ld", "llvm-ld\llvm-ld.vcproj", "{64D8AA46-88DB-41F4-B837-053AE02406B8}" + ProjectSection(ProjectDependencies) = postProject + {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -290,6 +303,10 @@ {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug.Build.0 = Debug|Win32 {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release.ActiveCfg = Release|Win32 {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release.Build.0 = Release|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug.ActiveCfg = Debug|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug.Build.0 = Debug|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Release.ActiveCfg = Release|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From llvm at cs.uiuc.edu Mon Jan 17 23:43:44 2005 From: llvm at cs.uiuc.edu (LLVM) Date: Mon, 17 Jan 2005 23:43:44 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-nm/ Message-ID: <200501180543.XAA09797@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-nm: --- Log message: Directory /var/cvs/llvm/llvm/win32/llvm-nm added to the repository --- Diffs of the changes: (+0 -0) From jeffc at jolt-lang.org Mon Jan 17 23:44:36 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 17 Jan 2005 23:44:36 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200501180544.XAA09833@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.19 -> 1.20 --- Log message: Add project llvm-nm to Visual Studio --- Diffs of the changes: (+13 -0) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.19 llvm/win32/llvm.sln:1.20 --- llvm/win32/llvm.sln:1.19 Mon Jan 17 23:39:37 2005 +++ llvm/win32/llvm.sln Mon Jan 17 23:44:25 2005 @@ -197,6 +197,15 @@ {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-nm", "llvm-nm\llvm-nm.vcproj", "{5FF862CE-80A0-4B48-A80B-68AE325A0432}" + ProjectSection(ProjectDependencies) = postProject + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -307,6 +316,10 @@ {64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug.Build.0 = Debug|Win32 {64D8AA46-88DB-41F4-B837-053AE02406B8}.Release.ActiveCfg = Release|Win32 {64D8AA46-88DB-41F4-B837-053AE02406B8}.Release.Build.0 = Release|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug.ActiveCfg = Debug|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug.Build.0 = Debug|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release.ActiveCfg = Release|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From jeffc at jolt-lang.org Mon Jan 17 23:44:36 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 17 Jan 2005 23:44:36 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-nm/llvm-nm.vcproj Message-ID: <200501180544.XAA09837@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-nm: llvm-nm.vcproj added (r1.1) --- Log message: Add project llvm-nm to Visual Studio --- Diffs of the changes: (+137 -0) Index: llvm/win32/llvm-nm/llvm-nm.vcproj diff -c /dev/null llvm/win32/llvm-nm/llvm-nm.vcproj:1.1 *** /dev/null Mon Jan 17 23:44:35 2005 --- llvm/win32/llvm-nm/llvm-nm.vcproj Mon Jan 17 23:44:25 2005 *************** *** 0 **** --- 1,137 ---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From jeffc at jolt-lang.org Mon Jan 17 23:45:01 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 17 Jan 2005 23:45:01 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-ld/llvm-ld.vcproj Message-ID: <200501180545.XAA09865@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-ld: llvm-ld.vcproj added (r1.1) --- Log message: Add project llvm-ld to Visual Studio --- Diffs of the changes: (+140 -0) Index: llvm/win32/llvm-ld/llvm-ld.vcproj diff -c /dev/null llvm/win32/llvm-ld/llvm-ld.vcproj:1.1 *** /dev/null Mon Jan 17 23:45:00 2005 --- llvm/win32/llvm-ld/llvm-ld.vcproj Mon Jan 17 23:44:50 2005 *************** *** 0 **** --- 1,140 ---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From alkis at cs.uiuc.edu Tue Jan 18 06:06:42 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue, 18 Jan 2005 06:06:42 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Equals.java Message-ID: <200501181206.GAA28815@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Equals.java updated: 1.1 -> 1.2 --- Log message: Make test more interesting. --- Diffs of the changes: (+3 -3) Index: llvm-java/test/Programs/SingleSource/UnitTests/Equals.java diff -u llvm-java/test/Programs/SingleSource/UnitTests/Equals.java:1.1 llvm-java/test/Programs/SingleSource/UnitTests/Equals.java:1.2 --- llvm-java/test/Programs/SingleSource/UnitTests/Equals.java:1.1 Mon Jan 17 20:36:13 2005 +++ llvm-java/test/Programs/SingleSource/UnitTests/Equals.java Tue Jan 18 06:06:31 2005 @@ -1,9 +1,9 @@ public class Equals { public static void main(String[] args) { - Integer i1 = new Integer(123); - Integer i2 = new Integer(234); - Integer i3 = new Integer(123); + Object i1 = new Integer(123); + Object i2 = new Integer(123); + Object i3 = new Long(123); Test.println(i1.equals(i1)); Test.println(i1 == i1); From lattner at cs.uiuc.edu Tue Jan 18 11:35:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 11:35:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501181735.j0IHZhcG016831@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.72 -> 1.73 --- Log message: Fix 124.m88ksim. --- Diffs of the changes: (+3 -0) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.72 llvm/lib/Target/X86/X86ISelPattern.cpp:1.73 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.72 Mon Jan 17 22:18:32 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jan 18 11:35:28 2005 @@ -2511,6 +2511,9 @@ case MVT::i32: Opc = TabPtr[5]; break; } + // Table entry doesn't exist? + if (Opc == 0) return false; + if (!ExprMap.insert(std::make_pair(TheLoad.getValue(1), 1)).second) assert(0 && "Already emitted?"); Select(Chain); From lattner at cs.uiuc.edu Tue Jan 18 11:55:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 11:55:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200501181755.j0IHtAXH018727@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.40 -> 1.41 SelectionDAGISel.cpp updated: 1.26 -> 1.27 --- Log message: Teach legalize to promote copy(from|to)reg, instead of making the isel pass do it. This results in better code on X86 for floats (because if strict precision is not required, we can elide some more expensive double -> float conversions like the old isel did), and allows other targets to emit CopyFromRegs that are not legal for arguments. --- Diffs of the changes: (+13 -26) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.40 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.41 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.40 Mon Jan 17 20:59:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 18 11:54:55 2005 @@ -380,7 +380,11 @@ if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) Result = DAG.getCopyToReg(Tmp1, Tmp2, cast(Node)->getReg()); break; - case Expand: { + case Promote: + Tmp2 = PromoteOp(Node->getOperand(1)); + Result = DAG.getCopyToReg(Tmp1, Tmp2, cast(Node)->getReg()); + break; + case Expand: SDOperand Lo, Hi; ExpandOp(Node->getOperand(1), Lo, Hi); unsigned Reg = cast(Node)->getReg(); @@ -390,10 +394,6 @@ "Cannot expand multiple times yet (i64 -> i16)"); break; } - case Promote: - assert(0 && "CopyToReg should not require promotion!"); - abort(); - } break; case ISD::RET: @@ -917,6 +917,13 @@ Result = DAG.getNode(ISD::FP_EXTEND, NVT, Op); assert(isa(Result) && "Didn't constant fold fp_extend?"); break; + case ISD::CopyFromReg: + Result = DAG.getCopyFromReg(cast(Node)->getReg(), NVT, + Node->getOperand(0)); + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); + break; + case ISD::SETCC: assert(getTypeAction(TLI.getSetCCResultTy()) == Legal && "SetCC type is not legal??"); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.26 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.27 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.26 Mon Jan 17 20:52:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jan 18 11:54:55 2005 @@ -292,19 +292,7 @@ FuncInfo.ValueMap.find(V); assert(VMI != FuncInfo.ValueMap.end() && "Value not in map!"); - MVT::ValueType RegVT = VT; - if (TLI.getTypeAction(VT) == 1) // Must promote this value? - RegVT = TLI.getTypeToTransformTo(VT); - - N = DAG.getCopyFromReg(VMI->second, RegVT, DAG.getEntryNode()); - - if (RegVT != VT) - if (MVT::isFloatingPoint(VT)) - N = DAG.getNode(ISD::FP_ROUND, VT, N); - else - N = DAG.getNode(ISD::TRUNCATE, VT, N); - - return N; + return N = DAG.getCopyFromReg(VMI->second, VT, DAG.getEntryNode()); } const SDOperand &setValue(const Value *V, SDOperand NewN) { @@ -843,14 +831,6 @@ assert((Op.getOpcode() != ISD::CopyFromReg || cast(Op)->getReg() != Reg) && "Copy from a reg to the same reg!"); - MVT::ValueType VT = Op.getValueType(); - if (TLI.getTypeAction(VT) == 1) { // Must promote this value? - if (MVT::isFloatingPoint(VT)) - Op = DAG.getNode(ISD::FP_EXTEND, TLI.getTypeToTransformTo(VT), Op); - else - Op = DAG.getNode(ISD::ZERO_EXTEND, TLI.getTypeToTransformTo(VT), Op); - } - return DAG.getCopyToReg(SDL.getRoot(), Op, Reg); } From lattner at cs.uiuc.edu Tue Jan 18 13:26:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 13:26:33 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200501181926.j0IJQXfD021119@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.15 -> 1.16 --- Log message: Keep track of the returned value type as well. --- Diffs of the changes: (+2 -1) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.15 llvm/include/llvm/CodeGen/SelectionDAG.h:1.16 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.15 Mon Jan 17 20:51:41 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Tue Jan 18 13:26:18 2005 @@ -175,7 +175,8 @@ std::map >, SDNode *> BinaryOps; - std::map, ISD::CondCode>, + std::map, + std::pair >, SetCCSDNode*> SetCCs; std::map >, From lattner at cs.uiuc.edu Tue Jan 18 13:26:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 13:26:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501181926.j0IJQmlN021132@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.40 -> 1.41 --- Log message: Keep track of the retval type as well. --- Diffs of the changes: (+5 -2) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.40 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.41 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.40 Mon Jan 17 20:52:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Jan 18 13:26:36 2005 @@ -218,7 +218,9 @@ case ISD::SETCC: SetCCs.erase(std::make_pair(std::make_pair(N->getOperand(0), N->getOperand(1)), - cast(N)->getCondition())); + std::make_pair( + cast(N)->getCondition(), + N->getValueType(0)))); break; case ISD::TRUNCSTORE: case ISD::SIGN_EXTEND_INREG: @@ -463,7 +465,8 @@ } } - SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)]; + SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), + std::make_pair(Cond, VT))]; if (N) return SDOperand(N, 0); N = new SetCCSDNode(Cond, N1, N2); N->setValueTypes(VT); From lattner at cs.uiuc.edu Tue Jan 18 13:27:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 13:27:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501181927.j0IJRJ0A021143@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.41 -> 1.42 --- Log message: Fix some fixmes (promoting bools for select and brcond), fix promotion of zero and sign extends. --- Diffs of the changes: (+43 -8) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.41 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.42 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.41 Tue Jan 18 11:54:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 18 13:27:06 2005 @@ -320,8 +320,16 @@ case ISD::BRCOND: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. - // FIXME: booleans might not be legal! - Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition. + + switch (getTypeAction(Node->getOperand(1).getValueType())) { + case Expand: assert(0 && "It's impossible to expand bools"); + case Legal: + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition. + break; + case Promote: + Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the condition. + break; + } // Basic block destination (Op#2) is always legal. if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2, @@ -524,8 +532,15 @@ } break; case ISD::SELECT: - // FIXME: BOOLS MAY REQUIRE PROMOTION! - Tmp1 = LegalizeOp(Node->getOperand(0)); // Cond + switch (getTypeAction(Node->getOperand(0).getValueType())) { + case Expand: assert(0 && "It's impossible to expand bools"); + case Legal: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition. + break; + case Promote: + Tmp1 = PromoteOp(Node->getOperand(0)); // Promote the condition. + break; + } Tmp2 = LegalizeOp(Node->getOperand(1)); // TrueVal Tmp3 = LegalizeOp(Node->getOperand(2)); // FalseVal @@ -770,11 +785,15 @@ switch (Node->getOpcode()) { case ISD::ZERO_EXTEND: Result = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::ZERO_EXTEND_INREG, Result.getValueType(), + // NOTE: Any extend would work here... + Result = DAG.getNode(ISD::ZERO_EXTEND, Op.getValueType(), Result); + Result = DAG.getNode(ISD::ZERO_EXTEND_INREG, Op.getValueType(), Result, Node->getOperand(0).getValueType()); break; case ISD::SIGN_EXTEND: Result = PromoteOp(Node->getOperand(0)); + // NOTE: Any extend would work here... + Result = DAG.getNode(ISD::SIGN_EXTEND, Op.getValueType(), Result); Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), Result, Node->getOperand(0).getValueType()); break; @@ -1101,7 +1120,15 @@ AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); break; case ISD::SELECT: - Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition + switch (getTypeAction(Node->getOperand(0).getValueType())) { + case Expand: assert(0 && "It's impossible to expand bools"); + case Legal: + Tmp1 = LegalizeOp(Node->getOperand(0));// Legalize the condition. + break; + case Promote: + Tmp1 = PromoteOp(Node->getOperand(0)); // Promote the condition. + break; + } Tmp2 = PromoteOp(Node->getOperand(1)); // Legalize the op0 Tmp3 = PromoteOp(Node->getOperand(2)); // Legalize the op1 Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2, Tmp3); @@ -1238,8 +1265,16 @@ } case ISD::SELECT: { SDOperand C, LL, LH, RL, RH; - // FIXME: BOOLS MAY REQUIRE PROMOTION! - C = LegalizeOp(Node->getOperand(0)); + + switch (getTypeAction(Node->getOperand(0).getValueType())) { + case Expand: assert(0 && "It's impossible to expand bools"); + case Legal: + C = LegalizeOp(Node->getOperand(0)); // Legalize the condition. + break; + case Promote: + C = PromoteOp(Node->getOperand(0)); // Promote the condition. + break; + } ExpandOp(Node->getOperand(1), LL, LH); ExpandOp(Node->getOperand(2), RL, RH); Lo = DAG.getNode(ISD::SELECT, NVT, C, LL, RL); From lattner at cs.uiuc.edu Tue Jan 18 13:47:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 13:47:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501181947.j0IJl9VC021851@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.73 -> 1.74 --- Log message: The selection dag code handles the promotions from F32 to F64 for us, so we don't need to even think about F32 in the X86 code anymore. --- Diffs of the changes: (+0 -12) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.73 llvm/lib/Target/X86/X86ISelPattern.cpp:1.74 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.73 Tue Jan 18 11:35:28 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jan 18 13:46:54 2005 @@ -53,7 +53,6 @@ // FIXME: Eliminate these two classes when legalize can handle promotions // well. /**/ addRegisterClass(MVT::i1, X86::R8RegisterClass); -/**/ //addRegisterClass(MVT::f32, X86::RFPRegisterClass); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); @@ -965,7 +964,6 @@ default: assert(0 && "Cannot select this type!"); case MVT::i16: Opc = CMOVTAB16[CondCode]; break; case MVT::i32: Opc = CMOVTAB32[CondCode]; break; - case MVT::f32: case MVT::f64: Opc = CMOVTABFP[CondCode]; break; } } @@ -981,7 +979,6 @@ default: assert(0 && "Cannot select this type!"); case MVT::i16: Opc = X86::CMOVE16rr; break; case MVT::i32: Opc = X86::CMOVE32rr; break; - case MVT::f32: case MVT::f64: Opc = X86::FCMOVE; break; } } else { @@ -1058,7 +1055,6 @@ case MVT::i8: Opc = X86::CMP8rr; break; case MVT::i16: Opc = X86::CMP16rr; break; case MVT::i32: Opc = X86::CMP32rr; break; - case MVT::f32: case MVT::f64: Opc = X86::FUCOMIr; break; } unsigned Tmp1, Tmp2; @@ -1634,7 +1630,6 @@ case MVT::i8: Opc = X86::ADD8rr; break; case MVT::i16: Opc = X86::ADD16rr; break; case MVT::i32: Opc = X86::ADD32rr; break; - case MVT::f32: case MVT::f64: Opc = X86::FpADD; break; } @@ -1951,8 +1946,6 @@ ClrOpcode = X86::MOV32ri; SExtOpcode = X86::CDQ; break; - case MVT::i64: assert(0 && "FIXME: implement i64 DIV/REM libcalls!"); - case MVT::f32: case MVT::f64: BuildMI(BB, X86::FpDIV, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; @@ -2099,7 +2092,6 @@ case MVT::i8: Opc = X86::MOV8rm; break; case MVT::i16: Opc = X86::MOV16rm; break; case MVT::i32: Opc = X86::MOV32rm; break; - case MVT::f32: Opc = X86::FLD32m; ContainsFPCode = true; break; case MVT::f64: Opc = X86::FLD64m; ContainsFPCode = true; break; } @@ -2303,7 +2295,6 @@ if (Node->getValueType(1) == MVT::i32) BuildMI(BB, X86::MOV32rr, 1, Result+1).addReg(X86::EDX); break; - case MVT::f32: case MVT::f64: // Floating-point return values live in %ST(0) ContainsFPCode = true; BuildMI(BB, X86::FpGETRESULT, 1, Result); @@ -2574,7 +2565,6 @@ case MVT::i8: Opc = X86::MOV8rr; break; case MVT::i16: Opc = X86::MOV16rr; break; case MVT::i32: Opc = X86::MOV32rr; break; - case MVT::f32: case MVT::f64: Opc = X86::FpMOV; ContainsFPCode = true; break; } BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1); @@ -2764,7 +2754,6 @@ case MVT::i8: Opc = X86::MOV8mi; break; case MVT::i16: Opc = X86::MOV16mi; break; case MVT::i32: Opc = X86::MOV32mi; break; - case MVT::f32: case MVT::f64: break; } if (Opc) { @@ -2790,7 +2779,6 @@ case MVT::i8: Opc = X86::MOV8mr; break; case MVT::i16: Opc = X86::MOV16mr; break; case MVT::i32: Opc = X86::MOV32mr; break; - case MVT::f32: Opc = X86::FST32m; break; case MVT::f64: Opc = X86::FST64m; break; } From lattner at cs.uiuc.edu Tue Jan 18 13:50:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 13:50:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501181950.j0IJoLfY022027@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.74 -> 1.75 --- Log message: Remove more dead code. --- Diffs of the changes: (+0 -17) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.74 llvm/lib/Target/X86/X86ISelPattern.cpp:1.75 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.74 Tue Jan 18 13:46:54 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jan 18 13:50:08 2005 @@ -1320,23 +1320,6 @@ BuildMI(BB, Opc, 1, Result).addReg(Tmp2); return Result; - case ISD::FP_ROUND: - // Truncate from double to float by storing to memory as float, - // then reading it back into a register. - - // Create as stack slot to use. - // FIXME: This should automatically be made by the Legalizer! - Tmp1 = TLI.getTargetData().getFloatAlignment(); - Tmp2 = BB->getParent()->getFrameInfo()->CreateStackObject(4, Tmp1); - - // Codegen the input. - Tmp1 = SelectExpr(N.getOperand(0)); - - // Emit the store, then the reload. - addFrameReference(BuildMI(BB, X86::FST32m, 5), Tmp2).addReg(Tmp1); - addFrameReference(BuildMI(BB, X86::FLD32m, 5, Result), Tmp2); - return Result; - case ISD::SINT_TO_FP: case ISD::UINT_TO_FP: { // FIXME: Most of this grunt work should be done by legalize! From lattner at cs.uiuc.edu Tue Jan 18 14:06:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 14:06:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501182006.j0IK6841022906@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.75 -> 1.76 --- Log message: Code to handle FP_EXTEND is dead now. X86 doesn't support any data types to FP_EXTEND from! --- Diffs of the changes: (+1 -4) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.75 llvm/lib/Target/X86/X86ISelPattern.cpp:1.76 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.75 Tue Jan 18 13:50:08 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jan 18 14:05:56 2005 @@ -1224,10 +1224,6 @@ BuildMI(BB, X86::MOV32ri, 1, Result).addExternalSymbol(Sym); return Result; } - case ISD::FP_EXTEND: - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, X86::FpMOV, 1, Result).addReg(Tmp1); - return Result; case ISD::ZERO_EXTEND: { int DestIs16 = N.getValueType() == MVT::i16; int SrcIs16 = N.getOperand(0).getValueType() == MVT::i16; @@ -1287,6 +1283,7 @@ } case ISD::TRUNCATE: // Fold TRUNCATE (LOAD P) into a smaller load from P. + // FIXME: This should be performed by the DAGCombiner. if (isFoldableLoad(N.getOperand(0), SDOperand())) { switch (N.getValueType()) { default: assert(0 && "Unknown truncate!"); From lattner at cs.uiuc.edu Tue Jan 18 15:58:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 15:58:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501182158.j0ILwEV0023636@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.42 -> 1.43 --- Log message: Zero is cheaper than sign extend. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.42 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.43 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.42 Tue Jan 18 13:27:06 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 18 15:57:59 2005 @@ -793,7 +793,7 @@ case ISD::SIGN_EXTEND: Result = PromoteOp(Node->getOperand(0)); // NOTE: Any extend would work here... - Result = DAG.getNode(ISD::SIGN_EXTEND, Op.getValueType(), Result); + Result = DAG.getNode(ISD::ZERO_EXTEND, Op.getValueType(), Result); Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), Result, Node->getOperand(0).getValueType()); break; From lattner at cs.uiuc.edu Tue Jan 18 21:36:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 21:36:18 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200501190336.j0J3aIuc025466@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.6 -> 1.7 --- Log message: Move all data members to the end of the class. Add a hook to find out how the target handles shift amounts that are out of range. Either they are undefined (the default), they mask the shift amount to the size of the register (X86, Alpha, etc), or they extend the shift (PPC). This defaults to undefined, which is conservatively correct. --- Diffs of the changes: (+65 -47) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.6 llvm/include/llvm/Target/TargetLowering.h:1.7 --- llvm/include/llvm/Target/TargetLowering.h:1.6 Sun Jan 16 17:59:30 2005 +++ llvm/include/llvm/Target/TargetLowering.h Tue Jan 18 21:36:03 2005 @@ -43,53 +43,6 @@ /// target-specific constructs to SelectionDAG operators. /// class TargetLowering { - TargetMachine &TM; - const TargetData &TD; - - /// IsLittleEndian - True if this is a little endian target. - /// - bool IsLittleEndian; - - /// PointerTy - The type to use for pointers, usually i32 or i64. - /// - MVT::ValueType PointerTy; - - /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever - /// PointerTy is. - MVT::ValueType ShiftAmountTy; - - /// SetCCResultTy - The type that SetCC operations use. This defaults to the - /// PointerTy. - MVT::ValueType SetCCResultTy; - - /// RegClassForVT - This indicates the default register class to use for - /// each ValueType the target supports natively. - TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; - unsigned char NumElementsForVT[MVT::LAST_VALUETYPE]; - - /// ValueTypeActions - This is a bitvector that contains two bits for each - /// value type, where the two bits correspond to the LegalizeAction enum. - /// This can be queried with "getTypeAction(VT)". - unsigned ValueTypeActions; - - /// TransformToType - For any value types we are promoting or expanding, this - /// contains the value type that we are changing to. For Expanded types, this - /// contains one step of the expand (e.g. i64 -> i32), even if there are - /// multiple steps required (e.g. i64 -> i16). For types natively supported - /// by the system, this holds the same type (e.g. i32 -> i32). - MVT::ValueType TransformToType[MVT::LAST_VALUETYPE]; - - /// OpActions - For each operation and each value type, keep a LegalizeAction - /// that indicates how instruction selection should deal with the operation. - /// Most operations are Legal (aka, supported natively by the target), but - /// operations that are not should be described. Note that operations on - /// non-legal value types are not described here. - unsigned OpActions[128]; - - std::vector LegalFPImmediates; - - std::vector > AvailableRegClasses; public: /// LegalizeAction - This enum indicates whether operations are valid for a /// target, and if not, what action should be used to make them valid. @@ -100,6 +53,12 @@ Custom, // Use the LowerOperation hook to implement custom lowering. }; + enum OutOfRangeShiftAmount { + Undefined, // Oversized shift amounts are undefined (default). + Mask, // Shift amounts are auto masked (anded) to value size. + Extend, // Oversized shift pulls in zeros or sign bits. + }; + TargetLowering(TargetMachine &TM); virtual ~TargetLowering(); @@ -110,6 +69,7 @@ MVT::ValueType getPointerTy() const { return PointerTy; } MVT::ValueType getShiftAmountTy() const { return ShiftAmountTy; } MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; } + OutOfRangeShiftAmount getShiftAmountFlavor() const {return ShiftAmtHandling; } /// getRegClassFor - Return the register class that should be used for the /// specified value type. This may only be called on legal types. @@ -223,6 +183,12 @@ /// of a setcc operation. This defaults to the pointer type. void setSetCCResultType(MVT::ValueType VT) { SetCCResultTy = VT; } + /// setShiftAmountFlavor - Describe how the target handles out of range shift + /// amounts. + void setShiftAmountFlavor(OutOfRangeShiftAmount OORSA) { + ShiftAmtHandling = OORSA; + } + /// addRegisterClass - Add the specified register class as an available /// regclass for the specified value type. This indicates the selector can /// handle values of that class natively. @@ -307,6 +273,58 @@ /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation of this aborts. virtual SDOperand LowerOperation(SDOperand Op); + + +private: + TargetMachine &TM; + const TargetData &TD; + + /// IsLittleEndian - True if this is a little endian target. + /// + bool IsLittleEndian; + + /// PointerTy - The type to use for pointers, usually i32 or i64. + /// + MVT::ValueType PointerTy; + + /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever + /// PointerTy is. + MVT::ValueType ShiftAmountTy; + + OutOfRangeShiftAmount ShiftAmtHandling; + + /// SetCCResultTy - The type that SetCC operations use. This defaults to the + /// PointerTy. + MVT::ValueType SetCCResultTy; + + /// RegClassForVT - This indicates the default register class to use for + /// each ValueType the target supports natively. + TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; + unsigned char NumElementsForVT[MVT::LAST_VALUETYPE]; + + /// ValueTypeActions - This is a bitvector that contains two bits for each + /// value type, where the two bits correspond to the LegalizeAction enum. + /// This can be queried with "getTypeAction(VT)". + unsigned ValueTypeActions; + + /// TransformToType - For any value types we are promoting or expanding, this + /// contains the value type that we are changing to. For Expanded types, this + /// contains one step of the expand (e.g. i64 -> i32), even if there are + /// multiple steps required (e.g. i64 -> i16). For types natively supported + /// by the system, this holds the same type (e.g. i32 -> i32). + MVT::ValueType TransformToType[MVT::LAST_VALUETYPE]; + + /// OpActions - For each operation and each value type, keep a LegalizeAction + /// that indicates how instruction selection should deal with the operation. + /// Most operations are Legal (aka, supported natively by the target), but + /// operations that are not should be described. Note that operations on + /// non-legal value types are not described here. + unsigned OpActions[128]; + + std::vector LegalFPImmediates; + + std::vector > AvailableRegClasses; }; } // end llvm namespace From lattner at cs.uiuc.edu Tue Jan 18 21:36:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 21:36:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200501190336.j0J3aRGR025477@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.6 -> 1.7 --- Log message: Add a hook to find out how the target handles shift amounts that are out of range. Either they are undefined (the default), they mask the shift amount to the size of the register (X86, Alpha, etc), or they extend the shift (PPC). This defaults to undefined, which is conservatively correct. --- Diffs of the changes: (+1 -0) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.6 llvm/lib/Target/TargetLowering.cpp:1.7 --- llvm/lib/Target/TargetLowering.cpp:1.6 Sun Jan 16 17:59:48 2005 +++ llvm/lib/Target/TargetLowering.cpp Tue Jan 18 21:36:14 2005 @@ -25,6 +25,7 @@ IsLittleEndian = TD.isLittleEndian(); ShiftAmountTy = SetCCResultTy = PointerTy = getValueType(TD.getIntPtrType()); + ShiftAmtHandling = Undefined; memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); } From lattner at cs.uiuc.edu Tue Jan 18 21:36:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 21:36:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501190336.j0J3agSC025487@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.76 -> 1.77 --- Log message: X86 shifts mask the amount. --- Diffs of the changes: (+1 -0) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.76 llvm/lib/Target/X86/X86ISelPattern.cpp:1.77 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.76 Tue Jan 18 14:05:56 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jan 18 21:36:30 2005 @@ -43,6 +43,7 @@ // X86 is wierd, it always uses i8 for shift amounts and setcc results. setShiftAmountType(MVT::i8); setSetCCResultType(MVT::i8); + setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 // Set up the register classes. addRegisterClass(MVT::i8, X86::R8RegisterClass); From lattner at cs.uiuc.edu Tue Jan 18 22:19:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 18 Jan 2005 22:19:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501190419.j0J4JtSN026409@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.43 -> 1.44 --- Log message: Implement a way of expanding shifts. This applies to targets that offer select operations or to shifts that are by a constant. This automatically implements (with no special code) all of the special cases for shift by 32, shift by < 32 and shift by > 32. --- Diffs of the changes: (+94 -3) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.43 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.44 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.43 Tue Jan 18 15:57:59 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 18 22:19:40 2005 @@ -119,6 +119,9 @@ void ExpandOp(SDOperand O, SDOperand &Lo, SDOperand &Hi); SDOperand PromoteOp(SDOperand O); + bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt, + SDOperand &Lo, SDOperand &Hi); + SDOperand getIntPtrConstant(uint64_t Val) { return DAG.getConstant(Val, TLI.getPointerTy()); } @@ -1157,6 +1160,71 @@ return Result; } +/// ExpandShift - Try to find a clever way to expand this shift operation out to +/// smaller elements. If we can't find a way that is more efficient than a +/// libcall on this target, return false. Otherwise, return true with the +/// low-parts expanded into Lo and Hi. +bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt, + SDOperand &Lo, SDOperand &Hi) { + assert((Opc == ISD::SHL || Opc == ISD::SRA || Opc == ISD::SRL) && + "This is not a shift!"); + MVT::ValueType NVT = TLI.getTypeToTransformTo(Op.getValueType()); + + // If we have an efficient select operation (or if the selects will all fold + // away), lower to some complex code, otherwise just emit the libcall. + if (TLI.getOperationAction(ISD::SELECT, NVT) != TargetLowering::Legal && + !isa(Amt)) + return false; + + SDOperand InL, InH; + ExpandOp(Op, InL, InH); + SDOperand ShAmt = LegalizeOp(Amt); + SDOperand OShAmt = ShAmt; // Unmasked shift amount. + MVT::ValueType ShTy = ShAmt.getValueType(); + + unsigned NVTBits = MVT::getSizeInBits(NVT); + SDOperand NAmt = DAG.getNode(ISD::SUB, ShTy, // NAmt = 32-ShAmt + DAG.getConstant(NVTBits, ShTy), ShAmt); + + if (TLI.getShiftAmountFlavor() != TargetLowering::Mask) { + ShAmt = DAG.getNode(ISD::AND, ShTy, ShAmt, // ShAmt &= 31 + DAG.getConstant(NVTBits-1, ShTy)); + NAmt = DAG.getNode(ISD::AND, ShTy, NAmt, // NAmt &= 31 + DAG.getConstant(NVTBits-1, ShTy)); + } + + if (Opc == ISD::SHL) { + SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << Amt) | (Lo >> NAmt) + DAG.getNode(ISD::SHL, NVT, InH, ShAmt), + DAG.getNode(ISD::SRL, NVT, InL, NAmt)); + SDOperand T2 = DAG.getNode(ISD::SHL, NVT, InL, ShAmt); // T2 = Lo << Amt + + SDOperand Cond = DAG.getSetCC(ISD::SETGE, TLI.getSetCCResultTy(), OShAmt, + DAG.getConstant(NVTBits, ShTy)); + Hi = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1); + Lo = DAG.getNode(ISD::SELECT, NVT, Cond, DAG.getConstant(0, NVT), T2); + } else { + SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << NAmt) | (Lo >> Amt) + DAG.getNode(ISD::SHL, NVT, InH, NAmt), + DAG.getNode(ISD::SRL, NVT, InL, ShAmt)); + bool isSign = Opc == ISD::SRA; + SDOperand T2 = DAG.getNode(Opc, NVT, InH, ShAmt); + + SDOperand HiPart; + if (isSign) + HiPart = DAG.getNode(Opc, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); + else + HiPart = DAG.getConstant(0, NVT); + SDOperand Cond = DAG.getSetCC(ISD::SETGE, TLI.getSetCCResultTy(), OShAmt, + DAG.getConstant(NVTBits, ShTy)); + Lo = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1); + Hi = DAG.getNode(ISD::SELECT, NVT, Cond, HiPart,T2); + } + return true; +} + + + /// ExpandOp - Expand the specified SDOperand into its two component pieces /// Lo&Hi. Note that the Op MUST be an expanded type. As a result of this, the /// LegalizeNodes map is filled in for any results that are not expanded, the @@ -1316,6 +1384,32 @@ LibCallName = "__fixunsdfdi"; break; + case ISD::SHL: + // If we can emit an efficient shift operation, do so now. + if (ExpandShift(ISD::SHL, Node->getOperand(0), Node->getOperand(1), + Lo, Hi)) + break; + // Otherwise, emit a libcall. + LibCallName = "__ashldi3"; + break; + + case ISD::SRA: + // If we can emit an efficient shift operation, do so now. + if (ExpandShift(ISD::SRA, Node->getOperand(0), Node->getOperand(1), + Lo, Hi)) + break; + // Otherwise, emit a libcall. + LibCallName = "__ashrdi3"; + break; + case ISD::SRL: + // If we can emit an efficient shift operation, do so now. + if (ExpandShift(ISD::SRL, Node->getOperand(0), Node->getOperand(1), + Lo, Hi)) + break; + // Otherwise, emit a libcall. + LibCallName = "__lshrdi3"; + break; + case ISD::ADD: LibCallName = "__adddi3"; break; case ISD::SUB: LibCallName = "__subdi3"; break; case ISD::MUL: LibCallName = "__muldi3"; break; @@ -1323,9 +1417,6 @@ case ISD::UDIV: LibCallName = "__udivdi3"; break; case ISD::SREM: LibCallName = "__moddi3"; break; case ISD::UREM: LibCallName = "__umoddi3"; break; - case ISD::SHL: LibCallName = "__ashldi3"; break; - case ISD::SRA: LibCallName = "__ashrdi3"; break; - case ISD::SRL: LibCallName = "__lshrdi3"; break; } // Int2FP -> __floatdisf/__floatdidf From jeffc at jolt-lang.org Tue Jan 18 23:08:42 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Tue, 18 Jan 2005 23:08:42 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/DataTypes.h.in Message-ID: <200501190508.XAA17249@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: DataTypes.h.in updated: 1.18 -> 1.19 --- Log message: Add missing data types for VC++ --- Diffs of the changes: (+6 -2) Index: llvm/include/llvm/Support/DataTypes.h.in diff -u llvm/include/llvm/Support/DataTypes.h.in:1.18 llvm/include/llvm/Support/DataTypes.h.in:1.19 --- llvm/include/llvm/Support/DataTypes.h.in:1.18 Thu Dec 16 12:47:17 2004 +++ llvm/include/llvm/Support/DataTypes.h.in Tue Jan 18 23:08:31 2005 @@ -69,9 +69,13 @@ #include typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -typedef signed int int32_t; +typedef signed int int32_t; typedef unsigned int uint32_t; -typedef signed int ssize_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed int ssize_t; #define INT8_MAX 127 #define INT8_MIN -128 #define UINT8_MAX 255 From lattner at cs.uiuc.edu Wed Jan 19 00:18:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 00:18:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501190618.j0J6Iwf9028694@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.77 -> 1.78 --- Log message: Codegen long >> 2 to this: foo: mov %EAX, DWORD PTR [%ESP + 4] mov %EDX, DWORD PTR [%ESP + 8] shrd %EAX, %EDX, 2 sar %EDX, 2 ret instead of this: test1: mov %ECX, DWORD PTR [%ESP + 4] shr %ECX, 2 mov %EDX, DWORD PTR [%ESP + 8] mov %EAX, %EDX shl %EAX, 30 or %EAX, %ECX sar %EDX, 2 ret and long << 2 to this: foo: mov %EAX, DWORD PTR [%ESP + 4] mov %ECX, DWORD PTR [%ESP + 8] *** mov %EDX, %EAX shrd %EDX, %ECX, 30 shl %EAX, 2 ret instead of this: foo: mov %EAX, DWORD PTR [%ESP + 4] mov %ECX, %EAX shr %ECX, 30 mov %EDX, DWORD PTR [%ESP + 8] shl %EDX, 2 or %EDX, %ECX shl %EAX, 2 ret The extra copy (marked ***) can be eliminated when I teach the code generator that shrd32rri8 is really commutative. --- Diffs of the changes: (+85 -1) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.77 llvm/lib/Target/X86/X86ISelPattern.cpp:1.78 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.77 Tue Jan 18 21:36:30 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jan 19 00:18:43 2005 @@ -370,6 +370,7 @@ void EmitFoldedLoad(SDOperand Op, X86AddressMode &AM); bool TryToFoldLoadOpStore(SDNode *Node); + bool EmitDoubleShift(SDOperand Op1, SDOperand Op2, unsigned DestReg); void EmitCMP(SDOperand LHS, SDOperand RHS, bool isOnlyUse); bool EmitBranchCC(MachineBasicBlock *Dest, SDOperand Chain, SDOperand Cond); void EmitSelectCC(SDOperand Cond, MVT::ValueType SVT, @@ -1141,6 +1142,84 @@ assert(0 && "Load emitted more than once!"); } +// EmitDoubleShift - Pattern match the expression (Op1|Op2), where we know that +// op1 and op2 are i32 values with one use each (the or). If we can form a SHLD +// or SHRD, emit the instruction (generating the value into DestReg) and return +// true. +bool ISel::EmitDoubleShift(SDOperand Op1, SDOperand Op2, unsigned DestReg) { + if (Op1.getOpcode() == ISD::SHL && Op2.getOpcode() == ISD::SRL) { + // good! + } else if (Op2.getOpcode() == ISD::SHL && Op1.getOpcode() == ISD::SRL) { + std::swap(Op1, Op2); // Op1 is the SHL now. + } else { + return false; // No match + } + + SDOperand ShlVal = Op1.getOperand(0); + SDOperand ShlAmt = Op1.getOperand(1); + SDOperand ShrVal = Op2.getOperand(0); + SDOperand ShrAmt = Op2.getOperand(1); + + // Find out if ShrAmt = 32-ShlAmt or ShlAmt = 32-ShrAmt. + if (ShlAmt.getOpcode() == ISD::SUB && ShlAmt.getOperand(1) == ShrAmt) + if (ConstantSDNode *SubCST = dyn_cast(ShlAmt.getOperand(0))) + if (SubCST->getValue() == 32) { + // (A >> ShrAmt) | (B << (32-ShrAmt)) ==> SHRD A, B, ShrAmt + unsigned AReg, BReg; + if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { + AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); + } else { + BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); + } + unsigned ShAmt = SelectExpr(ShrAmt); + BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); + BuildMI(BB, X86::SHRD32rrCL,2,DestReg).addReg(AReg).addReg(BReg); + return true; + } + + if (ShrAmt.getOpcode() == ISD::SUB && ShrAmt.getOperand(1) == ShlAmt) + if (ConstantSDNode *SubCST = dyn_cast(ShrAmt.getOperand(0))) + if (SubCST->getValue() == 32) { + // (A << ShlAmt) | (B >> (32-ShlAmt)) ==> SHLD A, B, ShrAmt + unsigned AReg, BReg; + if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { + AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); + } else { + BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); + } + unsigned ShAmt = SelectExpr(ShlAmt); + BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); + BuildMI(BB, X86::SHLD32rrCL,2,DestReg).addReg(AReg).addReg(BReg); + return true; + } + + if (ConstantSDNode *ShrCst = dyn_cast(ShrAmt)) + if (ConstantSDNode *ShlCst = dyn_cast(ShlAmt)) + if (ShrCst->getValue() < 32 && ShlCst->getValue() < 32) { + if (ShrCst->getValue() == 32-ShlCst->getValue()) { + // (A >> 5) | (B << 27) --> SHRD A, B, 5 + unsigned AReg, BReg; + if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { + AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); + } else { + BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); + } + BuildMI(BB, X86::SHRD32rri8, 3, DestReg).addReg(AReg).addReg(BReg) + .addImm(ShrCst->getValue()); + return true; + } + } + + + return false; +} + unsigned ISel::SelectExpr(SDOperand N) { unsigned Result; unsigned Tmp1, Tmp2, Tmp3; @@ -1658,7 +1737,12 @@ Op0 = Node->getOperand(0); Op1 = Node->getOperand(1); - if (Node->getOpcode() == ISD::SUB && MVT::isInteger(N.getValueType())) + if (Node->getOpcode() == ISD::OR && N.getValueType() == MVT::i32 && + Op0.hasOneUse() && Op1.hasOneUse()) // Match SHLD and SHRD. + if (EmitDoubleShift(Op0, Op1, Result)) + return Result; + + if (Node->getOpcode() == ISD::SUB) if (ConstantSDNode *CN = dyn_cast(N.getOperand(0))) if (CN->isNullValue()) { // 0 - N -> neg N switch (N.getValueType()) { From lattner at cs.uiuc.edu Wed Jan 19 00:30:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 00:30:48 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/shift-double.llx Message-ID: <200501190630.j0J6UmUn002407@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: shift-double.llx added (r1.1) --- Log message: Ensure that each these functions generates a sh[rl]d instruction. --- Diffs of the changes: (+22 -0) Index: llvm/test/Regression/CodeGen/X86/shift-double.llx diff -c /dev/null llvm/test/Regression/CodeGen/X86/shift-double.llx:1.1 *** /dev/null Wed Jan 19 00:30:46 2005 --- llvm/test/Regression/CodeGen/X86/shift-double.llx Wed Jan 19 00:30:36 2005 *************** *** 0 **** --- 1,22 ---- + ; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel -disable-pattern-isel=0 | grep sh[lr]d | wc -l | grep 4 + + long %test1(long %X, ubyte %C) { + %Y = shl long %X, ubyte %C + ret long %Y + } + long %test2(long %X, ubyte %C) { + %Y = shr long %X, ubyte %C + ret long %Y + } + ulong %test3(ulong %X, ubyte %C) { + %Y = shr ulong %X, ubyte %C + ret ulong %Y + } + + uint %test4(uint %A, uint %B, ubyte %C) { + %X = shl uint %A, ubyte %C + %Cv = sub ubyte 32, %C + %Y = shr uint %B, ubyte %Cv + %Z = or uint %Y, %X + ret uint %Z + } From lattner at cs.uiuc.edu Wed Jan 19 00:53:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 00:53:15 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200501190653.j0J6rF1o003949@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.74 -> 1.75 --- Log message: Add a new method, described in the comment. --- Diffs of the changes: (+12 -0) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.74 llvm/include/llvm/Target/TargetInstrInfo.h:1.75 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.74 Sat Jan 1 20:28:31 2005 +++ llvm/include/llvm/Target/TargetInstrInfo.h Wed Jan 19 00:53:02 2005 @@ -177,6 +177,18 @@ return 0; } + /// commuteInstruction - If a target has any instructions that are commutable, + /// but require converting to a different instruction or making non-trivial + /// changes to commute them, this method can overloaded to do this. The + /// default implementation of this method simply swaps the first two operands + /// of MI and returns it. + /// + /// If a target wants to make more aggressive changes, they can construct and + /// return a new machine instruction. If an instruction cannot commute, it + /// can also return null. + /// + virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + /// Insert a goto (unconditional branch) sequence to TMBB, at the /// end of MBB virtual void insertGoto(MachineBasicBlock& MBB, From lattner at cs.uiuc.edu Wed Jan 19 00:53:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 00:53:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetInstrInfo.cpp Message-ID: <200501190653.j0J6rnBp003959@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetInstrInfo.cpp updated: 1.13 -> 1.14 --- Log message: Finegrainify namespacification Add default impl of commuteInstruction Add notes about ugly V9 code. --- Diffs of the changes: (+20 -7) Index: llvm/lib/Target/TargetInstrInfo.cpp diff -u llvm/lib/Target/TargetInstrInfo.cpp:1.13 llvm/lib/Target/TargetInstrInfo.cpp:1.14 --- llvm/lib/Target/TargetInstrInfo.cpp:1.13 Tue Jul 27 16:43:38 2004 +++ llvm/lib/Target/TargetInstrInfo.cpp Wed Jan 19 00:53:34 2005 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// // +// This file implements the TargetInstrInfo class. // //===----------------------------------------------------------------------===// @@ -14,14 +15,15 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Constant.h" #include "llvm/DerivedTypes.h" +using namespace llvm; namespace llvm { - -// External object describing the machine instructions -// Initialized only when the TargetMachine class is created -// and reset when that class is destroyed. -// -const TargetInstrDescriptor* TargetInstrDescriptors = 0; + // External object describing the machine instructions Initialized only when + // the TargetMachine class is created and reset when that class is destroyed. + // + // FIXME: UGLY SPARCV9 HACK! + const TargetInstrDescriptor* TargetInstrDescriptors = 0; +} TargetInstrInfo::TargetInstrInfo(const TargetInstrDescriptor* Desc, unsigned numOpcodes) @@ -36,6 +38,7 @@ TargetInstrDescriptors = NULL; // reset global variable } +// FIXME: SPARCV9 SPECIFIC! bool TargetInstrInfo::constantFitsInImmedField(MachineOpCode opCode, int64_t intValue) const { // First, check if opCode has an immed field. @@ -56,4 +59,14 @@ return false; } -} // End llvm namespace +// commuteInstruction - The default implementation of this method just exchanges +// operand 1 and 2. +MachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr *MI) const { + 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(); + MI->SetMachineOperandReg(2, Reg1); + MI->SetMachineOperandReg(1, Reg2); + return MI; +} From lattner at cs.uiuc.edu Wed Jan 19 01:08:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 01:08:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/TwoAddressInstructionPass.cpp Message-ID: <200501190708.j0J78vLs004824@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: TwoAddressInstructionPass.cpp updated: 1.28 -> 1.29 --- Log message: Use the TargetInstrInfo::commuteInstruction method to commute instructions instead of doing it manually. --- Diffs of the changes: (+17 -6) Index: llvm/lib/CodeGen/TwoAddressInstructionPass.cpp diff -u llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.28 llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.29 --- llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.28 Sat Jan 1 20:34:12 2005 +++ llvm/lib/CodeGen/TwoAddressInstructionPass.cpp Wed Jan 19 01:08:42 2005 @@ -141,12 +141,23 @@ unsigned regC = mi->getOperand(2).getReg(); if (LV.KillsRegister(mi, regC)) { DEBUG(std::cerr << "2addr: COMMUTING : " << *mi); - mi->SetMachineOperandReg(2, regB); - mi->SetMachineOperandReg(1, regC); - DEBUG(std::cerr << "2addr: COMMUTED TO: " << *mi); - ++NumCommuted; - regB = regC; - goto InstructionRearranged; + MachineInstr *NewMI = TII.commuteInstruction(mi); + if (NewMI == 0) { + DEBUG(std::cerr << "2addr: COMMUTING FAILED!\n"); + } else { + DEBUG(std::cerr << "2addr: COMMUTED TO: " << *NewMI); + // If the instruction changed to commute it, update livevar. + if (NewMI != mi) { + LV.instructionChanged(mi, NewMI); // Update live variables + mbbi->insert(mi, NewMI); // Insert the new inst + mbbi->erase(mi); // Nuke the old inst. + mi = NewMI; + } + + ++NumCommuted; + regB = regC; + goto InstructionRearranged; + } } } // If this instruction is potentially convertible to a true From lattner at cs.uiuc.edu Wed Jan 19 01:11:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 01:11:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86InstrInfo.cpp X86InstrInfo.h Message-ID: <200501190711.j0J7BDRw004861@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.115 -> 1.116 X86InstrInfo.cpp updated: 1.34 -> 1.35 X86InstrInfo.h updated: 1.44 -> 1.45 --- Log message: Teach the code generator that shrd/shld is commutable if it has an immediate. This allows us to generate this: foo: mov %EAX, DWORD PTR [%ESP + 4] mov %EDX, DWORD PTR [%ESP + 8] shld %EDX, %EDX, 2 shl %EAX, 2 ret instead of this: foo: mov %EAX, DWORD PTR [%ESP + 4] mov %ECX, DWORD PTR [%ESP + 8] mov %EDX, %EAX shrd %EDX, %ECX, 30 shl %EAX, 2 ret Note the magically transmogrifying immediate. --- Diffs of the changes: (+29 -0) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.115 llvm/lib/Target/X86/X86InstrInfo.td:1.116 --- llvm/lib/Target/X86/X86InstrInfo.td:1.115 Mon Jan 10 16:09:33 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jan 19 01:11:01 2005 @@ -881,12 +881,15 @@ def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2), "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}">, Imp<[CL],[]>, TB; + +let isCommutable = 1 in { // These instructions commute to each other. def SHLD32rri8 : Ii8<0xA4, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3), "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}">, TB; def SHRD32rri8 : Ii8<0xAC, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3), "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}">, TB; +} let isTwoAddress = 0 in { def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2), Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.34 llvm/lib/Target/X86/X86InstrInfo.cpp:1.35 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.34 Sat Jan 1 22:18:17 2005 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Wed Jan 19 01:11:01 2005 @@ -121,6 +121,26 @@ return 0; } +/// commuteInstruction - We have a few instructions that must be hacked on to +/// commute them. +/// +MachineInstr *X86InstrInfo::commuteInstruction(MachineInstr *MI) const { + switch (MI->getOpcode()) { + case X86::SHRD32rri8: // A = SHRD32rri8 B, C, I -> A = SHLD32rri8 C, B, (32-I) + case X86::SHLD32rri8:{// A = SHLD32rri8 B, C, I -> A = SHRD32rri8 C, B, (32-I) + unsigned Amt = MI->getOperand(3).getImmedValue(); + unsigned A = MI->getOperand(0).getReg(); + unsigned B = MI->getOperand(1).getReg(); + unsigned C = MI->getOperand(2).getReg(); + unsigned Opc = X86::SHRD32rri8; + if (MI->getOpcode() == X86::SHRD32rri8) Opc = X86::SHLD32rri8; + return BuildMI(Opc, 3, A).addReg(B).addReg(C).addImm(32-Amt); + } + default: + return TargetInstrInfo::commuteInstruction(MI); + } +} + void X86InstrInfo::insertGoto(MachineBasicBlock& MBB, MachineBasicBlock& TMBB) const { Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.44 llvm/lib/Target/X86/X86InstrInfo.h:1.45 --- llvm/lib/Target/X86/X86InstrInfo.h:1.44 Sat Jan 1 20:37:07 2005 +++ llvm/lib/Target/X86/X86InstrInfo.h Wed Jan 19 01:11:01 2005 @@ -191,6 +191,12 @@ /// virtual MachineInstr *convertToThreeAddress(MachineInstr *TA) const; + /// commuteInstruction - We have a few instructions that must be hacked on to + /// commute them. + /// + virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + + /// Insert a goto (unconditional branch) sequence to TMBB, at the /// end of MBB virtual void insertGoto(MachineBasicBlock& MBB, From lattner at cs.uiuc.edu Wed Jan 19 01:31:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 01:31:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86InstrInfo.cpp X86RegisterInfo.cpp Message-ID: <200501190731.j0J7Vb9v005183@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.116 -> 1.117 X86InstrInfo.cpp updated: 1.35 -> 1.36 X86RegisterInfo.cpp updated: 1.97 -> 1.98 --- Log message: Improve coverage of the X86 instruction set by adding 16-bit shift doubles. --- Diffs of the changes: (+45 -3) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.116 llvm/lib/Target/X86/X86InstrInfo.td:1.117 --- llvm/lib/Target/X86/X86InstrInfo.td:1.116 Wed Jan 19 01:11:01 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jan 19 01:31:24 2005 @@ -881,6 +881,12 @@ def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2), "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}">, Imp<[CL],[]>, TB; +def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2), + "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}">, + Imp<[CL],[]>, TB, OpSize; +def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2), + "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}">, + Imp<[CL],[]>, TB, OpSize; let isCommutable = 1 in { // These instructions commute to each other. def SHLD32rri8 : Ii8<0xA4, MRMDestReg, @@ -889,6 +895,14 @@ def SHRD32rri8 : Ii8<0xAC, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3), "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}">, TB; +def SHLD16rri8 : Ii8<0xA4, MRMDestReg, + (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3), + "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}">, + TB, OpSize; +def SHRD16rri8 : Ii8<0xAC, MRMDestReg, + (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3), + "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}">, + TB, OpSize; } let isTwoAddress = 0 in { @@ -904,6 +918,21 @@ def SHRD32mri8 : Ii8<0xAC, MRMDestMem, (ops i32mem:$dst, R32:$src2, i8imm:$src3), "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}">, TB; + + def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2), + "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}">, + Imp<[CL],[]>, TB, OpSize; + def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2), + "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}">, + Imp<[CL],[]>, TB, OpSize; + def SHLD16mri8 : Ii8<0xA4, MRMDestMem, + (ops i16mem:$dst, R16:$src2, i8imm:$src3), + "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}">, + TB, OpSize; + def SHRD16mri8 : Ii8<0xAC, MRMDestMem, + (ops i16mem:$dst, R16:$src2, i8imm:$src3), + "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}">, + TB, OpSize; } Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.35 llvm/lib/Target/X86/X86InstrInfo.cpp:1.36 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.35 Wed Jan 19 01:11:01 2005 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Wed Jan 19 01:31:24 2005 @@ -126,15 +126,24 @@ /// MachineInstr *X86InstrInfo::commuteInstruction(MachineInstr *MI) const { switch (MI->getOpcode()) { + case X86::SHRD16rri8: // A = SHRD16rri8 B, C, I -> A = SHLD16rri8 C, B, (16-I) + case X86::SHLD16rri8: // A = SHLD16rri8 B, C, I -> A = SHRD16rri8 C, B, (16-I) case X86::SHRD32rri8: // A = SHRD32rri8 B, C, I -> A = SHLD32rri8 C, B, (32-I) case X86::SHLD32rri8:{// A = SHLD32rri8 B, C, I -> A = SHRD32rri8 C, B, (32-I) + unsigned Opc; + unsigned Size; + switch (MI->getOpcode()) { + default: assert(0 && "Unreachable!"); + case X86::SHRD16rri8: Size = 16; Opc = X86::SHLD16rri8; break; + case X86::SHLD16rri8: Size = 16; Opc = X86::SHRD16rri8; break; + case X86::SHRD32rri8: Size = 32; Opc = X86::SHLD32rri8; break; + case X86::SHLD32rri8: Size = 32; Opc = X86::SHRD32rri8; break; + } unsigned Amt = MI->getOperand(3).getImmedValue(); unsigned A = MI->getOperand(0).getReg(); unsigned B = MI->getOperand(1).getReg(); unsigned C = MI->getOperand(2).getReg(); - unsigned Opc = X86::SHRD32rri8; - if (MI->getOpcode() == X86::SHRD32rri8) Opc = X86::SHLD32rri8; - return BuildMI(Opc, 3, A).addReg(B).addReg(C).addImm(32-Amt); + return BuildMI(Opc, 3, A).addReg(B).addReg(C).addImm(Size-Amt); } default: return TargetInstrInfo::commuteInstruction(MI); Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.97 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.98 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.97 Mon Jan 10 16:09:33 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Jan 19 01:31:24 2005 @@ -225,6 +225,10 @@ case X86::SHLD32rri8:return MakeMRIInst(X86::SHLD32mri8,FrameIndex, MI); case X86::SHRD32rrCL:return MakeMRInst( X86::SHRD32mrCL,FrameIndex, MI); case X86::SHRD32rri8:return MakeMRIInst(X86::SHRD32mri8,FrameIndex, MI); + case X86::SHLD16rrCL:return MakeMRInst( X86::SHLD16mrCL,FrameIndex, MI); + case X86::SHLD16rri8:return MakeMRIInst(X86::SHLD16mri8,FrameIndex, MI); + case X86::SHRD16rrCL:return MakeMRInst( X86::SHRD16mrCL,FrameIndex, MI); + case X86::SHRD16rri8:return MakeMRIInst(X86::SHRD16mri8,FrameIndex, MI); case X86::SETBr: return MakeMInst( X86::SETBm, FrameIndex, MI); case X86::SETAEr: return MakeMInst( X86::SETAEm, FrameIndex, MI); case X86::SETEr: return MakeMInst( X86::SETEm, FrameIndex, MI); From lattner at cs.uiuc.edu Wed Jan 19 01:37:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 01:37:13 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/shift-double.llx Message-ID: <200501190737.j0J7bDrn005486@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: shift-double.llx updated: 1.1 -> 1.2 --- Log message: Add a test for 16-bit sh*d. --- Diffs of the changes: (+9 -1) Index: llvm/test/Regression/CodeGen/X86/shift-double.llx diff -u llvm/test/Regression/CodeGen/X86/shift-double.llx:1.1 llvm/test/Regression/CodeGen/X86/shift-double.llx:1.2 --- llvm/test/Regression/CodeGen/X86/shift-double.llx:1.1 Wed Jan 19 00:30:36 2005 +++ llvm/test/Regression/CodeGen/X86/shift-double.llx Wed Jan 19 01:37:01 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel -disable-pattern-isel=0 | grep sh[lr]d | wc -l | grep 4 +; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel -disable-pattern-isel=0 | grep sh[lr]d | wc -l | grep 5 long %test1(long %X, ubyte %C) { %Y = shl long %X, ubyte %C @@ -20,3 +20,11 @@ %Z = or uint %Y, %X ret uint %Z } + +ushort %test5(ushort %A, ushort %B, ubyte %C) { + %X = shl ushort %A, ubyte %C + %Cv = sub ubyte 16, %C + %Y = shr ushort %B, ubyte %Cv + %Z = or ushort %Y, %X + ret ushort %Z +} From lattner at cs.uiuc.edu Wed Jan 19 01:37:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 01:37:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501190737.j0J7bdSN005500@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.78 -> 1.79 --- Log message: Match 16-bit shld/shrd instructions as well, implementing shift-double.llx:test5 --- Diffs of the changes: (+20 -16) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.78 llvm/lib/Target/X86/X86ISelPattern.cpp:1.79 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.78 Wed Jan 19 00:18:43 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jan 19 01:37:26 2005 @@ -370,7 +370,7 @@ void EmitFoldedLoad(SDOperand Op, X86AddressMode &AM); bool TryToFoldLoadOpStore(SDNode *Node); - bool EmitDoubleShift(SDOperand Op1, SDOperand Op2, unsigned DestReg); + bool EmitOrOpOp(SDOperand Op1, SDOperand Op2, unsigned DestReg); void EmitCMP(SDOperand LHS, SDOperand RHS, bool isOnlyUse); bool EmitBranchCC(MachineBasicBlock *Dest, SDOperand Chain, SDOperand Cond); void EmitSelectCC(SDOperand Cond, MVT::ValueType SVT, @@ -1142,11 +1142,11 @@ assert(0 && "Load emitted more than once!"); } -// EmitDoubleShift - Pattern match the expression (Op1|Op2), where we know that -// op1 and op2 are i32 values with one use each (the or). If we can form a SHLD -// or SHRD, emit the instruction (generating the value into DestReg) and return -// true. -bool ISel::EmitDoubleShift(SDOperand Op1, SDOperand Op2, unsigned DestReg) { +// EmitOrOpOp - Pattern match the expression (Op1|Op2), where we know that op1 +// and op2 are i8/i16/i32 values with one use each (the or). If we can form a +// SHLD or SHRD, emit the instruction (generating the value into DestReg) and +// return true. +bool ISel::EmitOrOpOp(SDOperand Op1, SDOperand Op2, unsigned DestReg) { if (Op1.getOpcode() == ISD::SHL && Op2.getOpcode() == ISD::SRL) { // good! } else if (Op2.getOpcode() == ISD::SHL && Op1.getOpcode() == ISD::SRL) { @@ -1160,10 +1160,12 @@ SDOperand ShrVal = Op2.getOperand(0); SDOperand ShrAmt = Op2.getOperand(1); + unsigned RegSize = MVT::getSizeInBits(Op1.getValueType()); + // Find out if ShrAmt = 32-ShlAmt or ShlAmt = 32-ShrAmt. if (ShlAmt.getOpcode() == ISD::SUB && ShlAmt.getOperand(1) == ShrAmt) if (ConstantSDNode *SubCST = dyn_cast(ShlAmt.getOperand(0))) - if (SubCST->getValue() == 32) { + if (SubCST->getValue() == RegSize && RegSize != 8) { // (A >> ShrAmt) | (B << (32-ShrAmt)) ==> SHRD A, B, ShrAmt unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { @@ -1175,13 +1177,14 @@ } unsigned ShAmt = SelectExpr(ShrAmt); BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); - BuildMI(BB, X86::SHRD32rrCL,2,DestReg).addReg(AReg).addReg(BReg); + unsigned Opc = RegSize == 16 ? X86::SHRD16rrCL : X86::SHRD32rrCL; + BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg); return true; } if (ShrAmt.getOpcode() == ISD::SUB && ShrAmt.getOperand(1) == ShlAmt) if (ConstantSDNode *SubCST = dyn_cast(ShrAmt.getOperand(0))) - if (SubCST->getValue() == 32) { + if (SubCST->getValue() == RegSize && RegSize != 8) { // (A << ShlAmt) | (B >> (32-ShlAmt)) ==> SHLD A, B, ShrAmt unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { @@ -1193,14 +1196,15 @@ } unsigned ShAmt = SelectExpr(ShlAmt); BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); - BuildMI(BB, X86::SHLD32rrCL,2,DestReg).addReg(AReg).addReg(BReg); + unsigned Opc = RegSize == 16 ? X86::SHLD16rrCL : X86::SHLD32rrCL; + BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg); return true; } if (ConstantSDNode *ShrCst = dyn_cast(ShrAmt)) if (ConstantSDNode *ShlCst = dyn_cast(ShlAmt)) - if (ShrCst->getValue() < 32 && ShlCst->getValue() < 32) { - if (ShrCst->getValue() == 32-ShlCst->getValue()) { + if (ShrCst->getValue() < RegSize && ShlCst->getValue() < RegSize) { + if (ShrCst->getValue() == RegSize-ShlCst->getValue() && RegSize != 8) { // (A >> 5) | (B << 27) --> SHRD A, B, 5 unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { @@ -1210,7 +1214,8 @@ BReg = SelectExpr(ShlVal); AReg = SelectExpr(ShrVal); } - BuildMI(BB, X86::SHRD32rri8, 3, DestReg).addReg(AReg).addReg(BReg) + unsigned Opc = RegSize == 16 ? X86::SHRD16rri8 : X86::SHRD32rri8; + BuildMI(BB, Opc, 3, DestReg).addReg(AReg).addReg(BReg) .addImm(ShrCst->getValue()); return true; } @@ -1737,9 +1742,8 @@ Op0 = Node->getOperand(0); Op1 = Node->getOperand(1); - if (Node->getOpcode() == ISD::OR && N.getValueType() == MVT::i32 && - Op0.hasOneUse() && Op1.hasOneUse()) // Match SHLD and SHRD. - if (EmitDoubleShift(Op0, Op1, Result)) + if (Node->getOpcode() == ISD::OR && Op0.hasOneUse() && Op1.hasOneUse()) + if (EmitOrOpOp(Op0, Op1, Result)) // Match SHLD, SHRD, and rotates. return Result; if (Node->getOpcode() == ISD::SUB) From lattner at cs.uiuc.edu Wed Jan 19 01:50:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 01:50:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86RegisterInfo.cpp Message-ID: <200501190750.j0J7oGuY005706@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.117 -> 1.118 X86RegisterInfo.cpp updated: 1.98 -> 1.99 --- Log message: Add rotate instructions. --- Diffs of the changes: (+75 -0) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.117 llvm/lib/Target/X86/X86InstrInfo.td:1.118 --- llvm/lib/Target/X86/X86InstrInfo.td:1.117 Wed Jan 19 01:31:24 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jan 19 01:50:03 2005 @@ -875,6 +875,69 @@ "sar{l} {$src, $dst|$dst, $src}">; } +// Rotate instructions +// FIXME: provide shorter instructions when imm8 == 1 +def ROL8rCL : I<0xD2, MRM0r, (ops R8 :$dst, R8 :$src), + "rol{b} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; +def ROL16rCL : I<0xD3, MRM0r, (ops R16:$dst, R16:$src), + "rol{w} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>, OpSize; +def ROL32rCL : I<0xD3, MRM0r, (ops R32:$dst, R32:$src), + "rol{l} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; + +def ROL8ri : Ii8<0xC0, MRM0r, (ops R8 :$dst, R8 :$src1, i8imm:$src2), + "rol{b} {$src2, $dst|$dst, $src2}">; +def ROL16ri : Ii8<0xC1, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2), + "rol{w} {$src2, $dst|$dst, $src2}">, OpSize; +def ROL32ri : Ii8<0xC1, MRM0r, (ops R32:$dst, R32:$src1, i8imm:$src2), + "rol{l} {$src2, $dst|$dst, $src2}">; + +let isTwoAddress = 0 in { + def ROL8mCL : I<0xD2, MRM0m, (ops i8mem :$dst), + "rol{b} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; + def ROL16mCL : I<0xD3, MRM0m, (ops i16mem:$dst), + "rol{w} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>, OpSize; + def ROL32mCL : I<0xD3, MRM0m, (ops i32mem:$dst), + "rol{l} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; + def ROL8mi : Ii8<0xC0, MRM0m, (ops i8mem :$dst, i8imm:$src), + "rol{b} {$src, $dst|$dst, $src}">; + def ROL16mi : Ii8<0xC1, MRM0m, (ops i16mem:$dst, i8imm:$src), + "rol{w} {$src, $dst|$dst, $src}">, OpSize; + def ROL32mi : Ii8<0xC1, MRM0m, (ops i32mem:$dst, i8imm:$src), + "rol{l} {$src, $dst|$dst, $src}">; +} + +def ROR8rCL : I<0xD2, MRM1r, (ops R8 :$dst, R8 :$src), + "ror{b} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; +def ROR16rCL : I<0xD3, MRM1r, (ops R16:$dst, R16:$src), + "ror{w} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>, OpSize; +def ROR32rCL : I<0xD3, MRM1r, (ops R32:$dst, R32:$src), + "ror{l} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; + +def ROR8ri : Ii8<0xC0, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2), + "ror{b} {$src2, $dst|$dst, $src2}">; +def ROR16ri : Ii8<0xC1, MRM1r, (ops R16:$dst, R16:$src1, i8imm:$src2), + "ror{w} {$src2, $dst|$dst, $src2}">, OpSize; +def ROR32ri : Ii8<0xC1, MRM1r, (ops R32:$dst, R32:$src1, i8imm:$src2), + "ror{l} {$src2, $dst|$dst, $src2}">; +let isTwoAddress = 0 in { + def ROR8mCL : I<0xD2, MRM1m, (ops i8mem :$dst), + "ror{b} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; + def ROR16mCL : I<0xD3, MRM1m, (ops i16mem:$dst), + "ror{w} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>, OpSize; + def ROR32mCL : I<0xD3, MRM1m, (ops i32mem:$dst), + "ror{l} {%cl, $dst|$dst, %CL}">, Imp<[CL],[]>; + def ROR8mi : Ii8<0xC0, MRM1m, (ops i8mem :$dst, i8imm:$src), + "ror{b} {$src, $dst|$dst, $src}">; + def ROR16mi : Ii8<0xC1, MRM1m, (ops i16mem:$dst, i8imm:$src), + "ror{w} {$src, $dst|$dst, $src}">, OpSize; + def ROR32mi : Ii8<0xC1, MRM1m, (ops i32mem:$dst, i8imm:$src), + "ror{l} {$src, $dst|$dst, $src}">; +} + + + +// Double shift instructions (generalizations of rotate) + def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2), "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}">, Imp<[CL],[]>, TB; Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.98 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.99 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.98 Wed Jan 19 01:31:24 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Jan 19 01:50:03 2005 @@ -221,6 +221,18 @@ case X86::SAR8ri: return MakeMIInst(X86::SAR8mi , FrameIndex, MI); case X86::SAR16ri: return MakeMIInst(X86::SAR16mi, FrameIndex, MI); case X86::SAR32ri: return MakeMIInst(X86::SAR32mi, FrameIndex, MI); + case X86::ROL8rCL: return MakeMInst( X86::ROL8mCL ,FrameIndex, MI); + case X86::ROL16rCL: return MakeMInst( X86::ROL16mCL,FrameIndex, MI); + case X86::ROL32rCL: return MakeMInst( X86::ROL32mCL,FrameIndex, MI); + case X86::ROL8ri: return MakeMIInst(X86::ROL8mi , FrameIndex, MI); + case X86::ROL16ri: return MakeMIInst(X86::ROL16mi, FrameIndex, MI); + case X86::ROL32ri: return MakeMIInst(X86::ROL32mi, FrameIndex, MI); + case X86::ROR8rCL: return MakeMInst( X86::ROR8mCL ,FrameIndex, MI); + case X86::ROR16rCL: return MakeMInst( X86::ROR16mCL,FrameIndex, MI); + case X86::ROR32rCL: return MakeMInst( X86::ROR32mCL,FrameIndex, MI); + case X86::ROR8ri: return MakeMIInst(X86::ROR8mi , FrameIndex, MI); + case X86::ROR16ri: return MakeMIInst(X86::ROR16mi, FrameIndex, MI); + case X86::ROR32ri: return MakeMIInst(X86::ROR32mi, FrameIndex, MI); case X86::SHLD32rrCL:return MakeMRInst( X86::SHLD32mrCL,FrameIndex, MI); case X86::SHLD32rri8:return MakeMRIInst(X86::SHLD32mri8,FrameIndex, MI); case X86::SHRD32rrCL:return MakeMRInst( X86::SHRD32mrCL,FrameIndex, MI); From lattner at cs.uiuc.edu Wed Jan 19 02:04:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 02:04:23 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/rotate.ll Message-ID: <200501190804.j0J84NuJ006619@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: rotate.ll added (r1.1) --- Log message: New testcase for rotate instructions. Each function should codegen to a rotate. --- Diffs of the changes: (+91 -0) Index: llvm/test/Regression/CodeGen/X86/rotate.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/rotate.ll:1.1 *** /dev/null Wed Jan 19 02:04:18 2005 --- llvm/test/Regression/CodeGen/X86/rotate.ll Wed Jan 19 02:04:08 2005 *************** *** 0 **** --- 1,91 ---- + ; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel -disable-pattern-isel=0 | grep ro[rl] | wc -l | grep 12 + + uint %rotl32(uint %A, ubyte %Amt) { + %B = shl uint %A, ubyte %Amt + %Amt2 = sub ubyte 32, %Amt + %C = shr uint %A, ubyte %Amt2 + %D = or uint %B, %C + ret uint %D + } + + uint %rotr32(uint %A, ubyte %Amt) { + %B = shr uint %A, ubyte %Amt + %Amt2 = sub ubyte 32, %Amt + %C = shl uint %A, ubyte %Amt2 + %D = or uint %B, %C + ret uint %D + } + + uint %rotli32(uint %A) { + %B = shl uint %A, ubyte 5 + %C = shr uint %A, ubyte 27 + %D = or uint %B, %C + ret uint %D + } + + uint %rotri32(uint %A) { + %B = shr uint %A, ubyte 5 + %C = shl uint %A, ubyte 27 + %D = or uint %B, %C + ret uint %D + } + + ushort %rotl16(ushort %A, ubyte %Amt) { + %B = shl ushort %A, ubyte %Amt + %Amt2 = sub ubyte 16, %Amt + %C = shr ushort %A, ubyte %Amt2 + %D = or ushort %B, %C + ret ushort %D + } + + ushort %rotr16(ushort %A, ubyte %Amt) { + %B = shr ushort %A, ubyte %Amt + %Amt2 = sub ubyte 16, %Amt + %C = shl ushort %A, ubyte %Amt2 + %D = or ushort %B, %C + ret ushort %D + } + + ushort %rotli16(ushort %A) { + %B = shl ushort %A, ubyte 5 + %C = shr ushort %A, ubyte 11 + %D = or ushort %B, %C + ret ushort %D + } + + ushort %rotri16(ushort %A) { + %B = shr ushort %A, ubyte 5 + %C = shl ushort %A, ubyte 11 + %D = or ushort %B, %C + ret ushort %D + } + + ubyte %rotl8(ubyte %A, ubyte %Amt) { + %B = shl ubyte %A, ubyte %Amt + %Amt2 = sub ubyte 8, %Amt + %C = shr ubyte %A, ubyte %Amt2 + %D = or ubyte %B, %C + ret ubyte %D + } + + ubyte %rotr8(ubyte %A, ubyte %Amt) { + %B = shr ubyte %A, ubyte %Amt + %Amt2 = sub ubyte 8, %Amt + %C = shl ubyte %A, ubyte %Amt2 + %D = or ubyte %B, %C + ret ubyte %D + } + + ubyte %rotli8(ubyte %A) { + %B = shl ubyte %A, ubyte 5 + %C = shr ubyte %A, ubyte 3 + %D = or ubyte %B, %C + ret ubyte %D + } + + ubyte %rotri8(ubyte %A) { + %B = shr ubyte %A, ubyte 5 + %C = shl ubyte %A, ubyte 3 + %D = or ubyte %B, %C + ret ubyte %D + } From lattner at cs.uiuc.edu Wed Jan 19 02:07:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 02:07:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501190807.j0J87JOH006642@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.79 -> 1.80 --- Log message: Implement Regression/CodeGen/X86/rotate.ll: emit rotate instructions (which typically cost 1 cycle) instead of shld/shrd instruction (which are typically 6 or more cycles). This also saves code space. For example, instead of emitting: rotr: mov %EAX, DWORD PTR [%ESP + 4] mov %CL, BYTE PTR [%ESP + 8] shrd %EAX, %EAX, %CL ret rotli: mov %EAX, DWORD PTR [%ESP + 4] shrd %EAX, %EAX, 27 ret Emit: rotr32: mov %CL, BYTE PTR [%ESP + 8] mov %EAX, DWORD PTR [%ESP + 4] ror %EAX, %CL ret rotli32: mov %EAX, DWORD PTR [%ESP + 4] ror %EAX, 27 ret We also emit byte rotate instructions which do not have a sh[lr]d counterpart at all. --- Diffs of the changes: (+79 -38) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.79 llvm/lib/Target/X86/X86ISelPattern.cpp:1.80 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.79 Wed Jan 19 01:37:26 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jan 19 02:07:05 2005 @@ -1165,47 +1165,60 @@ // Find out if ShrAmt = 32-ShlAmt or ShlAmt = 32-ShrAmt. if (ShlAmt.getOpcode() == ISD::SUB && ShlAmt.getOperand(1) == ShrAmt) if (ConstantSDNode *SubCST = dyn_cast(ShlAmt.getOperand(0))) - if (SubCST->getValue() == RegSize && RegSize != 8) { + if (SubCST->getValue() == RegSize) { + // (A >> ShrAmt) | (A << (32-ShrAmt)) ==> ROR A, ShrAmt // (A >> ShrAmt) | (B << (32-ShrAmt)) ==> SHRD A, B, ShrAmt - unsigned AReg, BReg; - if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { - AReg = SelectExpr(ShrVal); - BReg = SelectExpr(ShlVal); - } else { - BReg = SelectExpr(ShlVal); - AReg = SelectExpr(ShrVal); + if (ShrVal == ShlVal) { + unsigned Reg, ShAmt; + if (getRegPressure(ShrVal) > getRegPressure(ShrAmt)) { + Reg = SelectExpr(ShrVal); + ShAmt = SelectExpr(ShrAmt); + } else { + ShAmt = SelectExpr(ShrAmt); + Reg = SelectExpr(ShrVal); + } + BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); + unsigned Opc = RegSize == 8 ? X86::ROR8rCL : + (RegSize == 16 ? X86::ROR16rCL : X86::ROR32rCL); + BuildMI(BB, Opc, 1, DestReg).addReg(Reg); + return true; + } else if (RegSize != 8) { + unsigned AReg, BReg; + if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { + AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); + } else { + BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); + } + unsigned ShAmt = SelectExpr(ShrAmt); + BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); + unsigned Opc = RegSize == 16 ? X86::SHRD16rrCL : X86::SHRD32rrCL; + BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg); + return true; } - unsigned ShAmt = SelectExpr(ShrAmt); - BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); - unsigned Opc = RegSize == 16 ? X86::SHRD16rrCL : X86::SHRD32rrCL; - BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg); - return true; } if (ShrAmt.getOpcode() == ISD::SUB && ShrAmt.getOperand(1) == ShlAmt) if (ConstantSDNode *SubCST = dyn_cast(ShrAmt.getOperand(0))) - if (SubCST->getValue() == RegSize && RegSize != 8) { + if (SubCST->getValue() == RegSize) { + // (A << ShlAmt) | (A >> (32-ShlAmt)) ==> ROL A, ShrAmt // (A << ShlAmt) | (B >> (32-ShlAmt)) ==> SHLD A, B, ShrAmt - unsigned AReg, BReg; - if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { - AReg = SelectExpr(ShrVal); - BReg = SelectExpr(ShlVal); - } else { - BReg = SelectExpr(ShlVal); - AReg = SelectExpr(ShrVal); - } - unsigned ShAmt = SelectExpr(ShlAmt); - BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); - unsigned Opc = RegSize == 16 ? X86::SHLD16rrCL : X86::SHLD32rrCL; - BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg); - return true; - } - - if (ConstantSDNode *ShrCst = dyn_cast(ShrAmt)) - if (ConstantSDNode *ShlCst = dyn_cast(ShlAmt)) - if (ShrCst->getValue() < RegSize && ShlCst->getValue() < RegSize) { - if (ShrCst->getValue() == RegSize-ShlCst->getValue() && RegSize != 8) { - // (A >> 5) | (B << 27) --> SHRD A, B, 5 + if (ShrVal == ShlVal) { + unsigned Reg, ShAmt; + if (getRegPressure(ShrVal) > getRegPressure(ShlAmt)) { + Reg = SelectExpr(ShrVal); + ShAmt = SelectExpr(ShlAmt); + } else { + ShAmt = SelectExpr(ShlAmt); + Reg = SelectExpr(ShrVal); + } + BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); + unsigned Opc = RegSize == 8 ? X86::ROL8rCL : + (RegSize == 16 ? X86::ROL16rCL : X86::ROL32rCL); + BuildMI(BB, Opc, 1, DestReg).addReg(Reg); + return true; + } else if (RegSize != 8) { unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { AReg = SelectExpr(ShrVal); @@ -1214,14 +1227,42 @@ BReg = SelectExpr(ShlVal); AReg = SelectExpr(ShrVal); } - unsigned Opc = RegSize == 16 ? X86::SHRD16rri8 : X86::SHRD32rri8; - BuildMI(BB, Opc, 3, DestReg).addReg(AReg).addReg(BReg) - .addImm(ShrCst->getValue()); + unsigned ShAmt = SelectExpr(ShlAmt); + BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); + unsigned Opc = RegSize == 16 ? X86::SHLD16rrCL : X86::SHLD32rrCL; + BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg); return true; } } - + if (ConstantSDNode *ShrCst = dyn_cast(ShrAmt)) + if (ConstantSDNode *ShlCst = dyn_cast(ShlAmt)) + if (ShrCst->getValue() < RegSize && ShlCst->getValue() < RegSize) + if (ShrCst->getValue() == RegSize-ShlCst->getValue()) { + // (A >> 5) | (A << 27) --> ROR A, 5 + // (A >> 5) | (B << 27) --> SHRD A, B, 5 + if (ShrVal == ShlVal) { + unsigned Reg = SelectExpr(ShrVal); + unsigned Opc = RegSize == 8 ? X86::ROR8ri : + (RegSize == 16 ? X86::ROR16ri : X86::ROR32ri); + BuildMI(BB, Opc, 2, DestReg).addReg(Reg).addImm(ShrCst->getValue()); + return true; + } else if (RegSize != 8) { + unsigned AReg, BReg; + if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { + AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); + } else { + BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); + } + unsigned Opc = RegSize == 16 ? X86::SHRD16rri8 : X86::SHRD32rri8; + BuildMI(BB, Opc, 3, DestReg).addReg(AReg).addReg(BReg) + .addImm(ShrCst->getValue()); + return true; + } + } + return false; } From lattner at cs.uiuc.edu Wed Jan 19 10:16:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 10:16:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/LevelRaise.cpp Message-ID: <200501191616.j0JGGo0g007573@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: LevelRaise.cpp updated: 1.103 -> 1.104 --- Log message: Fix 'raise' to work with packed types. Patch by Morten Ofstad. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Transforms/LevelRaise.cpp diff -u llvm/lib/Transforms/LevelRaise.cpp:1.103 llvm/lib/Transforms/LevelRaise.cpp:1.104 --- llvm/lib/Transforms/LevelRaise.cpp:1.103 Sun Sep 19 23:43:57 2004 +++ llvm/lib/Transforms/LevelRaise.cpp Wed Jan 19 10:16:35 2005 @@ -382,7 +382,7 @@ // ElTy = CurSTy->getElementType(0); } else { - ElTy = cast(CurCTy)->getElementType(); + ElTy = cast(CurCTy)->getElementType(); } // Insert a zero to index through this type... From lattner at cs.uiuc.edu Wed Jan 19 10:56:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 10:56:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200501191656.j0JGu7qd008632@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.36 -> 1.37 --- Log message: When commuting these instructions, make sure to actually swap the operands too. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.36 llvm/lib/Target/X86/X86InstrInfo.cpp:1.37 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.36 Wed Jan 19 01:31:24 2005 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Wed Jan 19 10:55:52 2005 @@ -143,7 +143,7 @@ unsigned A = MI->getOperand(0).getReg(); unsigned B = MI->getOperand(1).getReg(); unsigned C = MI->getOperand(2).getReg(); - return BuildMI(Opc, 3, A).addReg(B).addReg(C).addImm(Size-Amt); + return BuildMI(Opc, 3, A).addReg(C).addReg(B).addImm(Size-Amt); } default: return TargetInstrInfo::commuteInstruction(MI); From lattner at cs.uiuc.edu Wed Jan 19 11:09:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 11:09:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveVariables.cpp Message-ID: <200501191709.j0JH9SgE008976@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveVariables.cpp updated: 1.45 -> 1.46 --- Log message: When an instruction moves, make sure to update the VarInfo::Kills list as well as all of teh other stuff in livevar. This fixes the compiler crash on fourinarow last night. --- Diffs of the changes: (+10 -3) Index: llvm/lib/CodeGen/LiveVariables.cpp diff -u llvm/lib/CodeGen/LiveVariables.cpp:1.45 llvm/lib/CodeGen/LiveVariables.cpp:1.46 --- llvm/lib/CodeGen/LiveVariables.cpp:1.45 Mon Oct 25 13:44:14 2004 +++ llvm/lib/CodeGen/LiveVariables.cpp Wed Jan 19 11:09:15 2005 @@ -302,12 +302,19 @@ // the instruction. for (unsigned i = 0, e = OldMI->getNumOperands(); i != e; ++i) { MachineOperand &MO = OldMI->getOperand(i); - if (MO.isRegister() && MO.isDef() && MO.getReg() && + if (MO.isRegister() && MO.getReg() && MRegisterInfo::isVirtualRegister(MO.getReg())) { unsigned Reg = MO.getReg(); VarInfo &VI = getVarInfo(Reg); - if (VI.DefInst == OldMI) - VI.DefInst = NewMI; + if (MO.isDef()) { + // Update the defining instruction. + if (VI.DefInst == OldMI) + VI.DefInst = NewMI; + } else if (MO.isUse()) { + // If this is a kill of the value, update the VI kills list. + if (VI.removeKill(OldMI)) + VI.Kills.push_back(NewMI); // Yes, there was a kill of it + } } } From lattner at cs.uiuc.edu Wed Jan 19 11:12:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 11:12:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveVariables.cpp Message-ID: <200501191712.j0JHC3MP009387@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveVariables.cpp updated: 1.46 -> 1.47 --- Log message: Just in case, handle something that is both a use and a def. --- Diffs of the changes: (+2 -1) Index: llvm/lib/CodeGen/LiveVariables.cpp diff -u llvm/lib/CodeGen/LiveVariables.cpp:1.46 llvm/lib/CodeGen/LiveVariables.cpp:1.47 --- llvm/lib/CodeGen/LiveVariables.cpp:1.46 Wed Jan 19 11:09:15 2005 +++ llvm/lib/CodeGen/LiveVariables.cpp Wed Jan 19 11:11:51 2005 @@ -310,7 +310,8 @@ // Update the defining instruction. if (VI.DefInst == OldMI) VI.DefInst = NewMI; - } else if (MO.isUse()) { + } + if (MO.isUse()) { // If this is a kill of the value, update the VI kills list. if (VI.removeKill(OldMI)) VI.Kills.push_back(NewMI); // Yes, there was a kill of it From lattner at cs.uiuc.edu Wed Jan 19 11:24:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 11:24:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501191724.j0JHOllw009745@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.80 -> 1.81 --- Log message: Fix a problem where were were literally selecting for INCREASED register pressure, not decreases register pressure. Fix problem where we accidentally swapped the operands of SHLD, which caused fourinarow to fail. This fixes fourinarow. --- Diffs of the changes: (+8 -8) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.80 llvm/lib/Target/X86/X86ISelPattern.cpp:1.81 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.80 Wed Jan 19 02:07:05 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jan 19 11:24:34 2005 @@ -1185,11 +1185,11 @@ } else if (RegSize != 8) { unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { - AReg = SelectExpr(ShrVal); BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); } else { - BReg = SelectExpr(ShlVal); AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); } unsigned ShAmt = SelectExpr(ShrAmt); BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); @@ -1221,11 +1221,11 @@ } else if (RegSize != 8) { unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { - AReg = SelectExpr(ShrVal); - BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShlVal); + BReg = SelectExpr(ShrVal); } else { - BReg = SelectExpr(ShlVal); - AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShrVal); + AReg = SelectExpr(ShlVal); } unsigned ShAmt = SelectExpr(ShlAmt); BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt); @@ -1250,11 +1250,11 @@ } else if (RegSize != 8) { unsigned AReg, BReg; if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) { - AReg = SelectExpr(ShrVal); BReg = SelectExpr(ShlVal); + AReg = SelectExpr(ShrVal); } else { - BReg = SelectExpr(ShlVal); AReg = SelectExpr(ShrVal); + BReg = SelectExpr(ShlVal); } unsigned Opc = RegSize == 16 ? X86::SHRD16rri8 : X86::SHRD32rri8; BuildMI(BB, Opc, 3, DestReg).addReg(AReg).addReg(BReg) From lattner at cs.uiuc.edu Wed Jan 19 11:30:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 11:30:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501191730.j0JHU1nL010152@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.41 -> 1.42 --- Log message: Know some simple identities. This improves codegen for (1LL << N). --- Diffs of the changes: (+13 -0) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.41 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.42 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.41 Tue Jan 18 13:26:36 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Jan 19 11:29:49 2005 @@ -615,6 +615,19 @@ std::swap(N1, N2); } } + + switch (Opcode) { + default: break; + case ISD::SHL: // shl 0, X -> 0 + if (N1C->isNullValue()) return N1; + break; + case ISD::SRL: // srl 0, X -> 0 + if (N1C->isNullValue()) return N1; + break; + case ISD::SRA: // sra -1, X -> -1 + if (N1C->isAllOnesValue()) return N1; + break; + } } if (N2C) { From lattner at cs.uiuc.edu Wed Jan 19 12:01:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 12:01:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501191801.j0JI1rQ0011631@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.42 -> 1.43 --- Log message: Know some identities about tokenfactor nodes. --- Diffs of the changes: (+11 -0) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.42 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.43 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.42 Wed Jan 19 11:29:49 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Jan 19 12:01:40 2005 @@ -549,6 +549,10 @@ SDOperand N1, SDOperand N2) { #ifndef NDEBUG switch (Opcode) { + case ISD::TokenFactor: + assert(VT == MVT::Other && N1.getValueType() == MVT::Other && + N2.getValueType() == MVT::Other && "Invalid token factor!"); + break; case ISD::AND: case ISD::OR: case ISD::XOR: @@ -739,6 +743,13 @@ // Finally, fold operations that do not require constants. switch (Opcode) { + case ISD::TokenFactor: + if (N1.getOpcode() == ISD::EntryToken) + return N2; + if (N2.getOpcode() == ISD::EntryToken) + return N1; + break; + case ISD::AND: case ISD::OR: if (SetCCSDNode *LHS = dyn_cast(N1.Val)) From lattner at cs.uiuc.edu Wed Jan 19 12:02:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 12:02:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501191802.j0JI2UO5011641@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.44 -> 1.45 --- Log message: Realize the individual pieces of an expanded copytoreg/store/load are independent of each other. --- Diffs of the changes: (+16 -9) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.44 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.45 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.44 Tue Jan 18 22:19:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 19 12:02:17 2005 @@ -399,8 +399,10 @@ SDOperand Lo, Hi; ExpandOp(Node->getOperand(1), Lo, Hi); unsigned Reg = cast(Node)->getReg(); - Result = DAG.getCopyToReg(Tmp1, Lo, Reg); - Result = DAG.getCopyToReg(Result, Hi, Reg+1); + Lo = DAG.getCopyToReg(Tmp1, Lo, Reg); + Hi = DAG.getCopyToReg(Tmp1, Hi, Reg+1); + // Note that the copytoreg nodes are independent of each other. + Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); assert(isTypeLegal(Result.getValueType()) && "Cannot expand multiple times yet (i64 -> i16)"); break; @@ -506,15 +508,16 @@ if (!TLI.isLittleEndian()) std::swap(Lo, Hi); - // FIXME: These two stores are independent of each other! - Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Lo, Tmp2); + Lo = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Lo, Tmp2); - unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8; + unsigned IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8; Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Tmp2.getValueType()) && "Pointers must be legal!"); - Result = DAG.getNode(ISD::STORE, MVT::Other, Result, Hi, Tmp2); + Hi = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Hi, Tmp2); + Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + break; } break; case ISD::TRUNCSTORE: @@ -1292,11 +1295,15 @@ unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8; Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); - // FIXME: This load is independent of the first one. - Hi = DAG.getLoad(NVT, Lo.getValue(1), Ptr); + Hi = DAG.getLoad(NVT, Ch, Ptr); + + // Build a factor node to remember that this load is independent of the + // other one. + SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); // Remember that we legalized the chain. - AddLegalizedOperand(Op.getValue(1), Hi.getValue(1)); + AddLegalizedOperand(Op.getValue(1), TF); if (!TLI.isLittleEndian()) std::swap(Lo, Hi); break; From lattner at cs.uiuc.edu Wed Jan 19 13:11:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 13:11:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501191911.j0JJB89V012281@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.45 -> 1.46 --- Log message: Fold single use token factor nodes into other token factor nodes. --- Diffs of the changes: (+10 -2) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.45 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.46 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.45 Wed Jan 19 12:02:17 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 19 13:10:54 2005 @@ -264,8 +264,16 @@ std::vector Ops; bool Changed = false; for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { - Ops.push_back(LegalizeOp(Node->getOperand(i))); // Legalize the operands - Changed |= Ops[i] != Node->getOperand(i); + SDOperand Op = Node->getOperand(i); + // Fold single-use TokenFactor nodes into this token factor as we go. + if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) { + Changed = true; + for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j) + Ops.push_back(LegalizeOp(Op.getOperand(j))); + } else { + Ops.push_back(LegalizeOp(Op)); // Legalize the operands + Changed |= Ops[i] != Op; + } } if (Changed) Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); From lattner at cs.uiuc.edu Wed Jan 19 14:20:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 14:20:13 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200501192020.j0JKKDNv012670@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.16 -> 1.17 --- Log message: Add an accessor for targets that pass args in regs --- Diffs of the changes: (+14 -0) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.16 llvm/include/llvm/CodeGen/SelectionDAG.h:1.17 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.16 Tue Jan 18 13:26:18 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Jan 19 14:19:58 2005 @@ -131,6 +131,20 @@ return NN; } + /// getCall - This is identical to the one above, and should be used for calls + /// where arguments are passed in physical registers. This destroys the + /// RetVals and ArgsInRegs vectors. + SDNode *getCall(std::vector &RetVals, SDOperand Chain, + SDOperand Callee, std::vector &ArgsInRegs) { + ArgsInRegs.insert(ArgsInRegs.begin(), Callee); + ArgsInRegs.insert(ArgsInRegs.begin(), Chain); + SDNode *NN = new SDNode(ISD::CALL, ArgsInRegs); + NN->setValueTypes(RetVals); + AllNodes.push_back(NN); + return NN; + } + + SDOperand getSetCC(ISD::CondCode, MVT::ValueType VT, SDOperand LHS, SDOperand RHS); From lattner at cs.uiuc.edu Wed Jan 19 14:24:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 14:24:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501192024.j0JKOmbF012788@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.46 -> 1.47 --- Log message: Add support for targets that pass args in registers to calls. --- Diffs of the changes: (+25 -6) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.46 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.47 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.46 Wed Jan 19 13:10:54 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 19 14:24:35 2005 @@ -305,15 +305,23 @@ AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); - case ISD::CALL: + case ISD::CALL: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the callee. - if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) { + + bool Changed = false; + std::vector Ops; + for (unsigned i = 2, e = Node->getNumOperands(); i != e; ++i) { + Ops.push_back(LegalizeOp(Node->getOperand(i))); + Changed |= Ops.back() != Node->getOperand(i); + } + + if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) || Changed) { std::vector RetTyVTs; RetTyVTs.reserve(Node->getNumValues()); for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) RetTyVTs.push_back(Node->getValueType(i)); - Result = SDOperand(DAG.getCall(RetTyVTs, Tmp1, Tmp2), 0); + Result = SDOperand(DAG.getCall(RetTyVTs, Tmp1, Tmp2, Ops), 0); } else { Result = Result.getValue(0); } @@ -322,7 +330,7 @@ for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) AddLegalizedOperand(SDOperand(Node, i), Result.getValue(i)); return Result.getValue(Op.ResNo); - + } case ISD::BR: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. if (Tmp1 != Node->getOperand(0)) @@ -1151,13 +1159,17 @@ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the callee. + std::vector Ops; + for (unsigned i = 2, e = Node->getNumOperands(); i != e; ++i) + Ops.push_back(LegalizeOp(Node->getOperand(i))); + assert(Node->getNumValues() == 2 && Op.ResNo == 0 && "Can only promote single result calls"); std::vector RetTyVTs; RetTyVTs.reserve(2); RetTyVTs.push_back(NVT); RetTyVTs.push_back(MVT::Other); - SDNode *NC = DAG.getCall(RetTyVTs, Tmp1, Tmp2); + SDNode *NC = DAG.getCall(RetTyVTs, Tmp1, Tmp2, Ops); Result = SDOperand(NC, 0); // Insert the new chain mapping. @@ -1320,6 +1332,13 @@ SDOperand Chain = LegalizeOp(Node->getOperand(0)); // Legalize the chain. SDOperand Callee = LegalizeOp(Node->getOperand(1)); // Legalize the callee. + bool Changed = false; + std::vector Ops; + for (unsigned i = 2, e = Node->getNumOperands(); i != e; ++i) { + Ops.push_back(LegalizeOp(Node->getOperand(i))); + Changed |= Ops.back() != Node->getOperand(i); + } + assert(Node->getNumValues() == 2 && Op.ResNo == 0 && "Can only expand a call once so far, not i64 -> i16!"); @@ -1328,7 +1347,7 @@ RetTyVTs.push_back(NVT); RetTyVTs.push_back(NVT); RetTyVTs.push_back(MVT::Other); - SDNode *NC = DAG.getCall(RetTyVTs, Chain, Callee); + SDNode *NC = DAG.getCall(RetTyVTs, Chain, Callee, Ops); Lo = SDOperand(NC, 0); Hi = SDOperand(NC, 1); From lattner at cs.uiuc.edu Wed Jan 19 15:32:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 15:32:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200501192132.j0JLWMxg016512@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.37 -> 1.38 --- Log message: Add an assertion that would have made more sense to duraid --- Diffs of the changes: (+3 -1) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.37 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.38 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.37 Sun Aug 29 17:00:24 2004 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Wed Jan 19 15:32:07 2005 @@ -220,7 +220,9 @@ I = MBB->end(); --I; for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i],StackSlots[i]); + RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i], StackSlots[i]); + assert(I != MBB->begin() && + "loadRegFromStackSlot didn't insert any code!"); --I; // Insert in reverse order } } From lattner at cs.uiuc.edu Wed Jan 19 15:48:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 15:48:46 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll Message-ID: <200501192148.j0JLmk1X017104@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.24 -> 1.25 --- Log message: Add some new tests --- Diffs of the changes: (+14 -0) Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.24 llvm/test/Regression/Transforms/InstCombine/add.ll:1.25 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.24 Sat Nov 13 13:45:37 2004 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Wed Jan 19 15:48:31 2005 @@ -177,3 +177,17 @@ ret long %tmp.8 } +int %test26(int %A, int %B) { + %C = add int %A, %B + %D = sub int %C, %B + ret int %D +} + +int %test27(bool %C, int %X, int %Y) { + %A = add int %X, %Y + %B = add int %Y, 123 + %C = select bool %C, int %A, int %B ;; Fold add through select. + %D = sub int %C, %Y + ret int %D +} + From lattner at cs.uiuc.edu Wed Jan 19 15:50:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 15:50:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200501192150.j0JLoVfn017144@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.307 -> 1.308 --- Log message: Add two optimizations. The first folds (X+Y)-X -> Y The second folds operations into selects, e.g. (select C, (X+Y), (Y+Z)) -> (Y+(select C, X, Z) This occurs a few times across spec, e.g. select add/sub mesa: 83 0 povray: 5 2 gcc 4 2 parser 0 22 perlbmk 13 30 twolf 0 3 --- Diffs of the changes: (+89 -2) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.307 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.308 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.307 Sun Jan 16 23:10:15 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Jan 19 15:50:18 2005 @@ -120,6 +120,8 @@ Instruction::BinaryOps Cond, Instruction &I); Instruction *visitShiftInst(ShiftInst &I); Instruction *visitCastInst(CastInst &CI); + Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI, + Instruction *FI); Instruction *visitSelectInst(SelectInst &CI); Instruction *visitCallInst(CallInst &CI); Instruction *visitInvokeInst(InvokeInst &II); @@ -833,6 +835,14 @@ } } + if (BinaryOperator *Op0I = dyn_cast(Op0)) + if (Op0I->getOpcode() == Instruction::Add) + if (!Op0->getType()->isFloatingPoint()) { + if (Op0I->getOperand(0) == Op1) // (Y+X)-Y == X + return ReplaceInstUsesWith(I, Op0I->getOperand(1)); + else if (Op0I->getOperand(1) == Op1) // (X+Y)-Y == X + return ReplaceInstUsesWith(I, Op0I->getOperand(0)); + } ConstantInt *C1; if (Value *X = dyn_castFoldableMul(Op0, C1)) { @@ -3496,6 +3506,78 @@ } } +/// FoldSelectOpOp - Here we have (select c, TI, FI), and we know that TI and FI +/// have the same opcode and only one use each. Try to simplify this. +Instruction *InstCombiner::FoldSelectOpOp(SelectInst &SI, Instruction *TI, + Instruction *FI) { + if (TI->getNumOperands() == 1) { + // If this is a non-volatile load or a cast from the same type, + // merge. + if (TI->getOpcode() == Instruction::Cast) { + if (TI->getOperand(0)->getType() != FI->getOperand(0)->getType()) + return 0; + } else { + return 0; // unknown unary op. + } + + // Fold this by inserting a select from the input values. + SelectInst *NewSI = new SelectInst(SI.getCondition(), TI->getOperand(0), + FI->getOperand(0), SI.getName()+".v"); + InsertNewInstBefore(NewSI, SI); + return new CastInst(NewSI, TI->getType()); + } + + // Only handle binary operators here. + if (!isa(TI) && !isa(TI)) + return 0; + + // Figure out if the operations have any operands in common. + Value *MatchOp, *OtherOpT, *OtherOpF; + bool MatchIsOpZero; + if (TI->getOperand(0) == FI->getOperand(0)) { + MatchOp = TI->getOperand(0); + OtherOpT = TI->getOperand(1); + OtherOpF = FI->getOperand(1); + MatchIsOpZero = true; + } else if (TI->getOperand(1) == FI->getOperand(1)) { + MatchOp = TI->getOperand(1); + OtherOpT = TI->getOperand(0); + OtherOpF = FI->getOperand(0); + MatchIsOpZero = false; + } else if (!TI->isCommutative()) { + return 0; + } else if (TI->getOperand(0) == FI->getOperand(1)) { + MatchOp = TI->getOperand(0); + OtherOpT = TI->getOperand(1); + OtherOpF = FI->getOperand(0); + MatchIsOpZero = true; + } else if (TI->getOperand(1) == FI->getOperand(0)) { + MatchOp = TI->getOperand(1); + OtherOpT = TI->getOperand(0); + OtherOpF = FI->getOperand(1); + MatchIsOpZero = true; + } else { + return 0; + } + + // If we reach here, they do have operations in common. + SelectInst *NewSI = new SelectInst(SI.getCondition(), OtherOpT, + OtherOpF, SI.getName()+".v"); + InsertNewInstBefore(NewSI, SI); + + if (BinaryOperator *BO = dyn_cast(TI)) { + if (MatchIsOpZero) + return BinaryOperator::create(BO->getOpcode(), MatchOp, NewSI); + else + return BinaryOperator::create(BO->getOpcode(), NewSI, MatchOp); + } else { + if (MatchIsOpZero) + return new ShiftInst(cast(TI)->getOpcode(), MatchOp, NewSI); + else + return new ShiftInst(cast(TI)->getOpcode(), NewSI, MatchOp); + } +} + Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { Value *CondVal = SI.getCondition(); Value *TrueVal = SI.getTrueValue(); @@ -3616,14 +3698,19 @@ } } - // Turn select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y))). This is legal for - // FP as well. if (Instruction *TI = dyn_cast(TrueVal)) if (Instruction *FI = dyn_cast(FalseVal)) if (TI->hasOneUse() && FI->hasOneUse()) { bool isInverse = false; Instruction *AddOp = 0, *SubOp = 0; + // Turn (select C, (op X, Y), (op X, Z)) -> (op X, (select C, Y, Z)) + if (TI->getOpcode() == FI->getOpcode()) + if (Instruction *IV = FoldSelectOpOp(SI, TI, FI)) + return IV; + + // Turn select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y))). This is + // even legal for FP. if (TI->getOpcode() == Instruction::Sub && FI->getOpcode() == Instruction::Add) { AddOp = FI; SubOp = TI; From lattner at cs.uiuc.edu Wed Jan 19 16:31:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 19 Jan 2005 16:31:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200501192231.j0JMVaVg018438@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.27 -> 1.28 --- Log message: Support targets that do not use i8 shift amounts. --- Diffs of the changes: (+4 -0) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.27 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.28 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.27 Tue Jan 18 11:54:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jan 19 16:31:21 2005 @@ -450,6 +450,10 @@ void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode) { SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1)); + + if (isa(I)) + Op2 = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), Op2); + setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); } From llvm at cs.uiuc.edu Wed Jan 19 22:41:09 2005 From: llvm at cs.uiuc.edu (LLVM) Date: Wed, 19 Jan 2005 22:41:09 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-prof/ Message-ID: <200501200441.WAA22960@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-prof: --- Log message: Directory /var/cvs/llvm/llvm/win32/llvm-prof added to the repository --- Diffs of the changes: (+0 -0) From jeffc at jolt-lang.org Wed Jan 19 22:41:45 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 19 Jan 2005 22:41:45 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm-prof/llvm-prof.vcproj Message-ID: <200501200441.WAA22978@zion.cs.uiuc.edu> Changes in directory llvm/win32/llvm-prof: llvm-prof.vcproj added (r1.1) --- Log message: Add project llvm-proj to Visual Studio --- Diffs of the changes: (+137 -0) Index: llvm/win32/llvm-prof/llvm-prof.vcproj diff -c /dev/null llvm/win32/llvm-prof/llvm-prof.vcproj:1.1 *** /dev/null Wed Jan 19 22:41:45 2005 --- llvm/win32/llvm-prof/llvm-prof.vcproj Wed Jan 19 22:41:35 2005 *************** *** 0 **** --- 1,137 ---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From jeffc at jolt-lang.org Wed Jan 19 22:42:00 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 19 Jan 2005 22:42:00 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200501200442.WAA22990@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.20 -> 1.21 --- Log message: Add project llvm-proj to Visual Studio --- Diffs of the changes: (+14 -0) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.20 llvm/win32/llvm.sln:1.21 --- llvm/win32/llvm.sln:1.20 Mon Jan 17 23:44:25 2005 +++ llvm/win32/llvm.sln Wed Jan 19 22:41:49 2005 @@ -206,6 +206,16 @@ {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-prof", "llvm-prof\llvm-prof.vcproj", "{ACBE81D9-64B1-4133-823A-807A4E60B454}" + ProjectSection(ProjectDependencies) = postProject + {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -320,6 +330,10 @@ {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug.Build.0 = Debug|Win32 {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release.ActiveCfg = Release|Win32 {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release.Build.0 = Release|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug.ActiveCfg = Debug|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug.Build.0 = Debug|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Release.ActiveCfg = Release|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From llvm at cs.uiuc.edu Wed Jan 19 22:52:41 2005 From: llvm at cs.uiuc.edu (LLVM) Date: Wed, 19 Jan 2005 22:52:41 -0600 Subject: [llvm-commits] CVS: llvm/win32/analyze/ Message-ID: <200501200452.WAA23046@zion.cs.uiuc.edu> Changes in directory llvm/win32/analyze: --- Log message: Directory /var/cvs/llvm/llvm/win32/analyze added to the repository --- Diffs of the changes: (+0 -0) From jeffc at jolt-lang.org Wed Jan 19 22:53:09 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 19 Jan 2005 22:53:09 -0600 Subject: [llvm-commits] CVS: llvm/win32/analyze/analyze.vcproj Message-ID: <200501200453.WAA23066@zion.cs.uiuc.edu> Changes in directory llvm/win32/analyze: analyze.vcproj added (r1.1) --- Log message: Add analyze project to Visual Studio --- Diffs of the changes: (+143 -0) Index: llvm/win32/analyze/analyze.vcproj diff -c /dev/null llvm/win32/analyze/analyze.vcproj:1.1 *** /dev/null Wed Jan 19 22:53:09 2005 --- llvm/win32/analyze/analyze.vcproj Wed Jan 19 22:52:59 2005 *************** *** 0 **** --- 1,143 ---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From jeffc at jolt-lang.org Wed Jan 19 22:53:10 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 19 Jan 2005 22:53:10 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200501200453.WAA23069@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.21 -> 1.22 --- Log message: Add analyze project to Visual Studio --- Diffs of the changes: (+16 -0) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.21 llvm/win32/llvm.sln:1.22 --- llvm/win32/llvm.sln:1.21 Wed Jan 19 22:41:49 2005 +++ llvm/win32/llvm.sln Wed Jan 19 22:52:59 2005 @@ -216,6 +216,18 @@ {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "analyze", "analyze\analyze.vcproj", "{DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}" + ProjectSection(ProjectDependencies) = postProject + {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -334,6 +346,10 @@ {ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug.Build.0 = Debug|Win32 {ACBE81D9-64B1-4133-823A-807A4E60B454}.Release.ActiveCfg = Release|Win32 {ACBE81D9-64B1-4133-823A-807A4E60B454}.Release.Build.0 = Release|Win32 + {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Debug.ActiveCfg = Debug|Win32 + {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Debug.Build.0 = Debug|Win32 + {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Release.ActiveCfg = Release|Win32 + {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From jeffc at jolt-lang.org Wed Jan 19 23:19:51 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 19 Jan 2005 23:19:51 -0600 Subject: [llvm-commits] CVS: llvm/win32/analyze/analyze.vcproj Message-ID: <200501200519.XAA23265@zion.cs.uiuc.edu> Changes in directory llvm/win32/analyze: analyze.vcproj updated: 1.1 -> 1.2 --- Log message: Get analyze to show all analysis options when compiled with VC++ --- Diffs of the changes: (+2 -0) Index: llvm/win32/analyze/analyze.vcproj diff -u llvm/win32/analyze/analyze.vcproj:1.1 llvm/win32/analyze/analyze.vcproj:1.2 --- llvm/win32/analyze/analyze.vcproj:1.1 Wed Jan 19 22:52:59 2005 +++ llvm/win32/analyze/analyze.vcproj Wed Jan 19 23:19:40 2005 @@ -36,6 +36,7 @@ Name="VCCustomBuildTool"/> Changes in directory llvm/win32: llvm.sln updated: 1.22 -> 1.23 --- Log message: Get analyze to show all analysis options when compiled with VC++ --- Diffs of the changes: (+1 -0) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.22 llvm/win32/llvm.sln:1.23 --- llvm/win32/llvm.sln:1.22 Wed Jan 19 22:52:59 2005 +++ llvm/win32/llvm.sln Wed Jan 19 23:19:40 2005 @@ -223,6 +223,7 @@ {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} From lattner at cs.uiuc.edu Thu Jan 20 10:50:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 10:50:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501201650.j0KGoWru024075@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.81 -> 1.82 --- Log message: Fix a crash compiling 134.perl. --- Diffs of the changes: (+41 -21) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.81 llvm/lib/Target/X86/X86ISelPattern.cpp:1.82 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.81 Wed Jan 19 11:24:34 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Thu Jan 20 10:50:16 2005 @@ -490,6 +490,27 @@ return Result; } +/// NodeTransitivelyUsesValue - Return true if N or any of its uses uses Op. +/// The DAG cannot have cycles in it, by definition, so the visited set is not +/// needed to prevent infinite loops. The DAG CAN, however, have unbounded +/// reuse, so it prevents exponential cases. +/// +static bool NodeTransitivelyUsesValue(SDOperand N, SDOperand Op, + std::set &Visited) { + if (N == Op) return true; // Found it. + SDNode *Node = N.Val; + if (Node->getNumOperands() == 0) return false; // Leaf? + if (!Visited.insert(Node).second) return false; // Already visited? + + // Recurse for the first N-1 operands. + for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) + if (NodeTransitivelyUsesValue(Node->getOperand(i), Op, Visited)) + return true; + + // Tail recurse for the last operand. + return NodeTransitivelyUsesValue(Node->getOperand(0), Op, Visited); +} + X86AddressMode ISel::SelectAddrExprs(const X86ISelAddressMode &IAM) { X86AddressMode Result; @@ -497,13 +518,33 @@ // register pressure first. if (IAM.BaseType == X86ISelAddressMode::RegBase && IAM.Base.Reg.Val && IAM.IndexReg.Val) { + bool EmitBaseThenIndex; if (getRegPressure(IAM.Base.Reg) > getRegPressure(IAM.IndexReg)) { + std::set Visited; + EmitBaseThenIndex = true; + // If Base ends up pointing to Index, we must emit index first. This is + // because of the way we fold loads, we may end up doing bad things with + // the folded add. + if (NodeTransitivelyUsesValue(IAM.Base.Reg, IAM.IndexReg, Visited)) + EmitBaseThenIndex = false; + } else { + std::set Visited; + EmitBaseThenIndex = false; + // If Base ends up pointing to Index, we must emit index first. This is + // because of the way we fold loads, we may end up doing bad things with + // the folded add. + if (NodeTransitivelyUsesValue(IAM.IndexReg, IAM.Base.Reg, Visited)) + EmitBaseThenIndex = true; + } + + if (EmitBaseThenIndex) { Result.Base.Reg = SelectExpr(IAM.Base.Reg); Result.IndexReg = SelectExpr(IAM.IndexReg); } else { Result.IndexReg = SelectExpr(IAM.IndexReg); Result.Base.Reg = SelectExpr(IAM.Base.Reg); } + } else if (IAM.BaseType == X86ISelAddressMode::RegBase && IAM.Base.Reg.Val) { Result.Base.Reg = SelectExpr(IAM.Base.Reg); } else if (IAM.IndexReg.Val) { @@ -1070,27 +1111,6 @@ BuildMI(BB, Opc, 2).addReg(Tmp1).addReg(Tmp2); } -/// NodeTransitivelyUsesValue - Return true if N or any of its uses uses Op. -/// The DAG cannot have cycles in it, by definition, so the visited set is not -/// needed to prevent infinite loops. The DAG CAN, however, have unbounded -/// reuse, so it prevents exponential cases. -/// -static bool NodeTransitivelyUsesValue(SDOperand N, SDOperand Op, - std::set &Visited) { - if (N == Op) return true; // Found it. - SDNode *Node = N.Val; - if (Node->getNumOperands() == 0) return false; // Leaf? - if (!Visited.insert(Node).second) return false; // Already visited? - - // Recurse for the first N-1 operands. - for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) - if (NodeTransitivelyUsesValue(Node->getOperand(i), Op, Visited)) - return true; - - // Tail recurse for the last operand. - return NodeTransitivelyUsesValue(Node->getOperand(0), Op, Visited); -} - /// isFoldableLoad - Return true if this is a load instruction that can safely /// be folded into an operation that uses it. bool ISel::isFoldableLoad(SDOperand Op, SDOperand OtherOp) { From lattner at cs.uiuc.edu Thu Jan 20 11:32:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 11:32:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ValueTypes.cpp Message-ID: <200501201732.j0KHWf3T025066@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: ValueTypes.cpp updated: 1.1 -> 1.2 --- Log message: Add missing entry. --- Diffs of the changes: (+1 -0) Index: llvm/lib/CodeGen/ValueTypes.cpp diff -u llvm/lib/CodeGen/ValueTypes.cpp:1.1 llvm/lib/CodeGen/ValueTypes.cpp:1.2 --- llvm/lib/CodeGen/ValueTypes.cpp:1.1 Sat Jan 15 00:52:40 2005 +++ llvm/lib/CodeGen/ValueTypes.cpp Thu Jan 20 11:32:28 2005 @@ -30,6 +30,7 @@ case MVT::f64: return "f64"; case MVT::f80: return "f80"; case MVT::f128: return "f128"; + case MVT::isVoid:return "isVoid"; case MVT::Other: return "ch"; } } From lattner at cs.uiuc.edu Thu Jan 20 12:50:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 12:50:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200501201850.j0KIos6N028136@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.19 -> 1.20 --- Log message: Eliminate the unimplemented ADDC/SUBB operations, add ADD_PARTS/SUB_PARTS instead. --- Diffs of the changes: (+6 -4) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.19 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.20 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.19 Mon Jan 17 20:51:41 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Thu Jan 20 12:50:39 2005 @@ -101,10 +101,12 @@ // state. SETCC, - // addc - Three input, two output operator: (X, Y, C) -> (X+Y+C, - // Cout). X,Y are integer inputs of agreeing size, C is a one bit - // value, and two values are produced: the sum and a carry out. - ADDC, SUBB, + // ADD_PARTS/SUB_PARTS - These operators take two logical operands which are + // broken into a multiple pieces each, and return the resulting pieces of + // doing an atomic add/sub operation. This is used to handle add/sub of + // expanded types. The operation ordering is: + // [Lo,Hi] = op [LoLHS,HiLHS], [LoRHS,HiRHS] + ADD_PARTS, SUB_PARTS, // Conversion operators. These are all single input single output // operations. For all of these, the result type must be strictly From lattner at cs.uiuc.edu Thu Jan 20 12:51:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 12:51:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501201851.j0KIp9eu028251@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.43 -> 1.44 --- Log message: implement add_parts/sub_parts. --- Diffs of the changes: (+8 -3) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.43 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.44 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.43 Wed Jan 19 12:01:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Jan 20 12:50:55 2005 @@ -889,7 +889,12 @@ default: // FIXME: MEMOIZE!! SDNode *N = new SDNode(Opcode, Children); - N->setValueTypes(VT); + if (Opcode != ISD::ADD_PARTS && Opcode != ISD::SUB_PARTS) { + N->setValueTypes(VT); + } else { + std::vector V(N->getNumOperands()/2, VT); + N->setValueTypes(V); + } AllNodes.push_back(N); return SDOperand(N, 0); } @@ -1075,8 +1080,8 @@ case ISD::SRL: return "srl"; case ISD::SELECT: return "select"; - case ISD::ADDC: return "addc"; - case ISD::SUBB: return "subb"; + case ISD::ADD_PARTS: return "add_parts"; + case ISD::SUB_PARTS: return "sub_parts"; // Conversion operators. case ISD::SIGN_EXTEND: return "sign_extend"; From lattner at cs.uiuc.edu Thu Jan 20 12:52:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 12:52:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501201852.j0KIqhGT028784@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.47 -> 1.48 --- Log message: Expand add/sub into ADD_PARTS/SUB_PARTS instead of a non-existant libcall. --- Diffs of the changes: (+41 -2) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.47 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.48 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.47 Wed Jan 19 14:24:35 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Jan 20 12:52:28 2005 @@ -121,6 +121,8 @@ bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt, SDOperand &Lo, SDOperand &Hi); + void ExpandAddSub(bool isAdd, SDOperand Op, SDOperand Amt, + SDOperand &Lo, SDOperand &Hi); SDOperand getIntPtrConstant(uint64_t Val) { return DAG.getConstant(Val, TLI.getPointerTy()); @@ -753,6 +755,18 @@ } break; } + case ISD::ADD_PARTS: + case ISD::SUB_PARTS: { + std::vector Ops; + bool Changed = false; + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { + Ops.push_back(LegalizeOp(Node->getOperand(i))); + Changed |= Ops.back() != Node->getOperand(i); + } + if (Changed) + Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Ops); + break; + } case ISD::ADD: case ISD::SUB: case ISD::MUL: @@ -1183,6 +1197,27 @@ return Result; } +/// ExpandAddSub - Find a clever way to expand this add operation into +/// subcomponents. +void SelectionDAGLegalize::ExpandAddSub(bool isAdd, SDOperand LHS,SDOperand RHS, + SDOperand &Lo, SDOperand &Hi) { + // Expand the subcomponents. + SDOperand LHSL, LHSH, RHSL, RHSH; + ExpandOp(LHS, LHSL, LHSH); + ExpandOp(RHS, RHSL, RHSH); + + // Convert this add to the appropriate ADDC pair. The low part has no carry + // in. + unsigned Opc = isAdd ? ISD::ADD_PARTS : ISD::SUB_PARTS; + std::vector Ops; + Ops.push_back(LHSL); + Ops.push_back(LHSH); + Ops.push_back(RHSL); + Ops.push_back(RHSH); + Lo = DAG.getNode(Opc, LHSL.getValueType(), Ops); + Hi = Lo.getValue(1); +} + /// ExpandShift - Try to find a clever way to expand this shift operation out to /// smaller elements. If we can't find a way that is more efficient than a /// libcall on this target, return false. Otherwise, return true with the @@ -1444,8 +1479,12 @@ LibCallName = "__lshrdi3"; break; - case ISD::ADD: LibCallName = "__adddi3"; break; - case ISD::SUB: LibCallName = "__subdi3"; break; + case ISD::ADD: + ExpandAddSub(true, Node->getOperand(0), Node->getOperand(1), Lo, Hi); + break; + case ISD::SUB: + ExpandAddSub(false, Node->getOperand(0), Node->getOperand(1), Lo, Hi); + break; case ISD::MUL: LibCallName = "__muldi3"; break; case ISD::SDIV: LibCallName = "__divdi3"; break; case ISD::UDIV: LibCallName = "__udivdi3"; break; From lattner at cs.uiuc.edu Thu Jan 20 12:53:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 12:53:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501201853.j0KIrFF7028849@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.82 -> 1.83 --- Log message: Implement ADD_PARTS/SUB_PARTS so that 64-bit integer add/sub work. This fixes most of the remaining llc-beta failures. --- Diffs of the changes: (+32 -6) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.82 llvm/lib/Target/X86/X86ISelPattern.cpp:1.83 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.82 Thu Jan 20 10:50:16 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Thu Jan 20 12:53:00 2005 @@ -1303,20 +1303,28 @@ unsigned &Reg = ExprMap[N]; if (Reg) return Reg; - if (N.getOpcode() != ISD::CALL) + if (N.getOpcode() != ISD::CALL && N.getOpcode() != ISD::ADD_PARTS && + N.getOpcode() != ISD::SUB_PARTS) Reg = Result = (N.getValueType() != MVT::Other) ? MakeReg(N.getValueType()) : 1; else { // If this is a call instruction, make sure to prepare ALL of the result // values as well as the chain. - if (Node->getNumValues() == 1) - Reg = Result = 1; // Void call, just a chain. - else { + if (N.getOpcode() == ISD::CALL) { + if (Node->getNumValues() == 1) + Reg = Result = 1; // Void call, just a chain. + else { + Result = MakeReg(Node->getValueType(0)); + ExprMap[N.getValue(0)] = Result; + for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i) + ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); + ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1; + } + } else { Result = MakeReg(Node->getValueType(0)); ExprMap[N.getValue(0)] = Result; - for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i) + for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i) ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); - ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1; } } @@ -1972,6 +1980,24 @@ } return Result; } + case ISD::ADD_PARTS: + case ISD::SUB_PARTS: { + assert(N.getNumOperands() == 4 && N.getValueType() == MVT::i32 && + "Not an i64 add/sub!"); + // Emit all of the operands. + std::vector InVals; + for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) + InVals.push_back(SelectExpr(N.getOperand(i))); + if (N.getOpcode() == ISD::ADD_PARTS) { + BuildMI(BB, X86::ADD32rr, 2, Result).addReg(InVals[0]).addReg(InVals[2]); + BuildMI(BB, X86::ADC32rr,2,Result+1).addReg(InVals[1]).addReg(InVals[3]); + } else { + BuildMI(BB, X86::SUB32rr, 2, Result).addReg(InVals[0]).addReg(InVals[2]); + BuildMI(BB, X86::SBB32rr, 2,Result+1).addReg(InVals[1]).addReg(InVals[3]); + } + return Result+N.ResNo; + } + case ISD::SELECT: if (getRegPressure(N.getOperand(1)) > getRegPressure(N.getOperand(2))) { Tmp2 = SelectExpr(N.getOperand(1)); From lattner at cs.uiuc.edu Thu Jan 20 13:12:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 13:12:24 -0600 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <200501201912.j0KJCOQX029921@apoc.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolAllocate.cpp updated: 1.96 -> 1.97 --- Log message: Minor bug fixes --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Thu Jan 20 13:17:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 13:17:32 -0600 Subject: [llvm-commits] CVS: poolalloc/Makefile.common.in Message-ID: <200501201917.j0KJHW9G031303@apoc.cs.uiuc.edu> Changes in directory poolalloc: Makefile.common.in updated: 1.5 -> 1.6 --- Log message: Upgrade to recent makefile changes. --- Diffs of the changes: (+2 -2) Index: poolalloc/Makefile.common.in diff -u poolalloc/Makefile.common.in:1.5 poolalloc/Makefile.common.in:1.6 --- poolalloc/Makefile.common.in:1.5 Tue Sep 30 11:31:24 2003 +++ poolalloc/Makefile.common.in Thu Jan 20 13:17:22 2005 @@ -17,9 +17,9 @@ # # Set the source root and source directory pathnames # -BUILD_SRC_DIR := $(subst //,/, at abs_top_srcdir@/$(patsubst $(BUILD_OBJ_ROOT)%,%,$(BUILD_OBJ_DIR))) +PROJ_SRC_DIR := $(subst //,/, at abs_top_srcdir@/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))) -BUILD_SRC_ROOT := $(subst //,/, at abs_top_srcdir@) +PROJ_SRC_ROOT := $(subst //,/, at abs_top_srcdir@) # # Include LLVM's Master Makefile. From lattner at cs.uiuc.edu Thu Jan 20 13:19:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 13:19:06 -0600 Subject: [llvm-commits] CVS: poolalloc/Makefile.common.in Message-ID: <200501201919.j0KJJ6Tf032415@apoc.cs.uiuc.edu> Changes in directory poolalloc: Makefile.common.in updated: 1.6 -> 1.7 --- Log message: More changes. --- Diffs of the changes: (+3 -10) Index: poolalloc/Makefile.common.in diff -u poolalloc/Makefile.common.in:1.6 poolalloc/Makefile.common.in:1.7 --- poolalloc/Makefile.common.in:1.6 Thu Jan 20 13:17:22 2005 +++ poolalloc/Makefile.common.in Thu Jan 20 13:18:55 2005 @@ -1,28 +1,21 @@ -# +PROJECT_NAME := poolalloc +PROJ_VERSION := 1.0 + # Set this variable to the top of the LLVM source tree. -# LLVM_SRC_ROOT = @LLVM_SRC@ -# # Set this variable to the top level directory where LLVM was built # (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config). -# LLVM_OBJ_ROOT = @LLVM_OBJ@ -# # Include LLVM's Master Makefile. -# include $(LLVM_OBJ_ROOT)/Makefile.config -# # Set the source root and source directory pathnames -# PROJ_SRC_DIR := $(subst //,/, at abs_top_srcdir@/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))) PROJ_SRC_ROOT := $(subst //,/, at abs_top_srcdir@) -# # Include LLVM's Master Makefile. -# include $(LLVM_SRC_ROOT)/Makefile.rules From lattner at cs.uiuc.edu Thu Jan 20 13:21:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 13:21:03 -0600 Subject: [llvm-commits] CVS: poolalloc/Makefile.common.in Message-ID: <200501201921.j0KJL3LB003490@apoc.cs.uiuc.edu> Changes in directory poolalloc: Makefile.common.in updated: 1.7 -> 1.8 --- Log message: Ugh, more changes. --- Diffs of the changes: (+4 -2) Index: poolalloc/Makefile.common.in diff -u poolalloc/Makefile.common.in:1.7 poolalloc/Makefile.common.in:1.8 --- poolalloc/Makefile.common.in:1.7 Thu Jan 20 13:18:55 2005 +++ poolalloc/Makefile.common.in Thu Jan 20 13:20:52 2005 @@ -9,13 +9,15 @@ LLVM_OBJ_ROOT = @LLVM_OBJ@ # Include LLVM's Master Makefile. -include $(LLVM_OBJ_ROOT)/Makefile.config +#include $(LLVM_OBJ_ROOT)/Makefile.config # Set the source root and source directory pathnames PROJ_SRC_DIR := $(subst //,/, at abs_top_srcdir@/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))) PROJ_SRC_ROOT := $(subst //,/, at abs_top_srcdir@) +PROJ_INSTALL_ROOT := @prefix@ + # Include LLVM's Master Makefile. -include $(LLVM_SRC_ROOT)/Makefile.rules +include $(LLVM_SRC_ROOT)/Makefile.common From lattner at cs.uiuc.edu Thu Jan 20 14:29:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 14:29:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501202029.j0KKTc6M005923@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.48 -> 1.49 --- Log message: Simplify the shift-expansion code. --- Diffs of the changes: (+7 -8) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.48 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.49 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.48 Thu Jan 20 12:52:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Jan 20 14:29:23 2005 @@ -1237,13 +1237,16 @@ SDOperand InL, InH; ExpandOp(Op, InL, InH); SDOperand ShAmt = LegalizeOp(Amt); - SDOperand OShAmt = ShAmt; // Unmasked shift amount. MVT::ValueType ShTy = ShAmt.getValueType(); unsigned NVTBits = MVT::getSizeInBits(NVT); SDOperand NAmt = DAG.getNode(ISD::SUB, ShTy, // NAmt = 32-ShAmt DAG.getConstant(NVTBits, ShTy), ShAmt); + // Compare the unmasked shift amount against 32. + SDOperand Cond = DAG.getSetCC(ISD::SETGE, TLI.getSetCCResultTy(), ShAmt, + DAG.getConstant(NVTBits, ShTy)); + if (TLI.getShiftAmountFlavor() != TargetLowering::Mask) { ShAmt = DAG.getNode(ISD::AND, ShTy, ShAmt, // ShAmt &= 31 DAG.getConstant(NVTBits-1, ShTy)); @@ -1255,10 +1258,8 @@ SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << Amt) | (Lo >> NAmt) DAG.getNode(ISD::SHL, NVT, InH, ShAmt), DAG.getNode(ISD::SRL, NVT, InL, NAmt)); - SDOperand T2 = DAG.getNode(ISD::SHL, NVT, InL, ShAmt); // T2 = Lo << Amt + SDOperand T2 = DAG.getNode(ISD::SHL, NVT, InL, ShAmt); // T2 = Lo << Amt&31 - SDOperand Cond = DAG.getSetCC(ISD::SETGE, TLI.getSetCCResultTy(), OShAmt, - DAG.getConstant(NVTBits, ShTy)); Hi = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1); Lo = DAG.getNode(ISD::SELECT, NVT, Cond, DAG.getConstant(0, NVT), T2); } else { @@ -1266,17 +1267,15 @@ DAG.getNode(ISD::SHL, NVT, InH, NAmt), DAG.getNode(ISD::SRL, NVT, InL, ShAmt)); bool isSign = Opc == ISD::SRA; - SDOperand T2 = DAG.getNode(Opc, NVT, InH, ShAmt); + SDOperand T2 = DAG.getNode(Opc, NVT, InH, ShAmt); // T2 = InH >> ShAmt&31 SDOperand HiPart; if (isSign) HiPart = DAG.getNode(Opc, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); else HiPart = DAG.getConstant(0, NVT); - SDOperand Cond = DAG.getSetCC(ISD::SETGE, TLI.getSetCCResultTy(), OShAmt, - DAG.getConstant(NVTBits, ShTy)); Lo = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1); - Hi = DAG.getNode(ISD::SELECT, NVT, Cond, HiPart,T2); + Hi = DAG.getNode(ISD::SELECT, NVT, Cond, HiPart, T2); } return true; } From lattner at cs.uiuc.edu Thu Jan 20 14:58:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 14:58:54 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2004-03-07-BitfieldCrash.c Message-ID: <200501202058.j0KKwsAa006615@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-03-07-BitfieldCrash.c (r1.5) removed --- Log message: Remove this test. This test is already in PR269: http://llvm.cs.uiuc.edu/PR269 , so it should be readded when the bug is fixed. --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Thu Jan 20 17:31:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 20 Jan 2005 17:31:51 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/FileUtilities.h Message-ID: <200501202331.j0KNVprF011253@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: FileUtilities.h updated: 1.27 -> 1.28 --- Log message: Apparently destroyFile() now throws an exception. Since this class is designed to be put on the stack, that's not cool. Catch and ignore the exception. --- Diffs of the changes: (+4 -2) Index: llvm/include/llvm/Support/FileUtilities.h diff -u llvm/include/llvm/Support/FileUtilities.h:1.27 llvm/include/llvm/Support/FileUtilities.h:1.28 --- llvm/include/llvm/Support/FileUtilities.h:1.27 Wed Dec 22 04:24:43 2004 +++ llvm/include/llvm/Support/FileUtilities.h Thu Jan 20 17:31:35 2005 @@ -46,8 +46,10 @@ : Filename(filename), DeleteIt(deleteIt) {} ~FileRemover() { - if (DeleteIt) - Filename.destroyFile(); + if (DeleteIt) + try { + Filename.destroyFile(); + } catch (...) {} // Ignore problems deleting the file. } /// releaseFile - Take ownership of the file away from the FileRemover so it From lattner at cs.uiuc.edu Fri Jan 21 00:05:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 00:05:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501210605.j0L65cb1022699@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.49 -> 1.50 --- Log message: Refactor libcall code a bit. Initial implementation of expanding int -> FP operations for 64-bit integers. --- Diffs of the changes: (+121 -50) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.49 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.50 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.49 Thu Jan 20 14:29:23 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Jan 21 00:05:23 2005 @@ -119,6 +119,10 @@ void ExpandOp(SDOperand O, SDOperand &Lo, SDOperand &Hi); SDOperand PromoteOp(SDOperand O); + SDOperand ExpandLibCall(const char *Name, SDNode *Node, + SDOperand &Hi); + SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, + SDOperand Source); bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt, SDOperand &Lo, SDOperand &Hi); void ExpandAddSub(bool isAdd, SDOperand Op, SDOperand Amt, @@ -802,10 +806,13 @@ Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1); break; case Expand: - assert(Node->getOpcode() != ISD::SINT_TO_FP && - Node->getOpcode() != ISD::UINT_TO_FP && - "Cannot lower Xint_to_fp to a call yet!"); - + if (Node->getOpcode() == ISD::SINT_TO_FP || + Node->getOpcode() == ISD::UINT_TO_FP) { + Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, + Node->getValueType(0), Node->getOperand(0)); + Result = LegalizeOp(Result); + break; + } // In the expand case, we must be dealing with a truncate, because // otherwise the result would be larger than the source. assert(Node->getOpcode() == ISD::TRUNCATE && @@ -1043,6 +1050,8 @@ switch (getTypeAction(Node->getOperand(0).getValueType())) { case Legal: Result = LegalizeOp(Node->getOperand(0)); + // No extra round required here. + Result = DAG.getNode(Node->getOpcode(), NVT, Result); break; case Promote: @@ -1053,12 +1062,19 @@ else Result = DAG.getNode(ISD::ZERO_EXTEND_INREG, Result.getValueType(), Result, Node->getOperand(0).getValueType()); + // No extra round required here. + Result = DAG.getNode(Node->getOpcode(), NVT, Result); break; case Expand: - assert(0 && "Unimplemented"); + Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, NVT, + Node->getOperand(0)); + Result = LegalizeOp(Result); + + // Round if we cannot tolerate excess precision. + if (NoExcessFPPrecision) + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT); + break; } - // No extra round required here. - Result = DAG.getNode(Node->getOpcode(), NVT, Result); break; case ISD::FP_TO_SINT: @@ -1263,15 +1279,21 @@ Hi = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1); Lo = DAG.getNode(ISD::SELECT, NVT, Cond, DAG.getConstant(0, NVT), T2); } else { + SDOperand HiLoPart = DAG.getNode(ISD::SELECT, NVT, + DAG.getSetCC(ISD::SETEQ, + TLI.getSetCCResultTy(), NAmt, + DAG.getConstant(32, ShTy)), + DAG.getConstant(0, NVT), + DAG.getNode(ISD::SHL, NVT, InH, NAmt)); SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << NAmt) | (Lo >> Amt) - DAG.getNode(ISD::SHL, NVT, InH, NAmt), + HiLoPart, DAG.getNode(ISD::SRL, NVT, InL, ShAmt)); - bool isSign = Opc == ISD::SRA; SDOperand T2 = DAG.getNode(Opc, NVT, InH, ShAmt); // T2 = InH >> ShAmt&31 SDOperand HiPart; - if (isSign) - HiPart = DAG.getNode(Opc, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); + if (Opc == ISD::SRA) + HiPart = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(NVTBits-1, ShTy)); else HiPart = DAG.getConstant(0, NVT); Lo = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1); @@ -1279,7 +1301,79 @@ } return true; } - + + +// ExpandLibCall - Expand a node into a call to a libcall. If the result value +// does not fit into a register, return the lo part and set the hi part to the +// by-reg argument. If it does fit into a single register, return the result +// and leave the Hi part unset. +SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node, + SDOperand &Hi) { + TargetLowering::ArgListTy Args; + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { + MVT::ValueType ArgVT = Node->getOperand(i).getValueType(); + const Type *ArgTy = MVT::getTypeForValueType(ArgVT); + Args.push_back(std::make_pair(Node->getOperand(i), ArgTy)); + } + SDOperand Callee = DAG.getExternalSymbol(Name, TLI.getPointerTy()); + + // We don't care about token chains for libcalls. We just use the entry + // node as our input and ignore the output chain. This allows us to place + // calls wherever we need them to satisfy data dependences. + const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0)); + SDOperand Result = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, Callee, + Args, DAG).first; + switch (getTypeAction(Result.getValueType())) { + default: assert(0 && "Unknown thing"); + case Legal: + return Result; + case Promote: + assert(0 && "Cannot promote this yet!"); + case Expand: + SDOperand Lo; + ExpandOp(Result, Lo, Hi); + return Lo; + } +} + +/// ExpandIntToFP - Expand a [US]INT_TO_FP operation, assuming that the +/// destination type is legal. +SDOperand SelectionDAGLegalize:: +ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { + assert(getTypeAction(DestTy) == Legal && "Destination type is not legal!"); + assert(getTypeAction(Source.getValueType()) == Expand && + "This is not an expansion!"); + assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); + + const char *FnName; + if (isSigned) { + if (DestTy == MVT::f32) + FnName = "__floatdisf"; + else { + assert(DestTy == MVT::f64 && "Unknown fp value type!"); + FnName = "__floatdidf"; + } + } else { + // If this is unsigned, and not supported, first perform the conversion to + // signed, then adjust the result if the sign bit is set. + SDOperand SignedConv = ExpandIntToFP(false, DestTy, Source); + + assert(0 && "Unsigned casts not supported yet!"); + } + SDOperand Callee = DAG.getExternalSymbol(FnName, TLI.getPointerTy()); + + TargetLowering::ArgListTy Args; + const Type *ArgTy = MVT::getTypeForValueType(Source.getValueType()); + Args.push_back(std::make_pair(Source, ArgTy)); + + // We don't care about token chains for libcalls. We just use the entry + // node as our input and ignore the output chain. This allows us to place + // calls wherever we need them to satisfy data dependences. + const Type *RetTy = MVT::getTypeForValueType(DestTy); + return TLI.LowerCallTo(DAG.getEntryNode(), RetTy, Callee, + Args, DAG).first; +} + /// ExpandOp - Expand the specified SDOperand into its two component pieces @@ -1313,7 +1407,6 @@ // is not careful to avoid operations the target does not support. Make sure // that all generated operations are legalized in the next iteration. NeedsAnotherIteration = true; - const char *LibCallName = 0; switch (Node->getOpcode()) { default: @@ -1441,41 +1534,38 @@ // library functions. case ISD::FP_TO_SINT: if (Node->getOperand(0).getValueType() == MVT::f32) - LibCallName = "__fixsfdi"; + Lo = ExpandLibCall("__fixsfdi", Node, Hi); else - LibCallName = "__fixdfdi"; + Lo = ExpandLibCall("__fixdfdi", Node, Hi); break; case ISD::FP_TO_UINT: if (Node->getOperand(0).getValueType() == MVT::f32) - LibCallName = "__fixunssfdi"; + Lo = ExpandLibCall("__fixunssfdi", Node, Hi); else - LibCallName = "__fixunsdfdi"; + Lo = ExpandLibCall("__fixunsdfdi", Node, Hi); break; case ISD::SHL: // If we can emit an efficient shift operation, do so now. - if (ExpandShift(ISD::SHL, Node->getOperand(0), Node->getOperand(1), - Lo, Hi)) + if (ExpandShift(ISD::SHL, Node->getOperand(0), Node->getOperand(1), Lo, Hi)) break; // Otherwise, emit a libcall. - LibCallName = "__ashldi3"; + Lo = ExpandLibCall("__ashldi3", Node, Hi); break; case ISD::SRA: // If we can emit an efficient shift operation, do so now. - if (ExpandShift(ISD::SRA, Node->getOperand(0), Node->getOperand(1), - Lo, Hi)) + if (ExpandShift(ISD::SRA, Node->getOperand(0), Node->getOperand(1), Lo, Hi)) break; // Otherwise, emit a libcall. - LibCallName = "__ashrdi3"; + Lo = ExpandLibCall("__ashrdi3", Node, Hi); break; case ISD::SRL: // If we can emit an efficient shift operation, do so now. - if (ExpandShift(ISD::SRL, Node->getOperand(0), Node->getOperand(1), - Lo, Hi)) + if (ExpandShift(ISD::SRL, Node->getOperand(0), Node->getOperand(1), Lo, Hi)) break; // Otherwise, emit a libcall. - LibCallName = "__lshrdi3"; + Lo = ExpandLibCall("__lshrdi3", Node, Hi); break; case ISD::ADD: @@ -1484,30 +1574,11 @@ case ISD::SUB: ExpandAddSub(false, Node->getOperand(0), Node->getOperand(1), Lo, Hi); break; - case ISD::MUL: LibCallName = "__muldi3"; break; - case ISD::SDIV: LibCallName = "__divdi3"; break; - case ISD::UDIV: LibCallName = "__udivdi3"; break; - case ISD::SREM: LibCallName = "__moddi3"; break; - case ISD::UREM: LibCallName = "__umoddi3"; break; - } - - // Int2FP -> __floatdisf/__floatdidf - - // If this is to be expanded into a libcall... do so now. - if (LibCallName) { - TargetLowering::ArgListTy Args; - for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) - Args.push_back(std::make_pair(Node->getOperand(i), - MVT::getTypeForValueType(Node->getOperand(i).getValueType()))); - SDOperand Callee = DAG.getExternalSymbol(LibCallName, TLI.getPointerTy()); - - // We don't care about token chains for libcalls. We just use the entry - // node as our input and ignore the output chain. This allows us to place - // calls wherever we need them to satisfy data dependences. - SDOperand Result = TLI.LowerCallTo(DAG.getEntryNode(), - MVT::getTypeForValueType(Op.getValueType()), Callee, - Args, DAG).first; - ExpandOp(Result, Lo, Hi); + case ISD::MUL: Lo = ExpandLibCall("__muldi3" , Node, Hi); break; + case ISD::SDIV: Lo = ExpandLibCall("__divdi3" , Node, Hi); break; + case ISD::UDIV: Lo = ExpandLibCall("__udivdi3", Node, Hi); break; + case ISD::SREM: Lo = ExpandLibCall("__moddi3" , Node, Hi); break; + case ISD::UREM: Lo = ExpandLibCall("__umoddi3", Node, Hi); break; } // Remember in a map if the values will be reused later. From alkis at cs.uiuc.edu Fri Jan 21 05:41:49 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 21 Jan 2005 05:41:49 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Locals.h Message-ID: <200501211141.FAA08470@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Locals.h updated: 1.2 -> 1.3 --- Log message: Update javadoc. --- Diffs of the changes: (+3 -3) Index: llvm-java/lib/Compiler/Locals.h diff -u llvm-java/lib/Compiler/Locals.h:1.2 llvm-java/lib/Compiler/Locals.h:1.3 --- llvm-java/lib/Compiler/Locals.h:1.2 Mon Jan 17 17:00:04 2005 +++ llvm-java/lib/Compiler/Locals.h Fri Jan 21 05:41:38 2005 @@ -42,9 +42,9 @@ /// insertAtEnd BasicBlock void store(unsigned i, Value* value, BasicBlock* insertAtEnd); - /// @brief - Loads the value of the \c i'th local variable and - /// appends any instructions to implement this to \c insertAtEnd - /// BasicBlock + /// @brief - Loads the value of the \c i'th local variable of type + /// \c type and appends any instructions to implement this to \c + /// insertAtEnd BasicBlock Value* load(unsigned i, const Type* type, BasicBlock* insertAtEnd); }; From alkis at cs.uiuc.edu Fri Jan 21 07:53:38 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 21 Jan 2005 07:53:38 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Support.h OperandStack.cpp Locals.cpp Compiler.cpp Message-ID: <200501211353.HAA23137@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Support.h added (r1.1) OperandStack.cpp updated: 1.7 -> 1.8 Locals.cpp updated: 1.6 -> 1.7 Compiler.cpp updated: 1.185 -> 1.186 --- Log message: Pull some common functions in Support.h. --- Diffs of the changes: (+75 -53) Index: llvm-java/lib/Compiler/Support.h diff -c /dev/null llvm-java/lib/Compiler/Support.h:1.1 *** /dev/null Fri Jan 21 07:53:37 2005 --- llvm-java/lib/Compiler/Support.h Fri Jan 21 07:53:27 2005 *************** *** 0 **** --- 1,44 ---- + //===-- Support.h - Support functions ---------------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains support functions for the compiler. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_JAVA_SUPPORT_H + #define LLVM_JAVA_SUPPORT_H + + #include + #include + + namespace llvm { namespace Java { + + inline const Type* getStorageType(const Type* type) { + if (isa(type)) + return ObjectBaseRefTy; + else if (type == Type::BoolTy || + type == Type::SByteTy || + type == Type::UShortTy || + type == Type::ShortTy) + return Type::IntTy; + else + return type; + } + + inline bool isTwoSlotType(const Type* type) { + return type == Type::LongTy || type == Type::DoubleTy; + } + + inline bool isOneSlotType(const Type* type) { + return !isTwoSlotType(type); + } + + } } // namespace llvm::Java + + #endif//LLVM_JAVA_SUPPORT_H Index: llvm-java/lib/Compiler/OperandStack.cpp diff -u llvm-java/lib/Compiler/OperandStack.cpp:1.7 llvm-java/lib/Compiler/OperandStack.cpp:1.8 --- llvm-java/lib/Compiler/OperandStack.cpp:1.7 Mon Jan 17 12:21:03 2005 +++ llvm-java/lib/Compiler/OperandStack.cpp Fri Jan 21 07:53:27 2005 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "OperandStack.h" +#include "Support.h" #include #include #include @@ -27,33 +28,24 @@ assert(currentDepth < TheStack.size() && "Pushing to a full stack!"); const Type* valueTy = value->getType(); - // All pointer types are cast to a pointer to - // llvm_java_lang_object_base. - if (isa(valueTy)) - value = new CastInst(value, ObjectBaseRefTy, - "to-object-base", insertAtEnd); - // Values of jboolean, jbyte, jchar and jshort are extended to a - // jint when pushed on the operand stack. - else if (valueTy == Type::BoolTy || - valueTy == Type::SByteTy || - valueTy == Type::UShortTy || - valueTy == Type::ShortTy) - value = new CastInst(value, Type::IntTy, "int-extend", insertAtEnd); + const Type* storageTy = getStorageType(valueTy); + if (valueTy != storageTy) + value = new CastInst(value, storageTy, "to-storage-type", insertAtEnd); // If we don't have an alloca already for this slot create one if (!TheStack[currentDepth] || - TheStack[currentDepth]->getAllocatedType() != value->getType()) { + TheStack[currentDepth]->getAllocatedType() != storageTy) { // Insert the alloca at the beginning of the entry block. BasicBlock* entry = &insertAtEnd->getParent()->getEntryBlock(); if (entry->empty()) TheStack[currentDepth] = - new AllocaInst(value->getType(), + new AllocaInst(storageTy, NULL, "opStack" + utostr(currentDepth), entry); else TheStack[currentDepth] = - new AllocaInst(value->getType(), + new AllocaInst(storageTy, NULL, "opStack" + utostr(currentDepth), &entry->front()); Index: llvm-java/lib/Compiler/Locals.cpp diff -u llvm-java/lib/Compiler/Locals.cpp:1.6 llvm-java/lib/Compiler/Locals.cpp:1.7 --- llvm-java/lib/Compiler/Locals.cpp:1.6 Mon Jan 17 17:00:04 2005 +++ llvm-java/lib/Compiler/Locals.cpp Fri Jan 21 07:53:27 2005 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "Locals.h" +#include "Support.h" #include #include #include @@ -31,52 +32,44 @@ void Locals::store(unsigned i, Value* value, BasicBlock* insertAtEnd) { const Type* valueTy = value->getType(); - // All pointer types are cast to a pointer to - // llvm_java_lang_object_base. - if (isa(valueTy)) - value = new CastInst(value, ObjectBaseRefTy, - "to-object-base", insertAtEnd); - - // Values of jboolean, jbyte, jchar and jshort are extended to a - // jint when stored in a local slot. - else if (valueTy == Type::BoolTy || - valueTy == Type::SByteTy || - valueTy == Type::UShortTy || - valueTy == Type::ShortTy) - value = new CastInst(value, Type::IntTy, "int-extend", insertAtEnd); - - valueTy = value->getType(); + const Type* storageTy = getStorageType(valueTy); + if (valueTy != storageTy) + value = new CastInst(value, storageTy, "to-storage-type", insertAtEnd); SlotMap& slotMap = TheLocals[i]; - SlotMap::iterator it = slotMap.find(valueTy); + SlotMap::iterator it = slotMap.find(storageTy); if (it == slotMap.end()) { // Insert the alloca at the beginning of the entry block. BasicBlock* entry = &insertAtEnd->getParent()->getEntryBlock(); AllocaInst* alloca; if (entry->empty()) - alloca = new AllocaInst( - value->getType(), - NULL, - "local" + utostr(i), - entry); + alloca = new AllocaInst(storageTy, + NULL, + "local" + utostr(i), + entry); else - alloca = new AllocaInst( - value->getType(), - NULL, - "local" + utostr(i), - &entry->front()); - it = slotMap.insert(it, std::make_pair(valueTy, alloca)); + alloca = new AllocaInst(storageTy, + NULL, + "local" + utostr(i), + &entry->front()); + it = slotMap.insert(it, std::make_pair(storageTy, alloca)); } new StoreInst(value, it->second, insertAtEnd); } -llvm::Value* Locals::load(unsigned i, const Type* type, BasicBlock* insertAtEnd) +llvm::Value* Locals::load(unsigned i, const Type* valueTy, + BasicBlock* insertAtEnd) { + const Type* storageTy = getStorageType(valueTy); + SlotMap& slotMap = TheLocals[i]; - SlotMap::iterator it = slotMap.find(type); + SlotMap::iterator it = slotMap.find(storageTy); assert(it != slotMap.end() && "Attempt to load a non initialized global!"); - return new LoadInst(it->second, "load", insertAtEnd); + Value* value = new LoadInst(it->second, "load", insertAtEnd); + if (valueTy != storageTy) + value = new CastInst(value, valueTy, "from-storage-type", insertAtEnd); + return value; } Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.185 llvm-java/lib/Compiler/Compiler.cpp:1.186 --- llvm-java/lib/Compiler/Compiler.cpp:1.185 Mon Jan 17 17:00:04 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Jan 21 07:53:27 2005 @@ -17,6 +17,7 @@ #include "BasicBlockBuilder.h" #include "Locals.h" #include "OperandStack.h" +#include "Support.h" #include #include #include @@ -55,18 +56,10 @@ const std::string TMP("tmp"); - inline bool isTwoSlotType(const Type* t) { - return t == Type::LongTy | t == Type::DoubleTy; - } - inline bool isTwoSlotValue(const Value* v) { return isTwoSlotType(v->getType()); } - inline bool isOneSlotType(const Type* t) { - return !isTwoSlotType(t); - } - inline bool isOneSlotValue(const Value* v) { return isOneSlotType(v->getType()); } From lattner at cs.uiuc.edu Fri Jan 21 12:01:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 12:01:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501211801.j0LI1c8X024827@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.44 -> 1.45 --- Log message: Unary token factor nodes are unneeded. --- Diffs of the changes: (+2 -0) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.44 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.45 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.44 Thu Jan 20 12:50:55 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jan 21 12:01:22 2005 @@ -511,6 +511,8 @@ unsigned OpOpcode = Operand.Val->getOpcode(); switch (Opcode) { + case ISD::TokenFactor: + return Operand; // Factor of one node? No factor. case ISD::SIGN_EXTEND: if (Operand.getValueType() == VT) return Operand; // noop extension if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) From lattner at cs.uiuc.edu Fri Jan 21 13:46:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 13:46:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501211946.j0LJksih026503@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.83 -> 1.84 --- Log message: Fix a FIXME: realize that argument stores are all independent (don't alias) --- Diffs of the changes: (+7 -6) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.83 llvm/lib/Target/X86/X86ISelPattern.cpp:1.84 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.83 Thu Jan 20 12:53:00 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Jan 21 13:46:38 2005 @@ -196,6 +196,8 @@ unsigned ArgOffset = 0; SDOperand StackPtr = DAG.getCopyFromReg(X86::ESP, MVT::i32, DAG.getEntryNode()); + std::vector Stores; + for (unsigned i = 0, e = Args.size(); i != e; ++i) { unsigned ArgReg; SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); @@ -216,20 +218,19 @@ // FALL THROUGH case MVT::i32: case MVT::f32: - // FIXME: Note that all of these stores are independent of each other. - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); ArgOffset += 4; break; case MVT::i64: case MVT::f64: - // FIXME: Note that all of these stores are independent of each other. - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); ArgOffset += 8; break; } } + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); } std::vector RetVals; From lattner at cs.uiuc.edu Fri Jan 21 13:59:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 13:59:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Message-ID: <200501211959.j0LJxp93027020@apoc.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: ExternalFunctions.cpp updated: 1.82 -> 1.83 --- Log message: If the interpreter tries to execute an external function, kill it. Of course since we are dirty, special case __main. This should fix the infinite loop horrible stuff that happens on linux-alpha when configuring llvm-gcc. It might also help cygwin, who knows?? --- Diffs of the changes: (+8 -6) Index: llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.82 llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.83 --- llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.82 Sat Jan 15 19:31:31 2005 +++ llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Fri Jan 21 13:59:37 2005 @@ -82,22 +82,24 @@ return FnPtr; } -GenericValue Interpreter::callExternalFunction(Function *M, +GenericValue Interpreter::callExternalFunction(Function *F, const std::vector &ArgVals) { TheInterpreter = this; // Do a lookup to see if the function is in our cache... this should just be a // deferred annotation! - std::map::iterator FI = Functions.find(M); - ExFunc Fn = (FI == Functions.end()) ? lookupFunction(M) : FI->second; + std::map::iterator FI = Functions.find(F); + ExFunc Fn = (FI == Functions.end()) ? lookupFunction(F) : FI->second; if (Fn == 0) { std::cout << "Tried to execute an unknown external function: " - << M->getType()->getDescription() << " " << M->getName() << "\n"; - return GenericValue(); + << F->getType()->getDescription() << " " << F->getName() << "\n"; + if (F->getName() == "__main") + return GenericValue(); + abort(); } // TODO: FIXME when types are not const! - GenericValue Result = Fn(const_cast(M->getFunctionType()), + GenericValue Result = Fn(const_cast(F->getFunctionType()), ArgVals); return Result; } From reid at x10sys.com Fri Jan 21 14:34:10 2005 From: reid at x10sys.com (Reid Spencer) Date: Fri, 21 Jan 2005 14:34:10 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.rules Makefile.tests Message-ID: <200501212034.OAA26829@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.rules updated: 1.6 -> 1.7 Makefile.tests updated: 1.3 -> 1.4 --- Log message: Quote the value of PATH= lines so that platforms with spaces in their paths can build without failure. --- Diffs of the changes: (+3 -3) Index: llvm-test/Makefile.rules diff -u llvm-test/Makefile.rules:1.6 llvm-test/Makefile.rules:1.7 --- llvm-test/Makefile.rules:1.6 Sat Jan 15 21:16:09 2005 +++ llvm-test/Makefile.rules Fri Jan 21 14:34:00 2005 @@ -252,8 +252,8 @@ #-------------------------------------------------------------------------- # The LLVM GCC front-end in C and C++ flavors # -LLVMGCC := PATH=$(LLVMTOOLCURRENT):$(PATH) $(LLVMGCCDIR)/bin/llvm-gcc -LLVMGXX := PATH=$(LLVMTOOLCURRENT):$(PATH) $(LLVMGCCDIR)/bin/llvm-g++ +LLVMGCC := PATH="$(LLVMTOOLCURRENT):$(PATH)" $(LLVMGCCDIR)/bin/llvm-gcc +LLVMGXX := PATH="$(LLVMTOOLCURRENT):$(PATH)" $(LLVMGCCDIR)/bin/llvm-g++ #-------------------------------------------------------------------------- # The compiled LLVM tools Index: llvm-test/Makefile.tests diff -u llvm-test/Makefile.tests:1.3 llvm-test/Makefile.tests:1.4 --- llvm-test/Makefile.tests:1.3 Wed Sep 1 09:33:16 2004 +++ llvm-test/Makefile.tests Fri Jan 21 14:34:00 2005 @@ -39,7 +39,7 @@ LLCFLAGS = FAILURE = $(LLVM_SRC_ROOT)/test/Failure.sh TESTRUNR = @echo Running test: $<; \ - PATH=$(LLVMTOOLCURRENT):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH) \ + PATH="$(LLVMTOOLCURRENT):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \ $(LLVM_SRC_ROOT)/test/TestRunner.sh LLCLIBS := $(LLCLIBS) -lm From lattner at cs.uiuc.edu Fri Jan 21 15:35:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 15:35:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501212135.j0LLZTPu028129@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.84 -> 1.85 --- Log message: The ever-important vanity pass name :) --- Diffs of the changes: (+4 -0) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.84 llvm/lib/Target/X86/X86ISelPattern.cpp:1.85 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.84 Fri Jan 21 13:46:38 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Jan 21 15:35:14 2005 @@ -358,6 +358,10 @@ ISel(TargetMachine &TM) : SelectionDAGISel(X86Lowering), X86Lowering(TM) { } + virtual const char *getPassName() const { + return "X86 Pattern Instruction Selection"; + } + unsigned getRegPressure(SDOperand O) { return RegPressureMap[O.Val]; } From lattner at cs.uiuc.edu Fri Jan 21 15:39:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 15:39:53 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200501212139.j0LLdrqL028433@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.20 -> 1.21 --- Log message: Keep track of node depth for each node --- Diffs of the changes: (+39 -6) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.20 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.21 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.20 Thu Jan 20 12:50:39 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Jan 21 15:39:38 2005 @@ -360,9 +360,10 @@ /// getValueType - Return the ValueType of the referenced return value. /// inline MVT::ValueType getValueType() const; - + // Forwarding methods - These forward to the corresponding methods in SDNode. inline unsigned getOpcode() const; + inline unsigned getNodeDepth() const; inline unsigned getNumOperands() const; inline const SDOperand &getOperand(unsigned i) const; @@ -391,7 +392,17 @@ /// SDNode - Represents one node in the SelectionDAG. /// class SDNode { - unsigned NodeType; + /// NodeType - The operation that this node performs. + /// + unsigned short NodeType; + + /// NodeDepth - Node depth is defined as MAX(Node depth of children)+1. This + /// means that leaves have a depth of 1, things that use only leaves have a + /// depth of 2, etc. + unsigned short NodeDepth; + + /// Operands - The values that are used by this operation. + /// std::vector Operands; /// Values - The types of the values this node defines. SDNode's may define @@ -412,6 +423,10 @@ bool use_empty() const { return Uses.empty(); } bool hasOneUse() const { return Uses.size() == 1; } + /// getNodeDepth - Return the distance from this node to the leaves in the + /// graph. The leaves have a depth of 1. + unsigned getNodeDepth() const { return NodeDepth; } + typedef std::vector::const_iterator use_iterator; use_iterator use_begin() const { return Uses.begin(); } use_iterator use_end() const { return Uses.end(); } @@ -457,23 +472,33 @@ protected: friend class SelectionDAG; - SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT) { + SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT), NodeDepth(1) { Values.reserve(1); Values.push_back(VT); } - SDNode(unsigned NT, SDOperand Op) - : NodeType(NT) { + : NodeType(NT), NodeDepth(Op.Val->getNodeDepth()+1) { Operands.reserve(1); Operands.push_back(Op); Op.Val->Uses.push_back(this); } SDNode(unsigned NT, SDOperand N1, SDOperand N2) : NodeType(NT) { + if (N1.Val->getNodeDepth() > N2.Val->getNodeDepth()) + NodeDepth = N1.Val->getNodeDepth()+1; + else + NodeDepth = N2.Val->getNodeDepth()+1; Operands.reserve(2); Operands.push_back(N1); Operands.push_back(N2); N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); } SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3) : NodeType(NT) { + unsigned ND = N1.Val->getNodeDepth(); + if (ND < N2.Val->getNodeDepth()) + ND = N2.Val->getNodeDepth(); + if (ND < N3.Val->getNodeDepth()) + ND = N3.Val->getNodeDepth(); + NodeDepth = ND+1; + Operands.reserve(3); Operands.push_back(N1); Operands.push_back(N2); Operands.push_back(N3); N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); @@ -481,8 +506,13 @@ } SDNode(unsigned NT, std::vector &Nodes) : NodeType(NT) { Operands.swap(Nodes); - for (unsigned i = 0, e = Operands.size(); i != e; ++i) + unsigned ND = 0; + for (unsigned i = 0, e = Operands.size(); i != e; ++i) { Operands[i].Val->Uses.push_back(this); + if (ND < Operands[i].Val->getNodeDepth()) + ND = Operands[i].Val->getNodeDepth(); + } + NodeDepth = ND+1; } virtual ~SDNode() { @@ -521,6 +551,9 @@ inline unsigned SDOperand::getOpcode() const { return Val->getOpcode(); } +inline unsigned SDOperand::getNodeDepth() const { + return Val->getNodeDepth(); +} inline MVT::ValueType SDOperand::getValueType() const { return Val->getValueType(ResNo); } From lattner at cs.uiuc.edu Fri Jan 21 15:43:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 15:43:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501212143.j0LLhHjt028790@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.85 -> 1.86 --- Log message: Speed up folding operations into loads. --- Diffs of the changes: (+2 -1) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.85 llvm/lib/Target/X86/X86ISelPattern.cpp:1.86 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.85 Fri Jan 21 15:35:14 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Jan 21 15:43:02 2005 @@ -504,7 +504,8 @@ std::set &Visited) { if (N == Op) return true; // Found it. SDNode *Node = N.Val; - if (Node->getNumOperands() == 0) return false; // Leaf? + if (Node->getNumOperands() == 0 || // Leaf? + Node->getNodeDepth() <= Op.getNodeDepth()) return false; // Can't find it? if (!Visited.insert(Node).second) return false; // Already visited? // Recurse for the first N-1 operands. From lattner at cs.uiuc.edu Fri Jan 21 17:07:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 17:07:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200501212307.j0LN74ow030799@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.308 -> 1.309 --- Log message: Handle comparisons of gep instructions that have different typed indices as long as they are the same size. --- Diffs of the changes: (+9 -5) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.308 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.309 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.308 Wed Jan 19 15:50:18 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 21 17:06:49 2005 @@ -2244,9 +2244,9 @@ unsigned DiffOperand = 0; // The operand that differs. for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i) if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) { - if (GEPLHS->getOperand(i)->getType() != - GEPRHS->getOperand(i)->getType()) { - // Irreconsilable differences. + if (GEPLHS->getOperand(i)->getType()->getPrimitiveSize() != + GEPRHS->getOperand(i)->getType()->getPrimitiveSize()) { + // Irreconcilable differences. NumDifferences = 2; break; } else { @@ -2259,8 +2259,12 @@ return ReplaceInstUsesWith(I, // No comparison is needed here. ConstantBool::get(Cond == Instruction::SetEQ)); else if (NumDifferences == 1) { - return new SetCondInst(Cond, GEPLHS->getOperand(DiffOperand), - GEPRHS->getOperand(DiffOperand)); + Value *LHSV = GEPLHS->getOperand(DiffOperand); + Value *RHSV = GEPRHS->getOperand(DiffOperand); + if (LHSV->getType() != RHSV->getType()) + LHSV = InsertNewInstBefore(new CastInst(LHSV, RHSV->getType(), + LHSV->getName()+".c"), I); + return new SetCondInst(Cond, LHSV, RHSV); } } From lattner at cs.uiuc.edu Fri Jan 21 17:39:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 17:39:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501212339.j0LNd9Yi031077@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.45 -> 1.46 --- Log message: test commit --- Diffs of the changes: (+1 -0) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.45 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.46 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.45 Fri Jan 21 12:01:22 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jan 21 17:38:56 2005 @@ -1231,3 +1231,4 @@ std::cerr << "\n\n"; } + SelectionDAG.cpp | 1 + 1 files changed, 1 insertion(+) From lattner at cs.uiuc.edu Fri Jan 21 17:43:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 17:43:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501212343.j0LNhOxu031100@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.46 -> 1.47 --- Log message: Remove unneeded line. --- Diffs of the changes: (+0 -1) SelectionDAG.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.46 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.47 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.46 Fri Jan 21 17:38:56 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jan 21 17:43:12 2005 @@ -1231,4 +1231,3 @@ std::cerr << "\n\n"; } - From lattner at cs.uiuc.edu Fri Jan 21 18:20:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 18:20:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501220020.j0M0KtD4032465@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.47 -> 1.48 --- Log message: Add a nasty hack to fix Alpha/IA64 multiplies by a power of two. --- Diffs of the changes: (+9 -4) SelectionDAG.cpp | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.47 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.48 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.47 Fri Jan 21 17:43:12 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jan 21 18:20:42 2005 @@ -446,6 +446,7 @@ else { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 + if (N2.getValueType() != MVT::i64) // FIXME: HACK HACK HACK! return getSetCC(Cond, VT, N1.getOperand(0), getNode(ISD::SHL, N2.getValueType(), N2, getConstant(1, MVT::i8))); @@ -654,8 +655,10 @@ // FIXME: This should only be done if the target supports shift // operations. if ((C2 & C2-1) == 0) { - SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); - return getNode(ISD::SHL, VT, N1, ShAmt); + if (N2.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! + SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); + return getNode(ISD::SHL, VT, N1, ShAmt); + } } break; @@ -663,8 +666,10 @@ // FIXME: This should only be done if the target supports shift // operations. if ((C2 & C2-1) == 0 && C2) { - SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); - return getNode(ISD::SRL, VT, N1, ShAmt); + if (N2.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! + SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); + return getNode(ISD::SRL, VT, N1, ShAmt); + } } break; From lattner at cs.uiuc.edu Fri Jan 21 18:32:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 18:32:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501220032.j0M0W761032763@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.50 -> 1.51 --- Log message: Fix problems with non-x86 targets. --- Diffs of the changes: (+3 -3) LegalizeDAG.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.50 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.51 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.50 Fri Jan 21 00:05:23 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Jan 21 18:31:52 2005 @@ -902,7 +902,7 @@ // SAR. However, it is doubtful that any exist. unsigned BitsDiff = MVT::getSizeInBits(Node->getValueType(0)) - MVT::getSizeInBits(ExtraVT); - SDOperand ShiftCst = DAG.getConstant(BitsDiff, MVT::i8); + SDOperand ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy()); Result = DAG.getNode(ISD::SHL, Node->getValueType(0), Node->getOperand(0), ShiftCst); Result = DAG.getNode(ISD::SRA, Node->getValueType(0), @@ -1302,7 +1302,6 @@ return true; } - // ExpandLibCall - Expand a node into a call to a libcall. If the result value // does not fit into a register, return the lo part and set the hi part to the // by-reg argument. If it does fit into a single register, return the result @@ -1518,7 +1517,8 @@ // The high part is obtained by SRA'ing all but one of the bits of the lo // part. unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1, MVT::i8)); + Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1, + TLI.getShiftAmountTy())); break; } case ISD::ZERO_EXTEND: From lattner at cs.uiuc.edu Fri Jan 21 18:33:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 18:33:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501220033.j0M0XG44000309@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.48 -> 1.49 --- Log message: More bugfixes for IA64 shifts. --- Diffs of the changes: (+2 -2) SelectionDAG.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.48 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.49 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.48 Fri Jan 21 18:20:42 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jan 21 18:33:03 2005 @@ -655,7 +655,7 @@ // FIXME: This should only be done if the target supports shift // operations. if ((C2 & C2-1) == 0) { - if (N2.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! + if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); return getNode(ISD::SHL, VT, N1, ShAmt); } @@ -666,7 +666,7 @@ // FIXME: This should only be done if the target supports shift // operations. if ((C2 & C2-1) == 0 && C2) { - if (N2.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! + if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); return getNode(ISD::SRL, VT, N1, ShAmt); } From alenhar2 at cs.uiuc.edu Fri Jan 21 18:35:37 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 21 Jan 2005 18:35:37 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501220035.SAA20994@niobe.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.9 -> 1.10 --- Log message: make double-dollar properly escape asmstrings --- Diffs of the changes: (+1 -0) AsmWriterEmitter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.9 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.10 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.9 Tue Oct 12 11:21:18 2004 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Fri Jan 21 18:35:22 2005 @@ -103,6 +103,7 @@ } else if (DollarPos+1 != AsmString.size() && AsmString[DollarPos+1] == '$') { O << " << '$'"; // "$$" -> $ + LastEmitted = DollarPos+2; } else { // Get the name of the variable. // TODO: should eventually handle ${foo}bar as $foo From lattner at cs.uiuc.edu Fri Jan 21 18:49:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 21 Jan 2005 18:49:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200501220049.j0M0nVFP001212@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.38 -> 1.39 --- Log message: Implicitly defined registers can clobber callee saved registers too! This fixes the return-address-not-being-saved problem in the Alpha backend. --- Diffs of the changes: (+6 -0) PrologEpilogInserter.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.38 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.39 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.38 Wed Jan 19 15:32:07 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Fri Jan 21 18:49:16 2005 @@ -96,6 +96,7 @@ 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(); @@ -133,6 +134,11 @@ "Register allocation must be performed!"); ModifiedRegs[MO.getReg()] = true; // Register is modified } + + // Mark any implicitly defined registers as being modified. + for (const unsigned *ImpDefs = TII.getImplicitDefs(I->getOpcode()); + *ImpDefs; ++ImpDefs) + ModifiedRegs[*ImpDefs] = true; } ++I; } From alkis at cs.uiuc.edu Fri Jan 21 19:30:23 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 21 Jan 2005 19:30:23 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Support.h OperandStack.h OperandStack.cpp Compiler.cpp Message-ID: <200501220130.TAA29404@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Support.h updated: 1.1 -> 1.2 OperandStack.h updated: 1.2 -> 1.3 OperandStack.cpp updated: 1.8 -> 1.9 Compiler.cpp updated: 1.186 -> 1.187 --- Log message: Change how the operand stack works. We now have only one operand stack per function (instead of one per basic block) and keep track of the operand stack depth at the beginning of each basic block. Furthermore, each operand stack slot keeps track of all the possible types of values it can hold. This fixes a problem with the previous approach where values originating from two (or more) different predecessors where not merged properly in the common successor block. --- Diffs of the changes: (+383 -337) Compiler.cpp | 512 +++++++++++++++++++++---------------------------------- OperandStack.cpp | 166 +++++++++++++++-- OperandStack.h | 36 +++ Support.h | 6 4 files changed, 383 insertions(+), 337 deletions(-) Index: llvm-java/lib/Compiler/Support.h diff -u llvm-java/lib/Compiler/Support.h:1.1 llvm-java/lib/Compiler/Support.h:1.2 --- llvm-java/lib/Compiler/Support.h:1.1 Fri Jan 21 07:53:27 2005 +++ llvm-java/lib/Compiler/Support.h Fri Jan 21 19:30:12 2005 @@ -23,10 +23,14 @@ if (isa(type)) return ObjectBaseRefTy; else if (type == Type::BoolTy || + type == Type::UByteTy || type == Type::SByteTy || type == Type::UShortTy || - type == Type::ShortTy) + type == Type::ShortTy || + type == Type::UIntTy) return Type::IntTy; + else if (type == Type::ULongTy) + return Type::LongTy; else return type; } Index: llvm-java/lib/Compiler/OperandStack.h diff -u llvm-java/lib/Compiler/OperandStack.h:1.2 llvm-java/lib/Compiler/OperandStack.h:1.3 --- llvm-java/lib/Compiler/OperandStack.h:1.2 Fri Dec 10 04:20:56 2004 +++ llvm-java/lib/Compiler/OperandStack.h Fri Jan 21 19:30:12 2005 @@ -18,7 +18,7 @@ #include #include #include - +#include #include namespace llvm { @@ -31,21 +31,45 @@ class OperandStack { unsigned currentDepth; - std::vector TheStack; + typedef std::map SlotMap; + std::vector TheStack; public: explicit OperandStack(unsigned maxDepth) : currentDepth(0), TheStack(maxDepth) { } + unsigned getDepth() const { return currentDepth; } + void setDepth(unsigned newDepth) { + assert(newDepth < TheStack.size() && + "Cannot set depth greater than the max depth!"); + currentDepth = newDepth; + } + /// @brief - Pushes the value \c value on the virtual operand /// stack and appends any instructions to implement this to \c /// insertAtEnd BasicBlock void push(Value* value, BasicBlock* insertAtEnd); - /// @brief - Pops a value from the virtual operand stack and - /// appends any instructions to implement this to \c insertAtEnd - /// BasicBlock - Value* pop(BasicBlock* insertAtEnd); + /// @brief - Pops a value of type \c type from the virtual operand + /// stack and appends any instructions to implement this to \c + /// insertAtEnd BasicBlock + Value* pop(const Type* type, BasicBlock* insertAtEnd); + + void do_pop(BasicBlock* insertAtEnd); + void do_pop2(BasicBlock* insertAtEnd); + void do_dup(BasicBlock* insertAtEnd); + void do_dup_x1(BasicBlock* insertAtEnd); + void do_dup_x2(BasicBlock* insertAtEnd); + void do_dup2(BasicBlock* insertAtEnd); + void do_dup2_x1(BasicBlock* insertAtEnd); + void do_dup2_x2(BasicBlock* insertAtEnd); + void do_swap(BasicBlock* insertAtEnd); + + private: + AllocaInst* getOrCreateSlot(SlotMap& slotMap, + const Type* type, + BasicBlock* bb); + void copySlots(const SlotMap& src, SlotMap& dst, BasicBlock* insertAtEnd); }; } } // namespace llvm::Java Index: llvm-java/lib/Compiler/OperandStack.cpp diff -u llvm-java/lib/Compiler/OperandStack.cpp:1.8 llvm-java/lib/Compiler/OperandStack.cpp:1.9 --- llvm-java/lib/Compiler/OperandStack.cpp:1.8 Fri Jan 21 07:53:27 2005 +++ llvm-java/lib/Compiler/OperandStack.cpp Fri Jan 21 19:30:12 2005 @@ -20,43 +20,165 @@ #include #include #include +#include using namespace llvm::Java; +void OperandStack::copySlots(const SlotMap& src, + SlotMap& dst, + BasicBlock* insertAtEnd) +{ + SlotMap::const_iterator it = src.begin(); + SlotMap::const_iterator end = src.end(); + + for (; it != end; ++it) { + AllocaInst* srcSlot = it->second; + AllocaInst* dstSlot = getOrCreateSlot(dst, it->first, insertAtEnd); + Value* value = new LoadInst(srcSlot, "tmp", insertAtEnd); + new StoreInst(value, dstSlot, insertAtEnd); + } +} + +llvm::AllocaInst* OperandStack::getOrCreateSlot(SlotMap& slotMap, + const Type* type, + BasicBlock* bb) +{ + SlotMap::iterator it = slotMap.find(type); + + if (it == slotMap.end()) { + // Insert the alloca at the beginning of the entry block. + BasicBlock* entry = &bb->getParent()->getEntryBlock(); + AllocaInst* alloca; + if (entry->empty()) + alloca = new AllocaInst(type, NULL, "opStack", entry); + else + alloca = new AllocaInst(type, NULL, "opStack", &entry->front()); + it = slotMap.insert(it, std::make_pair(type, alloca)); + } + + return it->second; +} + void OperandStack::push(Value* value, BasicBlock* insertAtEnd) { assert(currentDepth < TheStack.size() && "Pushing to a full stack!"); - const Type* valueTy = value->getType(); +// std::cerr << "PUSH(" << insertAtEnd << "/" +// << insertAtEnd->getParent()->getName() << " " << TheStack.size() +// << ") Depth: " << currentDepth << " type: " << *valueTy << '\n'; const Type* storageTy = getStorageType(valueTy); if (valueTy != storageTy) value = new CastInst(value, storageTy, "to-storage-type", insertAtEnd); - // If we don't have an alloca already for this slot create one - if (!TheStack[currentDepth] || - TheStack[currentDepth]->getAllocatedType() != storageTy) { - // Insert the alloca at the beginning of the entry block. - BasicBlock* entry = &insertAtEnd->getParent()->getEntryBlock(); - if (entry->empty()) - TheStack[currentDepth] = - new AllocaInst(storageTy, - NULL, - "opStack" + utostr(currentDepth), - entry); - else - TheStack[currentDepth] = - new AllocaInst(storageTy, - NULL, - "opStack" + utostr(currentDepth), - &entry->front()); - } + SlotMap& slotMap = TheStack[currentDepth]; + AllocaInst* slot = getOrCreateSlot(slotMap, storageTy, insertAtEnd); + new StoreInst(value, slot, insertAtEnd); + currentDepth += 1 + isTwoSlotType(storageTy); + assert(currentDepth < TheStack.size() && "Pushed more than max stack depth!"); +} + +llvm::Value* OperandStack::pop(const Type* valueTy, BasicBlock* insertAtEnd) +{ + const Type* storageTy = getStorageType(valueTy); + + assert(currentDepth != 0 && "Popping from an empty stack!"); + currentDepth -= 1 + isTwoSlotType(storageTy); +// std::cerr << "POP(" << insertAtEnd->getName() << "/" +// << insertAtEnd->getParent()->getName() << " " << TheStack.size() +// << ") Depth: " << currentDepth << " type: " << *valueTy << '\n'; + + SlotMap& slotMap = TheStack[currentDepth]; + SlotMap::iterator it = slotMap.find(storageTy); - new StoreInst(value, TheStack[currentDepth++], insertAtEnd); + assert(it != slotMap.end() && "Type mismatch on operand stack!"); + Value* value = new LoadInst(it->second, "pop", insertAtEnd); + if (valueTy != storageTy) + value = new CastInst(value, valueTy, "from-storage-type", insertAtEnd); + return value; } -llvm::Value* OperandStack::pop(BasicBlock* insertAtEnd) +/// ..., value -> ... +void OperandStack::do_pop(BasicBlock* insertAtEnd) { assert(currentDepth != 0 && "Popping from an empty stack!"); + --currentDepth; +} - return new LoadInst(TheStack[--currentDepth], "pop", insertAtEnd); +/// ..., value2, value1 -> ... +/// ..., value -> ... +void OperandStack::do_pop2(BasicBlock* insertAtEnd) +{ + do_pop(insertAtEnd); + do_pop(insertAtEnd); +} + +/// ..., value -> ..., value, value +void OperandStack::do_dup(BasicBlock* insertAtEnd) +{ + assert(currentDepth != 0 && "Popping from an empty stack!"); + copySlots(TheStack[currentDepth-1], TheStack[currentDepth], insertAtEnd); + ++currentDepth; +} + +/// ..., value2, value1 -> ..., value1, value2, value1 +void OperandStack::do_dup_x1(BasicBlock* insertAtEnd) +{ + copySlots(TheStack[currentDepth-1], TheStack[currentDepth], insertAtEnd); + copySlots(TheStack[currentDepth-2], TheStack[currentDepth-1], insertAtEnd); + copySlots(TheStack[currentDepth], TheStack[currentDepth-2], insertAtEnd); + ++currentDepth; +} + +/// ..., value3, value2, value1 -> ..., value1, value3, value2, value1 +/// ..., value2, value1 -> ..., value1, value2, value1 +void OperandStack::do_dup_x2(BasicBlock* insertAtEnd) +{ + copySlots(TheStack[currentDepth-1], TheStack[currentDepth], insertAtEnd); + copySlots(TheStack[currentDepth-2], TheStack[currentDepth-1], insertAtEnd); + copySlots(TheStack[currentDepth-3], TheStack[currentDepth-2], insertAtEnd); + copySlots(TheStack[currentDepth], TheStack[currentDepth-3], insertAtEnd); + ++currentDepth; +} + +/// ..., value2, value1 -> ..., value2, value1, value2, value1 +void OperandStack::do_dup2(BasicBlock* insertAtEnd) +{ + copySlots(TheStack[currentDepth-2], TheStack[currentDepth], insertAtEnd); + copySlots(TheStack[currentDepth-1], TheStack[currentDepth+1], insertAtEnd); + currentDepth += 2; +} + +/// ..., value3, value2, value1 -> ..., value2, value1, value3, value2, value1 +/// ..., value2, value1 -> ..., value1, value2, value1 +void OperandStack::do_dup2_x1(BasicBlock* insertAtEnd) +{ + copySlots(TheStack[currentDepth-1], TheStack[currentDepth+1], insertAtEnd); + copySlots(TheStack[currentDepth-2], TheStack[currentDepth], insertAtEnd); + copySlots(TheStack[currentDepth-3], TheStack[currentDepth-1], insertAtEnd); + copySlots(TheStack[currentDepth+1], TheStack[currentDepth-2], insertAtEnd); + copySlots(TheStack[currentDepth], TheStack[currentDepth-3], insertAtEnd); + currentDepth += 2; +} + +/// ..., value4, value3, value2, value1 -> ..., value2, value1, value4, value3, value2, value1 +/// ..., value3, value2, value1 -> ..., value1, value3, value2, value1 +/// ..., value3, value2, value1 -> ..., value2, value1, value3, value2, value1 +/// ..., value2, value1 -> ..., value1, value2, value1 +void OperandStack::do_dup2_x2(BasicBlock* insertAtEnd) +{ + copySlots(TheStack[currentDepth-1], TheStack[currentDepth+1], insertAtEnd); + copySlots(TheStack[currentDepth-2], TheStack[currentDepth], insertAtEnd); + copySlots(TheStack[currentDepth-3], TheStack[currentDepth-1], insertAtEnd); + copySlots(TheStack[currentDepth-4], TheStack[currentDepth-2], insertAtEnd); + copySlots(TheStack[currentDepth+1], TheStack[currentDepth-3], insertAtEnd); + copySlots(TheStack[currentDepth], TheStack[currentDepth-4], insertAtEnd); + currentDepth += 2; +} + +void OperandStack::do_swap(BasicBlock* insertAtEnd) +{ + SlotMap tmp; + copySlots(TheStack[currentDepth-1], tmp, insertAtEnd); + copySlots(TheStack[currentDepth-2], TheStack[currentDepth-1], insertAtEnd); + copySlots(tmp, TheStack[currentDepth-2], insertAtEnd); } Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.186 llvm-java/lib/Compiler/Compiler.cpp:1.187 --- llvm-java/lib/Compiler/Compiler.cpp:1.186 Fri Jan 21 07:53:27 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Jan 21 19:30:12 2005 @@ -70,11 +70,11 @@ ClassFile* cf_; std::auto_ptr bbBuilder_; std::list bbWorkList_; - typedef std::map OpStackMap; - OpStackMap opStackMap_; + typedef std::map OpStackDepthMap; + OpStackDepthMap opStackDepthMap_; BasicBlock* currentBB_; - Locals* currentLocals_; - OperandStack* currentOpStack_; + Locals locals_; + OperandStack opStack_; typedef SetVector FunctionSet; FunctionSet toCompileFunctions_; @@ -119,7 +119,7 @@ public: Compiler(Module& m) - : module_(m) { + : module_(m), locals_(0), opStack_(0) { Type* JNIEnvTy = OpaqueType::get(); module_.addTypeName("JNIEnv", JNIEnvTy); JNIEnvPtr_ = new GlobalVariable(JNIEnvTy, @@ -132,15 +132,11 @@ private: void push(Value* value) { - assert(currentOpStack_ && "Current operand stack not set!"); - assert(currentBB_ && "Current basic block not set!"); - currentOpStack_->push(value, currentBB_); + opStack_.push(value, currentBB_); } - Value* pop() { - assert(currentOpStack_ && "Current operand stack not set!"); - assert(currentBB_ && "Current basic block not set!"); - return currentOpStack_->pop(currentBB_); + Value* pop(const Type* type) { + return opStack_.pop(type, currentBB_); } /// Schedule a method for compilation. Returns true if this is the @@ -491,7 +487,7 @@ return arrayInfo; } - const ClassInfo& getPrimitiveArrayInfo(Type* type) { + const ClassInfo& getArrayInfo(const Type* type) { if (Type::BoolTy == type) return getPrimitiveArrayInfo(BOOLEAN); else if (Type::UShortTy == type) return getPrimitiveArrayInfo(CHAR); else if (Type::FloatTy == type) return getPrimitiveArrayInfo(FLOAT); @@ -500,6 +496,7 @@ else if (Type::ShortTy == type) return getPrimitiveArrayInfo(SHORT); else if (Type::IntTy == type) return getPrimitiveArrayInfo(INT); else if (Type::LongTy == type) return getPrimitiveArrayInfo(LONG); + else if (ObjectBaseRefTy == type) return getObjectArrayInfo(); else abort(); } @@ -1279,16 +1276,16 @@ Java::CodeAttribute* codeAttr = method->getCodeAttribute(); - opStackMap_.clear(); + opStackDepthMap_.clear(); bbBuilder_.reset(new BasicBlockBuilder(function, codeAttr)); // Put arguments into locals. - Locals locals(codeAttr->getMaxLocals()); + locals_ = Locals(codeAttr->getMaxLocals()); unsigned index = 0; for (Function::aiterator a = function->abegin(), ae = function->aend(); a != ae; ++a) { - locals.store(index, a, &function->getEntryBlock()); + locals_.store(index, a, &function->getEntryBlock()); index += isTwoSlotType(a->getType()) ? 2 : 1; } // For the entry block the operand stack is empty and the locals @@ -1297,10 +1294,8 @@ // NOTE: We create an operand stack one size too big because we // push extra values on the stack to simplify code generation // (see implementation of ifne). - currentLocals_ = &locals; - opStackMap_.insert( - std::make_pair(&function->getEntryBlock(), - OperandStack(codeAttr->getMaxStack()+1))); + opStack_ = OperandStack(codeAttr->getMaxStack()+2); + opStackDepthMap_.insert(std::make_pair(&function->getEntryBlock(), 0)); // Insert the entry block to the work list. bbWorkList_.push_back(&function->getEntryBlock()); @@ -1310,11 +1305,12 @@ currentBB_ = bbWorkList_.front(); bbWorkList_.pop_front(); - OpStackMap::iterator opStack = opStackMap_.find(currentBB_); - assert(opStack != opStackMap_.end() && - "Unknown operand stack for basic block in work list!"); + OpStackDepthMap::iterator opStackDepth = + opStackDepthMap_.find(currentBB_); + assert(opStackDepth != opStackDepthMap_.end() && + "Unknown operand stack depth for basic block in work list!"); - currentOpStack_ = &opStack->second; + opStack_.setDepth(opStackDepth->second); unsigned start, end; tie(start, end) = bbBuilder_->getBytecodeIndices(currentBB_); @@ -1337,10 +1333,12 @@ SI = succ_begin(currentBB_), SE = succ_end(currentBB_); SI != SE; ++SI) { BasicBlock* Succ = *SI; - OpStackMap::iterator succOpStack = opStackMap_.lower_bound(Succ); - if (succOpStack == opStackMap_.end() || succOpStack->first != Succ) { - opStackMap_.insert(succOpStack, - std::make_pair(Succ, *currentOpStack_)); + OpStackDepthMap::iterator succOpStackDepth = + opStackDepthMap_.lower_bound(Succ); + if (succOpStackDepth == opStackDepthMap_.end() || + succOpStackDepth->first != Succ) { + opStackDepthMap_.insert(succOpStackDepth, + std::make_pair(Succ, opStack_.getDepth())); bbWorkList_.push_back(Succ); } } @@ -1526,7 +1524,7 @@ void do_aload(unsigned index) { do_load_common(index, ObjectBaseRefTy); } void do_load_common(unsigned index, Type* type) { - Value* val = currentLocals_->load(index, type, currentBB_); + Value* val = locals_.load(index, type, currentBB_); push(val); } @@ -1540,8 +1538,9 @@ void do_saload() { do_aload_common(getPrimitiveArrayInfo(SHORT).type); } void do_aload_common(Type* arrayTy) { - Value* index = pop(); - Value* arrayRef = new CastInst(pop(), PointerType::get(arrayTy), + Value* index = pop(Type::IntTy); + Value* arrayRef = new CastInst(pop(ObjectBaseRefTy), + PointerType::get(arrayTy), "cast-to-array", currentBB_); std::vector indices; @@ -1555,30 +1554,32 @@ push(result); } - void do_istore(unsigned index) { do_store_common(index); } - void do_lstore(unsigned index) { do_store_common(index); } - void do_fstore(unsigned index) { do_store_common(index); } - void do_dstore(unsigned index) { do_store_common(index); } - void do_astore(unsigned index) { do_store_common(index); } - - void do_store_common(unsigned index) { - Value* val = pop(); - currentLocals_->store(index, val, currentBB_); - } - - void do_iastore() { do_astore_common(getPrimitiveArrayInfo(INT).type); } - void do_lastore() { do_astore_common(getPrimitiveArrayInfo(LONG).type); } - void do_fastore() { do_astore_common(getPrimitiveArrayInfo(FLOAT).type); } - void do_dastore() { do_astore_common(getPrimitiveArrayInfo(DOUBLE).type); } - void do_aastore() { do_astore_common(getObjectArrayInfo().type); } - void do_bastore() { do_astore_common(getPrimitiveArrayInfo(BYTE).type); } - void do_castore() { do_astore_common(getPrimitiveArrayInfo(CHAR).type); } - void do_sastore() { do_astore_common(getPrimitiveArrayInfo(SHORT).type); } - - void do_astore_common(Type* arrayTy) { - Value* value = pop(); - Value* index = pop(); - Value* arrayRef = new CastInst(pop(), PointerType::get(arrayTy), + void do_istore(unsigned index) { do_store_common(index, Type::IntTy); } + void do_lstore(unsigned index) { do_store_common(index, Type::LongTy); } + void do_fstore(unsigned index) { do_store_common(index, Type::FloatTy); } + void do_dstore(unsigned index) { do_store_common(index, Type::DoubleTy); } + void do_astore(unsigned index) { do_store_common(index, ObjectBaseRefTy); } + + void do_store_common(unsigned index, const Type* type) { + Value* val = pop(type); + locals_.store(index, val, currentBB_); + } + + void do_iastore() { do_astore_common(Type::IntTy); } + void do_lastore() { do_astore_common(Type::LongTy); } + void do_fastore() { do_astore_common(Type::FloatTy); } + void do_dastore() { do_astore_common(Type::DoubleTy); } + void do_aastore() { do_astore_common(ObjectBaseRefTy); } + void do_bastore() { do_astore_common(Type::SByteTy); } + void do_castore() { do_astore_common(Type::UShortTy); } + void do_sastore() { do_astore_common(Type::ShortTy); } + + void do_astore_common(const Type* elementTy) { + Value* value = pop(elementTy); + Value* index = pop(Type::IntTy); + const Type* arrayRefTy = PointerType::get(getArrayInfo(elementTy).type); + Value* arrayRef = new CastInst(pop(ObjectBaseRefTy), + arrayRefTy, "cast-to-array", currentBB_); std::vector indices; @@ -1589,252 +1590,151 @@ Value* elementPtr = new GetElementPtrInst(arrayRef, indices, TMP, currentBB_); - const Type* elementTy = - cast(elementPtr->getType())->getElementType(); - value = new CastInst(value, elementTy, TMP, currentBB_); new StoreInst(value, elementPtr, currentBB_); } void do_pop() { - pop(); + opStack_.do_pop(currentBB_); } void do_pop2() { - Value* v1 = pop(); - if (isOneSlotValue(v1)) - pop(); + opStack_.do_pop2(currentBB_); } void do_dup() { - Value* val = pop(); - push(val); - push(val); + opStack_.do_dup(currentBB_); } void do_dup_x1() { - Value* v1 = pop(); - Value* v2 = pop(); - push(v1); - push(v2); - push(v1); + opStack_.do_dup_x1(currentBB_); } void do_dup_x2() { - Value* v1 = pop(); - Value* v2 = pop(); - if (isOneSlotValue(v2)) { - Value* v3 = pop(); - push(v1); - push(v3); - push(v2); - push(v1); - } - else { - push(v1); - push(v2); - push(v1); - } + opStack_.do_dup_x2(currentBB_); } void do_dup2() { - Value* v1 = pop(); - if (isOneSlotValue(v1)) { - Value* v2 = pop(); - push(v2); - push(v1); - push(v2); - push(v1); - } - else { - push(v1); - push(v1); - } + opStack_.do_dup2(currentBB_); } void do_dup2_x1() { - Value* v1 = pop(); - Value* v2 = pop(); - if (isOneSlotValue(v1)) { - Value* v3 = pop(); - push(v2); - push(v1); - push(v3); - push(v2); - push(v1); - } - else { - push(v1); - push(v2); - push(v1); - } + opStack_.do_dup2_x1(currentBB_); } void do_dup2_x2() { - Value* v1 = pop(); - Value* v2 = pop(); - if (isOneSlotValue(v1)) { - Value* v3 = pop(); - if (isOneSlotValue(v3)) { - Value* v4 = pop(); - push(v2); - push(v1); - push(v4); - push(v3); - push(v2); - push(v1); - } - else { - push(v2); - push(v1); - push(v3); - push(v2); - push(v1); - } - } - else { - if (isOneSlotValue(v2)) { - Value* v3 = pop(); - push(v1); - push(v3); - push(v2); - push(v1); - } - else { - push(v1); - push(v2); - push(v1); - } - } + opStack_.do_dup2_x2(currentBB_); } void do_swap() { - Value* v1 = pop(); - Value* v2 = pop(); - push(v1); - push(v2); - } - - void do_iadd() { do_binary_op_common(Instruction::Add); } - void do_ladd() { do_binary_op_common(Instruction::Add); } - void do_fadd() { do_binary_op_common(Instruction::Add); } - void do_dadd() { do_binary_op_common(Instruction::Add); } - - void do_isub() { do_binary_op_common(Instruction::Sub); } - void do_lsub() { do_binary_op_common(Instruction::Sub); } - void do_fsub() { do_binary_op_common(Instruction::Sub); } - void do_dsub() { do_binary_op_common(Instruction::Sub); } - - void do_imul() { do_binary_op_common(Instruction::Mul); } - void do_lmul() { do_binary_op_common(Instruction::Mul); } - void do_fmul() { do_binary_op_common(Instruction::Mul); } - void do_dmul() { do_binary_op_common(Instruction::Mul); } - - void do_idiv() { do_binary_op_common(Instruction::Div); } - void do_ldiv() { do_binary_op_common(Instruction::Div); } - void do_fdiv() { do_binary_op_common(Instruction::Div); } - void do_ddiv() { do_binary_op_common(Instruction::Div); } - - void do_irem() { do_binary_op_common(Instruction::Rem); } - void do_lrem() { do_binary_op_common(Instruction::Rem); } - void do_frem() { do_binary_op_common(Instruction::Rem); } - void do_drem() { do_binary_op_common(Instruction::Rem); } - - void do_ineg() { do_neg_common(); } - void do_lneg() { do_neg_common(); } - void do_fneg() { do_neg_common(); } - void do_dneg() { do_neg_common(); } + opStack_.do_swap(currentBB_); + } + + void do_iadd() { do_binary_op_common(Instruction::Add, Type::IntTy); } + void do_ladd() { do_binary_op_common(Instruction::Add, Type::LongTy); } + void do_fadd() { do_binary_op_common(Instruction::Add, Type::FloatTy); } + void do_dadd() { do_binary_op_common(Instruction::Add, Type::DoubleTy); } + + void do_isub() { do_binary_op_common(Instruction::Sub, Type::IntTy); } + void do_lsub() { do_binary_op_common(Instruction::Sub, Type::LongTy); } + void do_fsub() { do_binary_op_common(Instruction::Sub, Type::FloatTy); } + void do_dsub() { do_binary_op_common(Instruction::Sub, Type::DoubleTy); } + + void do_imul() { do_binary_op_common(Instruction::Mul, Type::IntTy); } + void do_lmul() { do_binary_op_common(Instruction::Mul, Type::LongTy); } + void do_fmul() { do_binary_op_common(Instruction::Mul, Type::FloatTy); } + void do_dmul() { do_binary_op_common(Instruction::Mul, Type::DoubleTy); } + + void do_idiv() { do_binary_op_common(Instruction::Div, Type::IntTy); } + void do_ldiv() { do_binary_op_common(Instruction::Div, Type::LongTy); } + void do_fdiv() { do_binary_op_common(Instruction::Div, Type::FloatTy); } + void do_ddiv() { do_binary_op_common(Instruction::Div, Type::DoubleTy); } + + void do_irem() { do_binary_op_common(Instruction::Rem, Type::IntTy); } + void do_lrem() { do_binary_op_common(Instruction::Rem, Type::LongTy); } + void do_frem() { do_binary_op_common(Instruction::Rem, Type::FloatTy); } + void do_drem() { do_binary_op_common(Instruction::Rem, Type::DoubleTy); } + + void do_ineg() { do_neg_common(Type::IntTy); } + void do_lneg() { do_neg_common(Type::LongTy); } + void do_fneg() { do_neg_common(Type::FloatTy); } + void do_dneg() { do_neg_common(Type::DoubleTy); } - void do_neg_common() { - Value* v1 = pop(); + void do_neg_common(const Type* type) { + Value* v1 = pop(type); Value* r = BinaryOperator::createNeg(v1, TMP, currentBB_); push(r); } - void do_ishl() { do_shift_common(Instruction::Shl); } - void do_lshl() { do_shift_common(Instruction::Shl); } - void do_ishr() { do_shift_common(Instruction::Shr); } - void do_lshr() { do_shift_common(Instruction::Shr); } + void do_ishl() { do_shift_common(Instruction::Shl, Type::IntTy); } + void do_lshl() { do_shift_common(Instruction::Shl, Type::LongTy); } + void do_ishr() { do_shift_common(Instruction::Shr, Type::IntTy); } + void do_lshr() { do_shift_common(Instruction::Shr, Type::LongTy); } - void do_iushr() { do_shift_unsigned_common(); } - void do_lushr() { do_shift_unsigned_common(); } + void do_iushr() { do_shift_unsigned_common(Type::IntTy); } + void do_lushr() { do_shift_unsigned_common(Type::LongTy); } - void do_shift_unsigned_common() { + void do_shift_unsigned_common(const Type* type) { // Cast value to be shifted into its unsigned version. - do_swap(); - Value* v = pop(); - v = new CastInst(v, v->getType()->getUnsignedVersion(), TMP, currentBB_); - push(v); - do_swap(); - - do_shift_common(Instruction::Shr); - - v = pop(); + Value* a = pop(Type::UByteTy); + Value* v = pop(type->getUnsignedVersion()); + Value* r = new ShiftInst(Instruction::Shr, v, a, TMP, currentBB_); // Cast shifted value back to its original signed version. - v = new CastInst(v, v->getType()->getSignedVersion(), TMP, currentBB_); - push(v); + r = new CastInst(r, type->getSignedVersion(), TMP, currentBB_); + push(r); } - void do_shift_common(Instruction::OtherOps op) { - Value* a = pop(); - Value* v = pop(); - a = new CastInst(a, Type::UByteTy, TMP, currentBB_); + void do_shift_common(Instruction::OtherOps op, const Type* type) { + Value* a = pop(Type::UByteTy); + Value* v = pop(type); Value* r = new ShiftInst(op, v, a, TMP, currentBB_); push(r); } - void do_iand() { do_binary_op_common(Instruction::And); } - void do_land() { do_binary_op_common(Instruction::And); } - void do_ior() { do_binary_op_common(Instruction::Or); } - void do_lor() { do_binary_op_common(Instruction::Or); } - void do_ixor() { do_binary_op_common(Instruction::Xor); } - void do_lxor() { do_binary_op_common(Instruction::Xor); } - - void do_binary_op_common(Instruction::BinaryOps op) { - Value* v2 = pop(); - Value* v1 = pop(); + void do_iand() { do_binary_op_common(Instruction::And, Type::IntTy); } + void do_land() { do_binary_op_common(Instruction::And, Type::LongTy); } + void do_ior() { do_binary_op_common(Instruction::Or, Type::IntTy); } + void do_lor() { do_binary_op_common(Instruction::Or, Type::LongTy); } + void do_ixor() { do_binary_op_common(Instruction::Xor, Type::IntTy); } + void do_lxor() { do_binary_op_common(Instruction::Xor, Type::LongTy); } + + void do_binary_op_common(Instruction::BinaryOps op, const Type* type) { + Value* v2 = pop(type); + Value* v1 = pop(type); Value* r = BinaryOperator::create(op, v1, v2, TMP, currentBB_); push(r); } void do_iinc(unsigned index, int amount) { - Value* v = currentLocals_->load(index, Type::IntTy, currentBB_); + Value* v = locals_.load(index, Type::IntTy, currentBB_); Value* a = ConstantSInt::get(Type::IntTy, amount); v = BinaryOperator::createAdd(v, a, TMP, currentBB_); - currentLocals_->store(index, v, currentBB_); + locals_.store(index, v, currentBB_); } - void do_i2l() { do_cast_common(Type::LongTy); } - void do_i2f() { do_cast_common(Type::FloatTy); } - void do_i2d() { do_cast_common(Type::DoubleTy); } - void do_l2i() { do_cast_common(Type::IntTy); } - void do_l2f() { do_cast_common(Type::FloatTy); } - void do_l2d() { do_cast_common(Type::DoubleTy); } - void do_f2i() { do_cast_common(Type::IntTy); } - void do_f2l() { do_cast_common(Type::LongTy); } - void do_f2d() { do_cast_common(Type::DoubleTy); } - void do_d2i() { do_cast_common(Type::IntTy); } - void do_d2l() { do_cast_common(Type::LongTy); } - void do_d2f() { do_cast_common(Type::FloatTy); } - void do_i2b() { do_truncate_common(Type::SByteTy); } - void do_i2c() { do_truncate_common(Type::UShortTy); } - void do_i2s() { do_truncate_common(Type::ShortTy); } - - void do_cast_common(Type* type) { - Value* v1 = pop(); - v1 = new CastInst(v1, type, TMP, currentBB_); - push(v1); - } - - void do_truncate_common(Type* type) { - Value* v1 = pop(); - v1 = new CastInst(v1, type, TMP, currentBB_); - v1 = new CastInst(v1, Type::IntTy, TMP, currentBB_); - push(v1); + void do_i2l() { do_cast_common(Type::IntTy, Type::LongTy); } + void do_i2f() { do_cast_common(Type::IntTy, Type::FloatTy); } + void do_i2d() { do_cast_common(Type::IntTy, Type::DoubleTy); } + void do_l2i() { do_cast_common(Type::LongTy, Type::IntTy); } + void do_l2f() { do_cast_common(Type::LongTy, Type::FloatTy); } + void do_l2d() { do_cast_common(Type::LongTy, Type::DoubleTy); } + void do_f2i() { do_cast_common(Type::FloatTy, Type::IntTy); } + void do_f2l() { do_cast_common(Type::FloatTy, Type::LongTy); } + void do_f2d() { do_cast_common(Type::FloatTy, Type::DoubleTy); } + void do_d2i() { do_cast_common(Type::DoubleTy, Type::IntTy); } + void do_d2l() { do_cast_common(Type::DoubleTy, Type::LongTy); } + void do_d2f() { do_cast_common(Type::DoubleTy, Type::FloatTy); } + void do_i2b() { do_cast_common(Type::IntTy, Type::SByteTy); } + void do_i2c() { do_cast_common(Type::IntTy, Type::UShortTy); } + void do_i2s() { do_cast_common(Type::IntTy, Type::ShortTy); } + + void do_cast_common(const Type* from, const Type* to) { + Value* v1 = pop(from); + push(new CastInst(v1, to, TMP, currentBB_)); } void do_lcmp() { - Value* v2 = pop(); - Value* v1 = pop(); + Value* v2 = pop(Type::LongTy); + Value* v1 = pop(Type::LongTy); Value* c = BinaryOperator::createSetGT(v1, v2, TMP, currentBB_); Value* r = new SelectInst(c, ConstantSInt::get(Type::IntTy, 1), ConstantSInt::get(Type::IntTy, 0), TMP, @@ -1845,14 +1745,14 @@ push(r); } - void do_fcmpl() { do_cmp_common(-1); } - void do_dcmpl() { do_cmp_common(-1); } - void do_fcmpg() { do_cmp_common(1); } - void do_dcmpg() { do_cmp_common(1); } - - void do_cmp_common(int valueIfUnordered) { - Value* v2 = pop(); - Value* v1 = pop(); + void do_fcmpl() { do_cmp_common(Type::FloatTy, -1); } + void do_dcmpl() { do_cmp_common(Type::DoubleTy, -1); } + void do_fcmpg() { do_cmp_common(Type::FloatTy, 1); } + void do_dcmpg() { do_cmp_common(Type::DoubleTy, 1); } + + void do_cmp_common(const Type* type, int valueIfUnordered) { + Value* v2 = pop(type); + Value* v1 = pop(type); Value* c = BinaryOperator::createSetGT(v1, v2, TMP, currentBB_); Value* r = new SelectInst(c, ConstantSInt::get(Type::IntTy, 1), ConstantSInt::get(Type::IntTy, 0), TMP, @@ -1871,64 +1771,65 @@ void do_ifeq(unsigned t, unsigned f) { do_iconst(0); - do_if_common(Instruction::SetEQ, t, f); + do_if_common(Instruction::SetEQ, Type::IntTy, t, f); } void do_ifne(unsigned t, unsigned f) { do_iconst(0); - do_if_common(Instruction::SetNE, t, f); + do_if_common(Instruction::SetNE, Type::IntTy, t, f); } void do_iflt(unsigned t, unsigned f) { do_iconst(0); - do_if_common(Instruction::SetLT, t, f); + do_if_common(Instruction::SetLT, Type::IntTy, t, f); } void do_ifge(unsigned t, unsigned f) { do_iconst(0); - do_if_common(Instruction::SetGE, t, f); + do_if_common(Instruction::SetGE, Type::IntTy, t, f); } void do_ifgt(unsigned t, unsigned f) { do_iconst(0); - do_if_common(Instruction::SetGT, t, f); + do_if_common(Instruction::SetGT, Type::IntTy, t, f); } void do_ifle(unsigned t, unsigned f) { do_iconst(0); - do_if_common(Instruction::SetLE, t, f); + do_if_common(Instruction::SetLE, Type::IntTy, t, f); } void do_if_icmpeq(unsigned t, unsigned f) { - do_if_common(Instruction::SetEQ, t, f); + do_if_common(Instruction::SetEQ, Type::IntTy, t, f); } void do_if_icmpne(unsigned t, unsigned f) { - do_if_common(Instruction::SetNE, t, f); + do_if_common(Instruction::SetNE, Type::IntTy, t, f); } void do_if_icmplt(unsigned t, unsigned f) { - do_if_common(Instruction::SetLT, t, f); + do_if_common(Instruction::SetLT, Type::IntTy, t, f); } void do_if_icmpge(unsigned t, unsigned f) { - do_if_common(Instruction::SetGE, t, f); + do_if_common(Instruction::SetGE, Type::IntTy, t, f); } void do_if_icmpgt(unsigned t, unsigned f) { - do_if_common(Instruction::SetGT, t, f); + do_if_common(Instruction::SetGT, Type::IntTy, t, f); } void do_if_icmple(unsigned t, unsigned f) { - do_if_common(Instruction::SetLE, t, f); + do_if_common(Instruction::SetLE, Type::IntTy, t, f); } void do_if_acmpeq(unsigned t, unsigned f) { - do_if_common(Instruction::SetEQ, t, f); + do_if_common(Instruction::SetEQ, ObjectBaseRefTy, t, f); } void do_if_acmpne(unsigned t, unsigned f) { - do_if_common(Instruction::SetNE, t, f); + do_if_common(Instruction::SetNE, ObjectBaseRefTy, t, f); } void do_ifnull(unsigned t, unsigned f) { do_aconst_null(); - do_if_common(Instruction::SetEQ, t, f); + do_if_common(Instruction::SetEQ, ObjectBaseRefTy, t, f); } void do_ifnonnull(unsigned t, unsigned f) { do_aconst_null(); - do_if_common(Instruction::SetEQ, t, f); + do_if_common(Instruction::SetEQ, ObjectBaseRefTy, t, f); } - void do_if_common(Instruction::BinaryOps cc, unsigned t, unsigned f) { - Value* v2 = pop(); - Value* v1 = pop(); + void do_if_common(Instruction::BinaryOps cc, const Type* type, + unsigned t, unsigned f) { + Value* v2 = pop(type); + Value* v1 = pop(type); if (v1->getType() != v2->getType()) v1 = new CastInst(v1, v2->getType(), TMP, currentBB_); Value* c = new SetCondInst(cc, v1, v2, TMP, currentBB_); @@ -1941,14 +1842,14 @@ new BranchInst(bbBuilder_->getBasicBlock(target), currentBB_); } - void do_ireturn() { do_return_common(); } - void do_lreturn() { do_return_common(); } - void do_freturn() { do_return_common(); } - void do_dreturn() { do_return_common(); } - void do_areturn() { do_return_common(); } + void do_ireturn() { do_return_common(Type::IntTy); } + void do_lreturn() { do_return_common(Type::LongTy); } + void do_freturn() { do_return_common(Type::FloatTy); } + void do_dreturn() { do_return_common(Type::DoubleTy); } + void do_areturn() { do_return_common(ObjectBaseRefTy); } - void do_return_common() { - Value* r = pop(); + void do_return_common(const Type* type) { + Value* r = pop(type); const Type* retTy = currentBB_->getParent()->getReturnType(); new ReturnInst(new CastInst(r, retTy, TMP, currentBB_), currentBB_); } @@ -1968,7 +1869,7 @@ } void do_switch(unsigned defTarget, const SwitchCases& sw) { - Value* v = pop(); + Value* v = pop(Type::IntTy); SwitchInst* in = new SwitchInst(v, bbBuilder_->getBasicBlock(defTarget), currentBB_); for (unsigned i = 0, e = sw.size(); i != e; ++i) @@ -1982,23 +1883,23 @@ } void do_putstatic(unsigned index) { - Value* v = pop(); Value* ptr = getStaticField(index); const Type* fieldTy = cast(ptr->getType())->getElementType(); - if (v->getType() != fieldTy) - v = new CastInst(v, fieldTy, TMP, currentBB_); + Value* v = pop(fieldTy); new StoreInst(v, ptr, currentBB_); } void do_getfield(unsigned index) { - Value* p = pop(); + Value* p = pop(ObjectBaseRefTy); Value* v = new LoadInst(getField(index, p), TMP, currentBB_); push(v); } void do_putfield(unsigned index) { - Value* v = pop(); - Value* p = pop(); + ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); + const Type* type = getType(fieldRef->getNameAndType()->getDescriptor()); + Value* v = pop(type); + Value* p = pop(ObjectBaseRefTy); Value* fp = getField(index, p); const Type* ft = cast(fp->getType())->getElementType(); v = new CastInst(v, ft, TMP, currentBB_); @@ -2036,13 +1937,8 @@ std::vector getParams(const FunctionType* funTy) { unsigned numParams = funTy->getNumParams(); std::vector params(numParams); - while (numParams--) { - Value* p = pop(); - params[numParams] = - p->getType() == funTy->getParamType(numParams) ? - p : - new CastInst(p, funTy->getParamType(numParams), TMP, currentBB_); - } + while (numParams--) + params[numParams] = pop(funTy->getParamType(numParams)); return params; } @@ -2060,35 +1956,35 @@ else switch (className[1]) { case 'B': vi = &getPrimitiveArrayVTableInfo(Type::SByteTy); - ci = &getPrimitiveArrayInfo(Type::SByteTy); + ci = &getArrayInfo(Type::SByteTy); break; case 'C': vi = &getPrimitiveArrayVTableInfo(Type::UShortTy); - ci = &getPrimitiveArrayInfo(Type::UShortTy); + ci = &getArrayInfo(Type::UShortTy); break; case 'D': vi = &getPrimitiveArrayVTableInfo(Type::DoubleTy); - ci = &getPrimitiveArrayInfo(Type::DoubleTy); + ci = &getArrayInfo(Type::DoubleTy); break; case 'F': vi = &getPrimitiveArrayVTableInfo(Type::FloatTy); - ci = &getPrimitiveArrayInfo(Type::FloatTy); + ci = &getArrayInfo(Type::FloatTy); break; case 'I': vi = &getPrimitiveArrayVTableInfo(Type::IntTy); - ci = &getPrimitiveArrayInfo(Type::IntTy); + ci = &getArrayInfo(Type::IntTy); break; case 'J': vi = &getPrimitiveArrayVTableInfo(Type::LongTy); - ci = &getPrimitiveArrayInfo(Type::LongTy); + ci = &getArrayInfo(Type::LongTy); break; case 'S': vi = &getPrimitiveArrayVTableInfo(Type::ShortTy); - ci = &getPrimitiveArrayInfo(Type::ShortTy); + ci = &getArrayInfo(Type::ShortTy); break; case 'Z': vi = &getPrimitiveArrayVTableInfo(Type::BoolTy); - ci = &getPrimitiveArrayInfo(Type::BoolTy); + ci = &getArrayInfo(Type::BoolTy); break; } } @@ -2283,7 +2179,7 @@ } void do_newarray(JType type) { - Value* count = pop(); + Value* count = pop(Type::IntTy); count = new CastInst(count, Type::UIntTy, TMP, currentBB_); const ClassInfo& ci = getPrimitiveArrayInfo(type); @@ -2293,7 +2189,7 @@ } void do_anewarray(unsigned index) { - Value* count = pop(); + Value* count = pop(Type::IntTy); count = new CastInst(count, Type::UIntTy, TMP, currentBB_); ConstantClass* classRef = cf_->getConstantClass(index); @@ -2345,7 +2241,7 @@ } void do_arraylength() { - Value* arrayRef = pop(); + Value* arrayRef = pop(ObjectBaseRefTy); const ClassInfo& ci = getObjectArrayInfo(); arrayRef = new CastInst(arrayRef, PointerType::get(ci.type), TMP, currentBB_); @@ -2356,7 +2252,7 @@ } void do_athrow() { - Value* objRef = pop(); + Value* objRef = pop(ObjectBaseRefTy); objRef = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_THROW, Type::IntTy, @@ -2372,7 +2268,7 @@ const VTableInfo* vi = NULL; tie(ci, vi) = getInfo(classRef->getName()->str()); - Value* objRef = pop(); + Value* objRef = pop(ObjectBaseRefTy); Value* objBase = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( @@ -2399,7 +2295,7 @@ const VTableInfo* vi = NULL; tie(ci, vi) = getInfo(classRef->getName()->str()); - Value* objRef = pop(); + Value* objRef = pop(ObjectBaseRefTy); Value* objBase = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( From alkis at cs.uiuc.edu Fri Jan 21 21:28:23 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 21 Jan 2005 21:28:23 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200501220328.VAA30088@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.187 -> 1.188 --- Log message: Fix bug in ifnonnull codegen. --- Diffs of the changes: (+1 -1) Compiler.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.187 llvm-java/lib/Compiler/Compiler.cpp:1.188 --- llvm-java/lib/Compiler/Compiler.cpp:1.187 Fri Jan 21 19:30:12 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Jan 21 21:28:12 2005 @@ -1823,7 +1823,7 @@ } void do_ifnonnull(unsigned t, unsigned f) { do_aconst_null(); - do_if_common(Instruction::SetEQ, ObjectBaseRefTy, t, f); + do_if_common(Instruction::SetNE, ObjectBaseRefTy, t, f); } void do_if_common(Instruction::BinaryOps cc, const Type* type, From alkis at cs.uiuc.edu Fri Jan 21 21:29:06 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 21 Jan 2005 21:29:06 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java Message-ID: <200501220329.VAA30109@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Lists4.java added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+11 -0) Lists4.java | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java diff -c /dev/null llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java:1.1 *** /dev/null Fri Jan 21 21:29:06 2005 --- llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java Fri Jan 21 21:28:56 2005 *************** *** 0 **** --- 1,11 ---- + import java.util.*; + + public class Lists4 + { + public static void main(String[] args) { + LinkedList llist = new LinkedList(); + llist.add(null); + Test.println(llist.getFirst() == null); + Test.println(llist.contains(null)); + } + } From alkis at cs.uiuc.edu Fri Jan 21 21:30:18 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 21 Jan 2005 21:30:18 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java Message-ID: <200501220330.VAA30142@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Lists4.java updated: 1.1 -> 1.2 --- Log message: Improve testcase --- Diffs of the changes: (+1 -0) Lists4.java | 1 + 1 files changed, 1 insertion(+) Index: llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java diff -u llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java:1.1 llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java:1.2 --- llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java:1.1 Fri Jan 21 21:28:56 2005 +++ llvm-java/test/Programs/SingleSource/UnitTests/Lists4.java Fri Jan 21 21:30:07 2005 @@ -7,5 +7,6 @@ llist.add(null); Test.println(llist.getFirst() == null); Test.println(llist.contains(null)); + Test.println(llist.get(0) == null); } } From jeffc at jolt-lang.org Sat Jan 22 10:28:44 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 10:28:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200501221628.KAA27126@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.28 -> 1.29 --- Log message: Fix destroyDirectory bug --- Diffs of the changes: (+8 -5) Path.inc | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.28 llvm/lib/System/Win32/Path.inc:1.29 --- llvm/lib/System/Win32/Path.inc:1.28 Thu Jan 13 22:09:39 2005 +++ llvm/lib/System/Win32/Path.inc Sat Jan 22 10:28:33 2005 @@ -562,15 +562,17 @@ // If it doesn't exist, we're done. if (!exists()) return true; - char *pathname = reinterpret_cast(_alloca(path.length()+1)); - path.copy(pathname,path.length()+1); + char *pathname = reinterpret_cast(_alloca(path.length()+2)); int lastchar = path.length() - 1 ; - if (pathname[lastchar] == '/') - pathname[lastchar] = 0; + path.copy(pathname,lastchar+2); + + // Make path end with '/*'. + pathname[lastchar+1] = '*'; + pathname[lastchar+2] = 0; if (remove_contents) { WIN32_FIND_DATA fd; - HANDLE h = FindFirstFile(path.c_str(), &fd); + HANDLE h = FindFirstFile(pathname, &fd); // It's a bad idea to alter the contents of a directory while enumerating // its contents. So build a list of its contents first, then destroy them. @@ -610,6 +612,7 @@ } } + pathname[lastchar] = 0; if (!RemoveDirectory(pathname)) ThrowError(std::string(pathname) + ": Can't destroy directory: "); return true; From jeffc at jolt-lang.org Sat Jan 22 10:30:26 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 10:30:26 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/ToolRunner.h Message-ID: <200501221630.KAA27161@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: ToolRunner.h updated: 1.17 -> 1.18 --- Log message: Fix VC++ complaint --- Diffs of the changes: (+2 -1) ToolRunner.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Support/ToolRunner.h diff -u llvm/include/llvm/Support/ToolRunner.h:1.17 llvm/include/llvm/Support/ToolRunner.h:1.18 --- llvm/include/llvm/Support/ToolRunner.h:1.17 Sun Dec 19 11:59:45 2004 +++ llvm/include/llvm/Support/ToolRunner.h Sat Jan 22 10:30:16 2005 @@ -79,7 +79,8 @@ /// LLVM bytecode in a variety of ways. This abstract interface hides this /// complexity behind a simple interface. /// -struct AbstractInterpreter { +class AbstractInterpreter { +public: static CBE *createCBE(const std::string &ProgramPath, std::string &Message, const std::vector *Args = 0); static LLC *createLLC(const std::string &ProgramPath, std::string &Message, From jeffc at jolt-lang.org Sat Jan 22 10:31:08 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 10:31:08 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CrashDebugger.cpp Message-ID: <200501221631.KAA27177@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CrashDebugger.cpp updated: 1.39 -> 1.40 --- Log message: Fix VC++ complaint --- Diffs of the changes: (+1 -1) CrashDebugger.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.39 llvm/tools/bugpoint/CrashDebugger.cpp:1.40 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.39 Thu Dec 16 17:04:20 2004 +++ llvm/tools/bugpoint/CrashDebugger.cpp Sat Jan 22 10:30:58 2005 @@ -431,7 +431,7 @@ BD.compileProgram(M); std::cerr << '\n'; return false; - } catch (ToolExecutionError &TEE) { + } catch (ToolExecutionError &) { std::cerr << "\n"; return true; // Tool is still crashing. } From jeffc at jolt-lang.org Sat Jan 22 10:32:58 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 10:32:58 -0600 Subject: [llvm-commits] CVS: llvm/win32/Support/Support.vcproj Message-ID: <200501221632.KAA27195@zion.cs.uiuc.edu> Changes in directory llvm/win32/Support: Support.vcproj updated: 1.9 -> 1.10 --- Log message: Don't exclude FileUtilies and ToolRunner from VC++ build --- Diffs of the changes: (+3 -6) Support.vcproj | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) Index: llvm/win32/Support/Support.vcproj diff -u llvm/win32/Support/Support.vcproj:1.9 llvm/win32/Support/Support.vcproj:1.10 --- llvm/win32/Support/Support.vcproj:1.9 Sat Jan 1 15:34:18 2005 +++ llvm/win32/Support/Support.vcproj Sat Jan 22 10:32:47 2005 @@ -128,14 +128,12 @@ + Name="Debug|Win32"> + Name="Release|Win32"> @@ -179,8 +177,7 @@ + Name="Debug|Win32"> From lattner at cs.uiuc.edu Sat Jan 22 11:32:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 11:32:58 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501221732.j0MHWw5S005234@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.10 -> 1.11 --- Log message: Seperate asmstring parsing from emission. This allows the code to be simpler and more understandable. It also allows us to do simple things like fold consequtive literal strings together. For example, instead of emitting this for the X86 backend: O << "adc" << "l" << " "; we now generate this: O << "adcl "; *whoa* :) This shrinks the X86 asmwriters from 62729->58267 and 65176->58644 bytes for the intel/att asm writers respectively. --- Diffs of the changes: (+153 -86) AsmWriterEmitter.cpp | 239 ++++++++++++++++++++++++++++++++------------------- 1 files changed, 153 insertions(+), 86 deletions(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.10 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.11 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.10 Fri Jan 21 18:35:22 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 11:32:42 2005 @@ -25,6 +25,154 @@ C == '_'; } +namespace { + struct AsmWriterOperand { + enum { isLiteralTextOperand, isMachineInstrOperand } OperandType; + + /// Str - For isLiteralTextOperand, this IS the literal text. For + /// isMachineInstrOperand, this is the PrinterMethodName for the operand. + std::string Str; + + /// MiOpNo - For isMachineInstrOperand, this is the operand number of the + /// machine instruction. + unsigned MIOpNo; + + /// OpVT - For isMachineInstrOperand, this is the value type for the + /// operand. + MVT::ValueType OpVT; + + AsmWriterOperand(const std::string &LitStr) + : OperandType(isLiteralTextOperand), Str(LitStr) {} + + AsmWriterOperand(const std::string &Printer, unsigned OpNo, + MVT::ValueType VT) : OperandType(isMachineInstrOperand), + Str(Printer), MIOpNo(OpNo), OpVT(VT){} + + void EmitCode(std::ostream &OS) const; + }; + + struct AsmWriterInst { + std::vector Operands; + + void ParseAsmString(const CodeGenInstruction &CGI, unsigned Variant); + void EmitCode(std::ostream &OS) const { + for (unsigned i = 0, e = Operands.size(); i != e; ++i) + Operands[i].EmitCode(OS); + } + private: + void AddLiteralString(const std::string &Str) { + // If the last operand was already a literal text string, append this to + // it, otherwise add a new operand. + if (!Operands.empty() && + Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand) + Operands.back().Str.append(Str); + else + Operands.push_back(AsmWriterOperand(Str)); + } + }; +} + + +void AsmWriterOperand::EmitCode(std::ostream &OS) const { + if (OperandType == isLiteralTextOperand) + OS << "O << \"" << Str << "\"; "; + else + OS << Str << "(MI, " << MIOpNo << ", MVT::" << getName(OpVT) << "); "; +} + + +/// ParseAsmString - Parse the specified Instruction's AsmString into this +/// AsmWriterInst. +/// +void AsmWriterInst::ParseAsmString(const CodeGenInstruction &CGI, + unsigned Variant) { + bool inVariant = false; // True if we are inside a {.|.|.} region. + + const std::string &AsmString = CGI.AsmString; + std::string::size_type LastEmitted = 0; + while (LastEmitted != AsmString.size()) { + std::string::size_type DollarPos = + AsmString.find_first_of("${|}", LastEmitted); + if (DollarPos == std::string::npos) DollarPos = AsmString.size(); + + // Emit a constant string fragment. + if (DollarPos != LastEmitted) { + // TODO: this should eventually handle escaping. + AddLiteralString(std::string(AsmString.begin()+LastEmitted, + AsmString.begin()+DollarPos)); + LastEmitted = DollarPos; + } else if (AsmString[DollarPos] == '{') { + if (inVariant) + throw "Nested variants found for instruction '" + CGI.Name + "'!"; + LastEmitted = DollarPos+1; + inVariant = true; // We are now inside of the variant! + for (unsigned i = 0; i != Variant; ++i) { + // Skip over all of the text for an irrelevant variant here. The + // next variant starts at |, or there may not be text for this + // variant if we see a }. + std::string::size_type NP = + AsmString.find_first_of("|}", LastEmitted); + if (NP == std::string::npos) + throw "Incomplete variant for instruction '" + CGI.Name + "'!"; + LastEmitted = NP+1; + if (AsmString[NP] == '}') { + inVariant = false; // No text for this variant. + break; + } + } + } else if (AsmString[DollarPos] == '|') { + if (!inVariant) + throw "'|' character found outside of a variant in instruction '" + + CGI.Name + "'!"; + // Move to the end of variant list. + std::string::size_type NP = AsmString.find('}', LastEmitted); + if (NP == std::string::npos) + throw "Incomplete variant for instruction '" + CGI.Name + "'!"; + LastEmitted = NP+1; + inVariant = false; + } else if (AsmString[DollarPos] == '}') { + if (!inVariant) + throw "'}' character found outside of a variant in instruction '" + + CGI.Name + "'!"; + LastEmitted = DollarPos+1; + inVariant = false; + } else if (DollarPos+1 != AsmString.size() && + AsmString[DollarPos+1] == '$') { + AddLiteralString("$"); // "$$" -> $ + LastEmitted = DollarPos+2; + } else { + // Get the name of the variable. + // TODO: should eventually handle ${foo}bar as $foo + std::string::size_type VarEnd = DollarPos+1; + while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) + ++VarEnd; + std::string VarName(AsmString.begin()+DollarPos+1, + AsmString.begin()+VarEnd); + if (VarName.empty()) + throw "Stray '$' in '" + CGI.Name + "' asm string, maybe you want $$?"; + + unsigned OpNo = CGI.getOperandNamed(VarName); + + // If this is a two-address instruction and we are not accessing the + // 0th operand, remove an operand. + unsigned MIOp = CGI.OperandList[OpNo].MIOperandNo; + if (CGI.isTwoAddress && MIOp != 0) { + if (MIOp == 1) + throw "Should refer to operand #0 instead of #1 for two-address" + " instruction '" + CGI.Name + "'!"; + --MIOp; + } + + Operands.push_back(AsmWriterOperand(CGI.OperandList[OpNo].PrinterMethodName, + MIOp, CGI.OperandList[OpNo].Ty)); + LastEmitted = VarEnd; + } + } + + AddLiteralString("\\n"); +} + + void AsmWriterEmitter::run(std::ostream &O) { EmitSourceFileHeader("Assembly Writer Source Fragment", O); @@ -45,96 +193,15 @@ std::string Namespace = Target.inst_begin()->second.Namespace; - bool inVariant = false; // True if we are inside a {.|.|.} region. - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), E = Target.inst_end(); I != E; ++I) if (!I->second.AsmString.empty()) { - const std::string &AsmString = I->second.AsmString; - O << " case " << Namespace << "::" << I->first << ": O "; - - std::string::size_type LastEmitted = 0; - while (LastEmitted != AsmString.size()) { - std::string::size_type DollarPos = - AsmString.find_first_of("${|}", LastEmitted); - if (DollarPos == std::string::npos) DollarPos = AsmString.size(); - - // Emit a constant string fragment. - if (DollarPos != LastEmitted) { - // TODO: this should eventually handle escaping. - O << " << \"" << std::string(AsmString.begin()+LastEmitted, - AsmString.begin()+DollarPos) << "\""; - LastEmitted = DollarPos; - } else if (AsmString[DollarPos] == '{') { - if (inVariant) - throw "Nested variants found for instruction '" + I->first + "'!"; - LastEmitted = DollarPos+1; - inVariant = true; // We are now inside of the variant! - for (unsigned i = 0; i != Variant; ++i) { - // Skip over all of the text for an irrelevant variant here. The - // next variant starts at |, or there may not be text for this - // variant if we see a }. - std::string::size_type NP = - AsmString.find_first_of("|}", LastEmitted); - if (NP == std::string::npos) - throw "Incomplete variant for instruction '" + I->first + "'!"; - LastEmitted = NP+1; - if (AsmString[NP] == '}') { - inVariant = false; // No text for this variant. - break; - } - } - } else if (AsmString[DollarPos] == '|') { - if (!inVariant) - throw "'|' character found outside of a variant in instruction '" - + I->first + "'!"; - // Move to the end of variant list. - std::string::size_type NP = AsmString.find('}', LastEmitted); - if (NP == std::string::npos) - throw "Incomplete variant for instruction '" + I->first + "'!"; - LastEmitted = NP+1; - inVariant = false; - } else if (AsmString[DollarPos] == '}') { - if (!inVariant) - throw "'}' character found outside of a variant in instruction '" - + I->first + "'!"; - LastEmitted = DollarPos+1; - inVariant = false; - } else if (DollarPos+1 != AsmString.size() && - AsmString[DollarPos+1] == '$') { - O << " << '$'"; // "$$" -> $ - LastEmitted = DollarPos+2; - } else { - // Get the name of the variable. - // TODO: should eventually handle ${foo}bar as $foo - std::string::size_type VarEnd = DollarPos+1; - while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) - ++VarEnd; - std::string VarName(AsmString.begin()+DollarPos+1, - AsmString.begin()+VarEnd); - if (VarName.empty()) - throw "Stray '$' in '" + I->first + - "' asm string, maybe you want $$?"; - unsigned OpNo = I->second.getOperandNamed(VarName); - - // If this is a two-address instruction and we are not accessing the - // 0th operand, remove an operand. - unsigned MIOp = I->second.OperandList[OpNo].MIOperandNo; - if (I->second.isTwoAddress && MIOp != 0) { - if (MIOp == 1) - throw "Should refer to operand #0 instead of #1 for two-address" - " instruction '" + I->first + "'!"; - --MIOp; - } - - O << "; " << I->second.OperandList[OpNo].PrinterMethodName - << "(MI, " << MIOp << ", MVT::" - << getName(I->second.OperandList[OpNo].Ty) << "); O "; - LastEmitted = VarEnd; - } - } + O << " case " << Namespace << "::" << I->first << ": "; - O << " << '\\n'; break;\n"; + AsmWriterInst AWI; + AWI.ParseAsmString(I->second, Variant); + AWI.EmitCode(O); + O << " break;\n"; } O << " }\n" From llvm at cs.uiuc.edu Sat Jan 22 11:34:45 2005 From: llvm at cs.uiuc.edu (LLVM) Date: Sat, 22 Jan 2005 11:34:45 -0600 Subject: [llvm-commits] CVS: llvm/win32/bugpoint/ Message-ID: <200501221734.LAA27529@zion.cs.uiuc.edu> Changes in directory llvm/win32/bugpoint: --- Log message: Directory /var/cvs/llvm/llvm/win32/bugpoint added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From jeffc at jolt-lang.org Sat Jan 22 11:35:42 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:35:42 -0600 Subject: [llvm-commits] CVS: llvm/win32/bugpoint/bugpoint.vcproj Message-ID: <200501221735.LAA27557@zion.cs.uiuc.edu> Changes in directory llvm/win32/bugpoint: bugpoint.vcproj added (r1.1) --- Log message: Add (non-working) project bugpoint to Visual Studio --- Diffs of the changes: (+164 -0) bugpoint.vcproj | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 164 insertions(+) Index: llvm/win32/bugpoint/bugpoint.vcproj diff -c /dev/null llvm/win32/bugpoint/bugpoint.vcproj:1.1 *** /dev/null Sat Jan 22 11:35:40 2005 --- llvm/win32/bugpoint/bugpoint.vcproj Sat Jan 22 11:35:30 2005 *************** *** 0 **** --- 1,164 ---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From jeffc at jolt-lang.org Sat Jan 22 11:35:42 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:35:42 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200501221735.LAA27553@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.23 -> 1.24 --- Log message: Add (non-working) project bugpoint to Visual Studio --- Diffs of the changes: (+18 -0) llvm.sln | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.23 llvm/win32/llvm.sln:1.24 --- llvm/win32/llvm.sln:1.23 Wed Jan 19 23:19:40 2005 +++ llvm/win32/llvm.sln Sat Jan 22 11:35:30 2005 @@ -229,6 +229,20 @@ {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bugpoint", "bugpoint\bugpoint.vcproj", "{57249192-8E29-4D85-8B7A-FEFF1760B1DA}" + ProjectSection(ProjectDependencies) = postProject + {0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} + {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -351,6 +365,10 @@ {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Debug.Build.0 = Debug|Win32 {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Release.ActiveCfg = Release|Win32 {DF8506B5-28D2-4D2E-9A6C-57D5BC98BF76}.Release.Build.0 = Release|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug.ActiveCfg = Debug|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug.Build.0 = Debug|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release.ActiveCfg = Release|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From jeffc at jolt-lang.org Sat Jan 22 11:36:30 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:30 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200501221736.LAA27624@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.94 -> 1.95 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+3 -1) gccld.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.94 llvm/tools/gccld/gccld.cpp:1.95 --- llvm/tools/gccld/gccld.cpp:1.94 Mon Dec 20 21:24:02 2004 +++ llvm/tools/gccld/gccld.cpp Sat Jan 22 11:36:16 2005 @@ -238,7 +238,9 @@ // Create the output file. std::string RealBytecodeOutput = OutputFilename; if (!LinkAsLibrary) RealBytecodeOutput += ".bc"; - std::ofstream Out(RealBytecodeOutput.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + std::ofstream Out(RealBytecodeOutput.c_str(), io_mode); if (!Out.good()) return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput + "' for writing!"); From jeffc at jolt-lang.org Sat Jan 22 11:36:30 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200501221736.LAA27626@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.34 -> 1.35 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+3 -2) FileUtilities.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.34 llvm/lib/Support/FileUtilities.cpp:1.35 --- llvm/lib/Support/FileUtilities.cpp:1.34 Wed Dec 22 04:24:43 2004 +++ llvm/lib/Support/FileUtilities.cpp Sat Jan 22 11:36:16 2005 @@ -27,13 +27,14 @@ /// bool llvm::DiffFiles(const std::string &FileA, const std::string &FileB, std::string *Error) { - std::ifstream FileAStream(FileA.c_str()); + std::ios::openmode io_mode = std::ios::in | std::ios::binary; + std::ifstream FileAStream(FileA.c_str(), io_mode); if (!FileAStream) { if (Error) *Error = "Couldn't open file '" + FileA + "'"; return true; } - std::ifstream FileBStream(FileB.c_str()); + std::ifstream FileBStream(FileB.c_str(), io_mode); if (!FileBStream) { if (Error) *Error = "Couldn't open file '" + FileB + "'"; return true; From jeffc at jolt-lang.org Sat Jan 22 11:36:30 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:30 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200501221736.LAA27630@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.107 -> 1.108 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+4 -1) gccas.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.107 llvm/tools/gccas/gccas.cpp:1.108 --- llvm/tools/gccas/gccas.cpp:1.107 Sat Jan 1 16:10:32 2005 +++ llvm/tools/gccas/gccas.cpp Sat Jan 22 11:36:16 2005 @@ -164,9 +164,12 @@ } if (OutputFilename == "-") + // FIXME: cout is not binary! Out = &std::cout; else { - Out = new std::ofstream(OutputFilename.c_str(), std::ios::out); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + Out = new std::ofstream(OutputFilename.c_str(), io_mode); // Make sure that the Out file gets unlinked from the disk if we get a // signal From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-as/llvm-as.cpp Message-ID: <200501221736.LAA27647@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-as: llvm-as.cpp updated: 1.41 -> 1.42 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+16 -15) llvm-as.cpp | 31 ++++++++++++++++--------------- 1 files changed, 16 insertions(+), 15 deletions(-) Index: llvm/tools/llvm-as/llvm-as.cpp diff -u llvm/tools/llvm-as/llvm-as.cpp:1.41 llvm/tools/llvm-as/llvm-as.cpp:1.42 --- llvm/tools/llvm-as/llvm-as.cpp:1.41 Sat Jan 1 18:08:46 2005 +++ llvm/tools/llvm-as/llvm-as.cpp Sat Jan 22 11:36:17 2005 @@ -84,25 +84,26 @@ << "Use -f command line argument to force output\n"; return 1; } - Out = new std::ofstream(OutputFilename.c_str(), std::ios_base::out | - std::ios_base::trunc | std::ios_base::binary); + Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | + std::ios::trunc | std::ios::binary); } else { // Specified stdout - Out = &std::cout; + // FIXME: cout is not binary! + Out = &std::cout; } } else { if (InputFilename == "-") { - OutputFilename = "-"; - Out = &std::cout; + OutputFilename = "-"; + Out = &std::cout; } else { - std::string IFN = InputFilename; - int Len = IFN.length(); - if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') { - // Source ends in .ll - OutputFilename = std::string(IFN.begin(), IFN.end()-3); + std::string IFN = InputFilename; + int Len = IFN.length(); + if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') { + // Source ends in .ll + OutputFilename = std::string(IFN.begin(), IFN.end()-3); } else { - OutputFilename = IFN; // Append a .bc to it - } - OutputFilename += ".bc"; + OutputFilename = IFN; // Append a .bc to it + } + OutputFilename += ".bc"; if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! @@ -112,8 +113,8 @@ return 1; } - Out = new std::ofstream(OutputFilename.c_str(), std::ios_base::out | - std::ios_base::trunc | std::ios_base::binary); + Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | + std::ios::trunc | std::ios::binary); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-link/llvm-link.cpp Message-ID: <200501221736.LAA27649@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-link: llvm-link.cpp updated: 1.54 -> 1.55 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+4 -1) llvm-link.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/tools/llvm-link/llvm-link.cpp diff -u llvm/tools/llvm-link/llvm-link.cpp:1.54 llvm/tools/llvm-link/llvm-link.cpp:1.55 --- llvm/tools/llvm-link/llvm-link.cpp:1.54 Sat Jan 1 16:10:32 2005 +++ llvm/tools/llvm-link/llvm-link.cpp Sat Jan 22 11:36:17 2005 @@ -112,6 +112,7 @@ if (DumpAsm) std::cerr << "Here's the assembly:\n" << Composite.get(); + // FIXME: cout is not binary! std::ostream *Out = &std::cout; // Default to printing to stdout... if (OutputFilename != "-") { if (!Force && std::ifstream(OutputFilename.c_str())) { @@ -121,7 +122,9 @@ << "Use -f command line argument to force output\n"; return 1; } - Out = new std::ofstream(OutputFilename.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + Out = new std::ofstream(OutputFilename.c_str(), io_mode); if (!Out->good()) { std::cerr << argv[0] << ": error opening '" << OutputFilename << "'!\n"; return 1; From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/extract/extract.cpp Message-ID: <200501221736.LAA27661@zion.cs.uiuc.edu> Changes in directory llvm/tools/extract: extract.cpp updated: 1.26 -> 1.27 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+6 -4) extract.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/tools/extract/extract.cpp diff -u llvm/tools/extract/extract.cpp:1.26 llvm/tools/extract/extract.cpp:1.27 --- llvm/tools/extract/extract.cpp:1.26 Wed Dec 29 23:36:07 2004 +++ llvm/tools/extract/extract.cpp Sat Jan 22 11:36:16 2005 @@ -63,9 +63,8 @@ return 1; } - // In addition to deleting all other functions, we also want to spiff it up a - // little bit. Do this now. - // + // In addition to deleting all other functions, we also want to spiff it + // up a little bit. Do this now. PassManager Passes; Passes.add(new TargetData("extract", M.get())); // Use correct TargetData // Either isolate the function or delete it from the Module @@ -84,8 +83,11 @@ << "Use -f command line argument to force output\n"; return 1; } - Out = new std::ofstream(OutputFilename.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + Out = new std::ofstream(OutputFilename.c_str(), io_mode); } else { // Specified stdout + // FIXME: cout is not binary! Out = &std::cout; } From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.cpp Message-ID: <200501221736.LAA27634@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.cpp updated: 1.20 -> 1.21 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+3 -1) llvm-ld.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.20 llvm/tools/llvm-ld/llvm-ld.cpp:1.21 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.20 Wed Dec 29 23:36:07 2004 +++ llvm/tools/llvm-ld/llvm-ld.cpp Sat Jan 22 11:36:17 2005 @@ -186,7 +186,9 @@ void GenerateBytecode(Module* M, const std::string& FileName) { // Create the output file. - std::ofstream Out(FileName.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + std::ofstream Out(FileName.c_str(), io_mode); if (!Out.good()) { PrintAndReturn("error opening '" + FileName + "' for writing!"); return; From jeffc at jolt-lang.org Sat Jan 22 11:37:24 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:37:24 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/OptimizerDriver.cpp Message-ID: <200501221737.LAA27682@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: OptimizerDriver.cpp updated: 1.27 -> 1.28 --- Log message: oops --- Diffs of the changes: (+1 -1) OptimizerDriver.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.27 llvm/tools/bugpoint/OptimizerDriver.cpp:1.28 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.27 Sat Jan 22 11:36:16 2005 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Sat Jan 22 11:37:13 2005 @@ -19,7 +19,7 @@ // independent code co-exist via conditional compilation until it is verified // that the new code works correctly on Unix. -#define PLATFORMINDEPENDENT +//#define PLATFORMINDEPENDENT #include "BugDriver.h" #include "llvm/Module.h" From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Message-ID: <200501221736.LAA27640@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveWriter.cpp updated: 1.13 -> 1.14 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+4 -2) ArchiveWriter.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.13 llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.14 --- llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.13 Sun Dec 19 21:23:46 2004 +++ llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Sat Jan 22 11:36:16 2005 @@ -375,7 +375,9 @@ // Ensure we can remove the temporary even in the face of an exception try { // Create archive file for output. - std::ofstream ArchiveFile(TmpArchive.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + std::ofstream ArchiveFile(TmpArchive.c_str(), io_mode); // Check for errors opening or creating archive file. if ( !ArchiveFile.is_open() || ArchiveFile.bad() ) { @@ -413,7 +415,7 @@ const char* base = (const char*) arch.map(); // Open the final file to write and check it. - std::ofstream FinalFile(archPath.c_str()); + std::ofstream FinalFile(archPath.c_str(), io_mode); if ( !FinalFile.is_open() || FinalFile.bad() ) { throw std::string("Error opening archive file: ") + archPath.toString(); } From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Message-ID: <200501221736.LAA27645@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp updated: 1.25 -> 1.26 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+3 -1) llvm-ar.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -u llvm/tools/llvm-ar/llvm-ar.cpp:1.25 llvm/tools/llvm-ar/llvm-ar.cpp:1.26 --- llvm/tools/llvm-ar/llvm-ar.cpp:1.25 Wed Dec 15 15:58:03 2004 +++ llvm/tools/llvm-ar/llvm-ar.cpp Sat Jan 22 11:36:17 2005 @@ -436,7 +436,9 @@ } // Open up a file stream for writing - std::ofstream file(I->getPath().c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + std::ofstream file(I->getPath().c_str(), io_mode); // Get the data and its length const char* data = reinterpret_cast(I->getData()); From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/OptimizerDriver.cpp Message-ID: <200501221736.LAA27663@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: OptimizerDriver.cpp updated: 1.26 -> 1.27 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+21 -3) OptimizerDriver.cpp | 24 +++++++++++++++++++++--- 1 files changed, 21 insertions(+), 3 deletions(-) Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.26 llvm/tools/bugpoint/OptimizerDriver.cpp:1.27 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.26 Thu Dec 16 17:04:20 2004 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Sat Jan 22 11:36:16 2005 @@ -15,6 +15,12 @@ // //===----------------------------------------------------------------------===// +// Note: as a short term hack, the old Unix-specific code and platform- +// independent code co-exist via conditional compilation until it is verified +// that the new code works correctly on Unix. + +#define PLATFORMINDEPENDENT + #include "BugDriver.h" #include "llvm/Module.h" #include "llvm/PassManager.h" @@ -24,9 +30,11 @@ #include "llvm/Support/FileUtilities.h" #include "llvm/System/Path.h" #include +#ifndef PLATFORMINDEPENDENT #include #include #include +#endif using namespace llvm; /// writeProgramToFile - This writes the current "Program" to the named bytecode @@ -34,7 +42,9 @@ /// bool BugDriver::writeProgramToFile(const std::string &Filename, Module *M) const { - std::ofstream Out(Filename.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + std::ofstream Out(Filename.c_str(), io_mode); if (!Out.good()) return true; WriteBytecodeToFile(M ? M : Program, Out, /*compression=*/true); return false; @@ -76,7 +86,9 @@ static void RunChild(Module *Program,const std::vector &Passes, const std::string &OutFilename) { - std::ofstream OutFile(OutFilename.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + std::ofstream OutFile(OutFilename.c_str(), io_mode); if (!OutFile.good()) { std::cerr << "Error opening bytecode file: " << OutFilename << "\n"; exit(1); @@ -119,6 +131,7 @@ uniqueFilename.makeUnique(); OutputFilename = uniqueFilename.toString(); +#ifndef PLATFORMINDEPENDENT pid_t child_pid; switch (child_pid = fork()) { case -1: // Error occurred @@ -139,12 +152,16 @@ } bool ExitedOK = WIFEXITED(Status) && WEXITSTATUS(Status) == 0; +#else + bool ExitedOK = false; +#endif // If we are supposed to delete the bytecode file or if the passes crashed, // remove it now. This may fail if the file was never created, but that's ok. if (DeleteOutput || !ExitedOK) sys::Path(OutputFilename).destroyFile(); - + +#ifndef PLATFORMINDEPENDENT if (!Quiet) { if (ExitedOK) std::cout << "Success!\n"; @@ -159,6 +176,7 @@ else std::cout << "Failed for unknown reason!\n"; } +#endif // Was the child successful? return !ExitedOK; From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200501221736.LAA27669@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.124 -> 1.125 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+4 -4) Verifier.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.124 llvm/lib/VMCore/Verifier.cpp:1.125 --- llvm/lib/VMCore/Verifier.cpp:1.124 Wed Dec 15 14:23:49 2004 +++ llvm/lib/VMCore/Verifier.cpp Sat Jan 22 11:36:16 2005 @@ -78,17 +78,17 @@ Verifier() : Broken(false), RealPass(true), action(AbortProcessAction), - DS(0), msgs( std::ios_base::app | std::ios_base::out ) {} + DS(0), msgs( std::ios::app | std::ios::out ) {} Verifier( VerifierFailureAction ctn ) : Broken(false), RealPass(true), action(ctn), DS(0), - msgs( std::ios_base::app | std::ios_base::out ) {} + msgs( std::ios::app | std::ios::out ) {} Verifier(bool AB ) : Broken(false), RealPass(true), action( AB ? AbortProcessAction : PrintMessageAction), DS(0), - msgs( std::ios_base::app | std::ios_base::out ) {} + msgs( std::ios::app | std::ios::out ) {} Verifier(DominatorSet &ds) : Broken(false), RealPass(false), action(PrintMessageAction), - DS(&ds), msgs( std::ios_base::app | std::ios_base::out ) {} + DS(&ds), msgs( std::ios::app | std::ios::out ) {} bool doInitialization(Module &M) { From jeffc at jolt-lang.org Sat Jan 22 11:36:31 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 11:36:31 -0600 Subject: [llvm-commits] CVS: llvm/tools/opt/opt.cpp Message-ID: <200501221736.LAA27651@zion.cs.uiuc.edu> Changes in directory llvm/tools/opt: opt.cpp updated: 1.105 -> 1.106 --- Log message: Use binary mode for reading/writing bytecode files --- Diffs of the changes: (+6 -3) opt.cpp | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/tools/opt/opt.cpp diff -u llvm/tools/opt/opt.cpp:1.105 llvm/tools/opt/opt.cpp:1.106 --- llvm/tools/opt/opt.cpp:1.105 Thu Jan 6 01:01:08 2005 +++ llvm/tools/opt/opt.cpp Sat Jan 22 11:36:17 2005 @@ -95,6 +95,7 @@ } // Figure out what stream we are supposed to write to... + // FIXME: cout is not binary! std::ostream *Out = &std::cout; // Default to printing to stdout... if (OutputFilename != "-") { if (!Force && std::ifstream(OutputFilename.c_str())) { @@ -104,7 +105,9 @@ << "Use -f command line argument to force output\n"; return 1; } - Out = new std::ofstream(OutputFilename.c_str()); + std::ios::openmode io_mode = std::ios::out | std::ios::trunc | + std::ios::binary; + Out = new std::ofstream(OutputFilename.c_str(), io_mode); if (!Out->good()) { std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; @@ -117,8 +120,8 @@ } // If the output is set to be emitted to standard out, and standard out is a - // console, print out a warning message and refuse to do it. We don't impress - // anyone by spewing tons of binary goo to a terminal. + // console, print out a warning message and refuse to do it. We don't + // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && CheckBytecodeOutputToConsole(Out,!Quiet)) { NoOutput = true; } From lattner at cs.uiuc.edu Sat Jan 22 11:40:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 11:40:53 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501221740.j0MHercI005570@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.11 -> 1.12 --- Log message: Minor refactoring, no functionality change. --- Diffs of the changes: (+19 -14) AsmWriterEmitter.cpp | 33 +++++++++++++++++++-------------- 1 files changed, 19 insertions(+), 14 deletions(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.11 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.12 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.11 Sat Jan 22 11:32:42 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 11:40:38 2005 @@ -53,8 +53,9 @@ struct AsmWriterInst { std::vector Operands; + const CodeGenInstruction *CGI; - void ParseAsmString(const CodeGenInstruction &CGI, unsigned Variant); + AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant); void EmitCode(std::ostream &OS) const { for (unsigned i = 0, e = Operands.size(); i != e; ++i) Operands[i].EmitCode(OS); @@ -84,8 +85,8 @@ /// ParseAsmString - Parse the specified Instruction's AsmString into this /// AsmWriterInst. /// -void AsmWriterInst::ParseAsmString(const CodeGenInstruction &CGI, - unsigned Variant) { +AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) { + this->CGI = &CGI; bool inVariant = false; // True if we are inside a {.|.|.} region. const std::string &AsmString = CGI.AsmString; @@ -152,10 +153,11 @@ throw "Stray '$' in '" + CGI.Name + "' asm string, maybe you want $$?"; unsigned OpNo = CGI.getOperandNamed(VarName); + CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo]; // If this is a two-address instruction and we are not accessing the // 0th operand, remove an operand. - unsigned MIOp = CGI.OperandList[OpNo].MIOperandNo; + unsigned MIOp = OpInfo.MIOperandNo; if (CGI.isTwoAddress && MIOp != 0) { if (MIOp == 1) throw "Should refer to operand #0 instead of #1 for two-address" @@ -163,8 +165,8 @@ --MIOp; } - Operands.push_back(AsmWriterOperand(CGI.OperandList[OpNo].PrinterMethodName, - MIOp, CGI.OperandList[OpNo].Ty)); + Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, + MIOp, OpInfo.Ty)); LastEmitted = VarEnd; } } @@ -193,17 +195,20 @@ std::string Namespace = Target.inst_begin()->second.Namespace; + std::vector Instructions; + for (CodeGenTarget::inst_iterator I = Target.inst_begin(), E = Target.inst_end(); I != E; ++I) - if (!I->second.AsmString.empty()) { - O << " case " << Namespace << "::" << I->first << ": "; - - AsmWriterInst AWI; - AWI.ParseAsmString(I->second, Variant); - AWI.EmitCode(O); - O << " break;\n"; - } + if (!I->second.AsmString.empty()) + Instructions.push_back(AsmWriterInst(I->second, Variant)); + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { + O << " case " << Namespace << "::" + << Instructions[i].CGI->Name << ": "; + Instructions[i].EmitCode(O); + O << " break;\n"; + } + O << " }\n" " return true;\n" "}\n"; From lattner at cs.uiuc.edu Sat Jan 22 12:19:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 12:19:13 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501221819.j0MIJDmR008095@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.12 -> 1.13 --- Log message: Fix the ::: problem --- Diffs of the changes: (+1 -1) AsmWriterEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.12 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.13 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.12 Sat Jan 22 11:40:38 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 12:18:59 2005 @@ -204,7 +204,7 @@ for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { O << " case " << Namespace << "::" - << Instructions[i].CGI->Name << ": "; + << Instructions[i].CGI->TheDef->getName() << ": "; Instructions[i].EmitCode(O); O << " break;\n"; } From lattner at cs.uiuc.edu Sat Jan 22 12:38:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 12:38:28 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501221838.j0MIcS3A010362@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.13 -> 1.14 --- Log message: Implement factoring of instruction pattern strings. In particular, instead of emitting code like this: case PPC::ADD: O << "add "; printOperand(MI, 0, MVT::i64); O << ", "; prin tOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n '; break; case PPC::ADDC: O << "addc "; printOperand(MI, 0, MVT::i64); O << ", "; pr intOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << ' \n'; break; case PPC::ADDE: O << "adde "; printOperand(MI, 0, MVT::i64); O << ", "; pr intOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << ' \n'; break; ... Emit code like this: case PPC::ADD: case PPC::ADDC: case PPC::ADDE: ... switch (MI->getOpcode()) { case PPC::ADD: O << "add "; break; case PPC::ADDC: O << "addc "; break; case PPC::ADDE: O << "adde "; break; ... } printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << "\n"; break; This shrinks the PPC asm writer from 24785->15205 bytes (even though the new asmwriter has much more whitespace than the old one), and the X86 printers shrink quite a bit too. The important implication of this is that GCC no longer hits swap when building the PPC backend in optimized mode. Thus this fixes PR448: http://llvm.cs.uiuc.edu/PR448 . -Chris --- Diffs of the changes: (+97 -10) AsmWriterEmitter.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 97 insertions(+), 10 deletions(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.13 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.14 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.13 Sat Jan 22 12:18:59 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 12:38:13 2005 @@ -48,6 +48,12 @@ MVT::ValueType VT) : OperandType(isMachineInstrOperand), Str(Printer), MIOpNo(OpNo), OpVT(VT){} + bool operator!=(const AsmWriterOperand &Other) const { + if (OperandType != Other.OperandType || Str != Other.Str) return true; + if (OperandType == isMachineInstrOperand) + return MIOpNo != Other.MIOpNo || OpVT != Other.OpVT; + return false; + } void EmitCode(std::ostream &OS) const; }; @@ -56,10 +62,12 @@ const CodeGenInstruction *CGI; AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant); - void EmitCode(std::ostream &OS) const { - for (unsigned i = 0, e = Operands.size(); i != e; ++i) - Operands[i].EmitCode(OS); - } + + /// MatchesAllButOneString - If this instruction is exactly identical to the + /// specified instruction except for one differing literal string, return + /// the operand number of the literal string. Otherwise return ~0. + unsigned MatchesAllButOneString(const AsmWriterInst &Other) const; + private: void AddLiteralString(const std::string &Str) { // If the last operand was already a literal text string, append this to @@ -174,6 +182,85 @@ AddLiteralString("\\n"); } +/// MatchesAllButOneString - If this instruction is exactly identical to the +/// specified instruction except for one differing literal string, return +/// the operand number of the literal string. Otherwise return ~0. +unsigned AsmWriterInst::MatchesAllButOneString(const AsmWriterInst &Other)const{ + if (Operands.size() != Other.Operands.size()) return ~0; + + unsigned MismatchOperand = ~0U; + for (unsigned i = 0, e = Operands.size(); i != e; ++i) { + if (Operands[i].OperandType != Other.Operands[i].OperandType) + return ~0U; + + if (Operands[i] != Other.Operands[i]) + if (Operands[i].OperandType == AsmWriterOperand::isMachineInstrOperand || + MismatchOperand != ~0U) + return ~0U; + else + MismatchOperand = i; + } + return MismatchOperand; +} + + +/// EmitInstructions - Emit the last instruction in the vector and any other +/// instructions that are suitably similar to it. +static void EmitInstructions(std::vector &Insts, + std::ostream &O) { + AsmWriterInst FirstInst = Insts.back(); + Insts.pop_back(); + + std::vector SimilarInsts; + unsigned DifferingOperand = ~0; + for (unsigned i = Insts.size(); i != 0; --i) { + unsigned DiffOp = Insts[i-1].MatchesAllButOneString(FirstInst); + if (DiffOp != ~0U) { + if (DifferingOperand == ~0U) // First match! + DifferingOperand = DiffOp; + + // If this differs in the same operand as the rest of the instructions in + // this class, move it to the SimilarInsts list. + if (DifferingOperand == DiffOp) { + SimilarInsts.push_back(Insts[i-1]); + Insts.erase(Insts.begin()+i-1); + } + } + } + + std::string Namespace = FirstInst.CGI->Namespace; + + O << " case " << Namespace << "::" + << FirstInst.CGI->TheDef->getName() << ":\n"; + for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i) + O << " case " << Namespace << "::" + << SimilarInsts[i].CGI->TheDef->getName() << ":\n"; + for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) { + if (i != DifferingOperand) { + // If the operand is the same for all instructions, just print it. + O << " "; + FirstInst.Operands[i].EmitCode(O); + } else { + // If this is the operand that varies between all of the instructions, + // emit a switch for just this operand now. + O << " switch (MI->getOpcode()) {\n"; + O << " case " << Namespace << "::" + << FirstInst.CGI->TheDef->getName() << ": "; + FirstInst.Operands[i].EmitCode(O); + O << "break;\n"; + for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { + O << " case " << Namespace << "::" + << SimilarInsts[si].CGI->TheDef->getName() << ": "; + SimilarInsts[si].Operands[i].EmitCode(O); + O << "break;\n"; + } + O << " }"; + } + O << "\n"; + } + + O << " break;\n"; +} void AsmWriterEmitter::run(std::ostream &O) { EmitSourceFileHeader("Assembly Writer Source Fragment", O); @@ -202,13 +289,13 @@ if (!I->second.AsmString.empty()) Instructions.push_back(AsmWriterInst(I->second, Variant)); - for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { - O << " case " << Namespace << "::" - << Instructions[i].CGI->TheDef->getName() << ": "; - Instructions[i].EmitCode(O); - O << " break;\n"; - } + // Because this is a vector we want to emit from the end. Reverse all of the + // elements in the vector. + std::reverse(Instructions.begin(), Instructions.end()); + while (!Instructions.empty()) + EmitInstructions(Instructions, O); + O << " }\n" " return true;\n" "}\n"; From lattner at cs.uiuc.edu Sat Jan 22 12:45:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 12:45:50 -0600 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200501221845.j0MIjo85010456@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.287 -> 1.288 --- Log message: QOI feature implemented. --- Diffs of the changes: (+4 -3) ReleaseNotes.html | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.287 llvm/docs/ReleaseNotes.html:1.288 --- llvm/docs/ReleaseNotes.html:1.287 Sun Jan 2 22:20:21 2005 +++ llvm/docs/ReleaseNotes.html Sat Jan 22 12:45:35 2005 @@ -76,7 +76,7 @@
  1. LLVM now includes an - Inter-Procedural Sparse Conditional Constant Propagation pass, named + Interprocedural Sparse Conditional Constant Propagation pass, named -ipsccp, which is run by default at link-time.
@@ -105,7 +105,8 @@ @@ -565,7 +566,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
- Last modified: $Date: 2005/01/03 04:20:21 $ + Last modified: $Date: 2005/01/22 18:45:35 $ From jeffc at jolt-lang.org Sat Jan 22 12:50:21 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 22 Jan 2005 12:50:21 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501221850.MAA28147@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.14 -> 1.15 --- Log message: Fix VC++ compilation error --- Diffs of the changes: (+1 -0) AsmWriterEmitter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.14 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.15 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.14 Sat Jan 22 12:38:13 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 12:50:10 2005 @@ -15,6 +15,7 @@ #include "AsmWriterEmitter.h" #include "CodeGenTarget.h" #include "Record.h" +#include #include using namespace llvm; From lattner at cs.uiuc.edu Sat Jan 22 12:59:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 12:59:06 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp CodeGenTarget.h InstrInfoEmitter.cpp Message-ID: <200501221859.j0MIx6Q8010782@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.26 -> 1.27 CodeGenTarget.h updated: 1.15 -> 1.16 InstrInfoEmitter.cpp updated: 1.16 -> 1.17 --- Log message: Refactor code for numbering instructions into CodeGenTarget. --- Diffs of the changes: (+29 -10) CodeGenTarget.cpp | 16 ++++++++++++++++ CodeGenTarget.h | 6 ++++++ InstrInfoEmitter.cpp | 17 +++++++---------- 3 files changed, 29 insertions(+), 10 deletions(-) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.26 llvm/utils/TableGen/CodeGenTarget.cpp:1.27 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.26 Sat Jan 1 20:29:04 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Sat Jan 22 12:58:51 2005 @@ -198,6 +198,22 @@ return I->second; } +/// getInstructionsByEnumValue - Return all of the instructions defined by the +/// target, ordered by their enum value. +void CodeGenTarget:: +getInstructionsByEnumValue(std::vector + &NumberedInstructions) { + + // Print out the rest of the instructions now. + unsigned i = 0; + const CodeGenInstruction *PHI = &getPHIInstruction(); + NumberedInstructions.push_back(PHI); + for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) + if (&II->second != PHI) + NumberedInstructions.push_back(&II->second); +} + + /// isLittleEndianEncoding - Return whether this target encodes its instruction /// in little-endian format, i.e. bits laid out in the order [0..n] /// Index: llvm/utils/TableGen/CodeGenTarget.h diff -u llvm/utils/TableGen/CodeGenTarget.h:1.15 llvm/utils/TableGen/CodeGenTarget.h:1.16 --- llvm/utils/TableGen/CodeGenTarget.h:1.15 Wed Oct 27 11:06:27 2004 +++ llvm/utils/TableGen/CodeGenTarget.h Sat Jan 22 12:58:51 2005 @@ -93,6 +93,12 @@ inst_iterator inst_begin() const { return getInstructions().begin(); } inst_iterator inst_end() const { return Instructions.end(); } + /// getInstructionsByEnumValue - Return all of the instructions defined by the + /// target, ordered by their enum value. + void getInstructionsByEnumValue(std::vector + &NumberedInstructions); + + /// getPHIInstruction - Return the designated PHI instruction. /// const CodeGenInstruction &getPHIInstruction() const; Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.16 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.17 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.16 Sat Jan 1 20:29:04 2005 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Sat Jan 22 12:58:51 2005 @@ -26,7 +26,6 @@ // We must emit the PHI opcode first... Record *InstrInfo = Target.getInstructionSet(); - Record *PHI = InstrInfo->getValueAsDef("PHIInst"); std::string Namespace = Target.inst_begin()->second.Namespace; @@ -34,15 +33,13 @@ OS << "namespace " << Namespace << " {\n"; OS << " enum {\n"; - OS << " " << PHI->getName() << ", \t// 0 (fixed for all targets)\n"; - - // Print out the rest of the instructions now. - unsigned i = 0; - for (CodeGenTarget::inst_iterator II = Target.inst_begin(), - E = Target.inst_end(); II != E; ++II) - if (II->second.TheDef != PHI) - OS << " " << II->first << ", \t// " << ++i << "\n"; - + std::vector NumberedInstructions; + Target.getInstructionsByEnumValue(NumberedInstructions); + + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { + OS << " " << NumberedInstructions[i]->TheDef->getName() + << ", \t// " << i << "\n"; + } OS << " };\n"; if (!Namespace.empty()) OS << "}\n"; From lattner at cs.uiuc.edu Sat Jan 22 13:22:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 13:22:38 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501221922.j0MJMcFZ013364@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.15 -> 1.16 --- Log message: Implement *even more* factoring. In particular, if all of the instruction strings starts out with a constant string, we emit the string first, using a table lookup (instead of a switch statement). Because this is usually the opcode portion of the asm string, the differences between the instructions have now been greatly reduced. This allows many more case statements to be grouped together. This patch also allows instruction cases to be grouped together when the instruction patterns are exactly identical (common after the opcode string has been ripped off), and when the differing operand is a MachineInstr operand that needs to be formatted. The end result of this is a mean and lean generated AsmPrinter! --- Diffs of the changes: (+62 -20) AsmWriterEmitter.cpp | 82 ++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 62 insertions(+), 20 deletions(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.15 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.16 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.15 Sat Jan 22 12:50:10 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 13:22:23 2005 @@ -64,10 +64,10 @@ AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant); - /// MatchesAllButOneString - If this instruction is exactly identical to the - /// specified instruction except for one differing literal string, return - /// the operand number of the literal string. Otherwise return ~0. - unsigned MatchesAllButOneString(const AsmWriterInst &Other) const; + /// MatchesAllButOneOp - If this instruction is exactly identical to the + /// specified instruction except for one differing operand, return the + /// differing operand number. Otherwise return ~0. + unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const; private: void AddLiteralString(const std::string &Str) { @@ -183,21 +183,18 @@ AddLiteralString("\\n"); } -/// MatchesAllButOneString - If this instruction is exactly identical to the -/// specified instruction except for one differing literal string, return -/// the operand number of the literal string. Otherwise return ~0. -unsigned AsmWriterInst::MatchesAllButOneString(const AsmWriterInst &Other)const{ - if (Operands.size() != Other.Operands.size()) return ~0; +/// MatchesAllButOneOp - If this instruction is exactly identical to the +/// specified instruction except for one differing operand, return the differing +/// operand number. If more than one operand mismatches, return ~1, otherwise +/// if the instructions are identical return ~0. +unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{ + if (Operands.size() != Other.Operands.size()) return ~1; unsigned MismatchOperand = ~0U; for (unsigned i = 0, e = Operands.size(); i != e; ++i) { - if (Operands[i].OperandType != Other.Operands[i].OperandType) - return ~0U; - if (Operands[i] != Other.Operands[i]) - if (Operands[i].OperandType == AsmWriterOperand::isMachineInstrOperand || - MismatchOperand != ~0U) - return ~0U; + if (MismatchOperand != ~0U) // Already have one mismatch? + return ~1U; else MismatchOperand = i; } @@ -215,14 +212,14 @@ std::vector SimilarInsts; unsigned DifferingOperand = ~0; for (unsigned i = Insts.size(); i != 0; --i) { - unsigned DiffOp = Insts[i-1].MatchesAllButOneString(FirstInst); - if (DiffOp != ~0U) { + unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst); + if (DiffOp != ~1U) { if (DifferingOperand == ~0U) // First match! DifferingOperand = DiffOp; // If this differs in the same operand as the rest of the instructions in // this class, move it to the SimilarInsts list. - if (DifferingOperand == DiffOp) { + if (DifferingOperand == DiffOp || DiffOp == ~0U) { SimilarInsts.push_back(Insts[i-1]); Insts.erase(Insts.begin()+i-1); } @@ -278,8 +275,6 @@ "/// it returns false.\n" "bool " << Target.getName() << ClassName << "::printInstruction(const MachineInstr *MI) {\n"; - O << " switch (MI->getOpcode()) {\n" - " default: return false;\n"; std::string Namespace = Target.inst_begin()->second.Namespace; @@ -290,9 +285,56 @@ if (!I->second.AsmString.empty()) Instructions.push_back(AsmWriterInst(I->second, Variant)); + // If all of the instructions start with a constant string (a very very common + // occurance), emit all of the constant strings as a big table lookup instead + // of requiring a switch for them. + bool AllStartWithString = true; + + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) + if (Instructions[i].Operands.empty() || + Instructions[i].Operands[0].OperandType != + AsmWriterOperand::isLiteralTextOperand) { + AllStartWithString = false; + break; + } + + if (AllStartWithString) { + // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not + // all machine instructions are necessarily being printed, so there may be + // target instructions not in this map. + std::map CGIAWIMap; + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) + CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); + + // Emit a table of constant strings. + std::vector NumberedInstructions; + Target.getInstructionsByEnumValue(NumberedInstructions); + + O << " static const char * const OpStrs[] = {\n"; + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { + AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; + if (AWI == 0) { + // Something not handled by the asmwriter printer. + O << " 0,\t// "; + } else { + O << " \"" << AWI->Operands[0].Str << "\",\t// "; + // Nuke the string from the operand list. It is now handled! + AWI->Operands.erase(AWI->Operands.begin()); + } + O << NumberedInstructions[i]->TheDef->getName() << "\n"; + } + O << " };\n\n" + << " // Emit the opcode for the instruction.\n" + << " if (const char *AsmStr = OpStrs[MI->getOpcode()])\n" + << " O << AsmStr;\n\n"; + } + // Because this is a vector we want to emit from the end. Reverse all of the // elements in the vector. std::reverse(Instructions.begin(), Instructions.end()); + + O << " switch (MI->getOpcode()) {\n" + " default: return false;\n"; while (!Instructions.empty()) EmitInstructions(Instructions, O); From lattner at cs.uiuc.edu Sat Jan 22 14:31:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 14:31:32 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501222031.j0MKVWn1014569@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.16 -> 1.17 --- Log message: This is the final big of factoring. This shares cases in suboperand differences, which means that identical instructions (after stripping off the first literal string) do not run any different code at all. On the X86, this turns this code: switch (MI->getOpcode()) { case X86::ADC32mi: printOperand(MI, 4, MVT::i32); break; case X86::ADC32mi8: printOperand(MI, 4, MVT::i8); break; case X86::ADC32mr: printOperand(MI, 4, MVT::i32); break; case X86::ADD32mi: printOperand(MI, 4, MVT::i32); break; case X86::ADD32mi8: printOperand(MI, 4, MVT::i8); break; case X86::ADD32mr: printOperand(MI, 4, MVT::i32); break; case X86::AND32mi: printOperand(MI, 4, MVT::i32); break; case X86::AND32mi8: printOperand(MI, 4, MVT::i8); break; case X86::AND32mr: printOperand(MI, 4, MVT::i32); break; case X86::CMP32mi: printOperand(MI, 4, MVT::i32); break; case X86::CMP32mr: printOperand(MI, 4, MVT::i32); break; case X86::MOV32mi: printOperand(MI, 4, MVT::i32); break; case X86::MOV32mr: printOperand(MI, 4, MVT::i32); break; case X86::OR32mi: printOperand(MI, 4, MVT::i32); break; case X86::OR32mi8: printOperand(MI, 4, MVT::i8); break; case X86::OR32mr: printOperand(MI, 4, MVT::i32); break; case X86::ROL32mi: printOperand(MI, 4, MVT::i8); break; case X86::ROR32mi: printOperand(MI, 4, MVT::i8); break; case X86::SAR32mi: printOperand(MI, 4, MVT::i8); break; case X86::SBB32mi: printOperand(MI, 4, MVT::i32); break; case X86::SBB32mi8: printOperand(MI, 4, MVT::i8); break; case X86::SBB32mr: printOperand(MI, 4, MVT::i32); break; case X86::SHL32mi: printOperand(MI, 4, MVT::i8); break; case X86::SHLD32mrCL: printOperand(MI, 4, MVT::i32); break; case X86::SHR32mi: printOperand(MI, 4, MVT::i8); break; case X86::SHRD32mrCL: printOperand(MI, 4, MVT::i32); break; case X86::SUB32mi: printOperand(MI, 4, MVT::i32); break; case X86::SUB32mi8: printOperand(MI, 4, MVT::i8); break; case X86::SUB32mr: printOperand(MI, 4, MVT::i32); break; case X86::TEST32mi: printOperand(MI, 4, MVT::i32); break; case X86::TEST32mr: printOperand(MI, 4, MVT::i32); break; case X86::TEST8mi: printOperand(MI, 4, MVT::i8); break; case X86::XCHG32mr: printOperand(MI, 4, MVT::i32); break; case X86::XOR32mi: printOperand(MI, 4, MVT::i32); break; case X86::XOR32mi8: printOperand(MI, 4, MVT::i8); break; case X86::XOR32mr: printOperand(MI, 4, MVT::i32); break; } into this: switch (MI->getOpcode()) { case X86::ADC32mi: case X86::ADC32mr: case X86::ADD32mi: case X86::ADD32mr: case X86::AND32mi: case X86::AND32mr: case X86::CMP32mi: case X86::CMP32mr: case X86::MOV32mi: case X86::MOV32mr: case X86::OR32mi: case X86::OR32mr: case X86::SBB32mi: case X86::SBB32mr: case X86::SHLD32mrCL: case X86::SHRD32mrCL: case X86::SUB32mi: case X86::SUB32mr: case X86::TEST32mi: case X86::TEST32mr: case X86::XCHG32mr: case X86::XOR32mi: case X86::XOR32mr: printOperand(MI, 4, MVT::i32); break; case X86::ADC32mi8: case X86::ADD32mi8: case X86::AND32mi8: case X86::OR32mi8: case X86::ROL32mi: case X86::ROR32mi: case X86::SAR32mi: case X86::SBB32mi8: case X86::SHL32mi: case X86::SHR32mi: case X86::SUB32mi8: case X86::TEST8mi: case X86::XOR32mi8: printOperand(MI, 4, MVT::i8); break; } After this, the generated asmwriters look pretty much as though they were generated by hand. This shrinks the X86 asmwriter.inc files from 55101->39669 and 55429->39551 bytes each, and PPC from 16766->12859 bytes. --- Diffs of the changes: (+34 -8) AsmWriterEmitter.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 34 insertions(+), 8 deletions(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.16 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.17 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.16 Sat Jan 22 13:22:23 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 14:31:17 2005 @@ -55,6 +55,9 @@ return MIOpNo != Other.MIOpNo || OpVT != Other.OpVT; return false; } + bool operator==(const AsmWriterOperand &Other) const { + return !operator!=(Other); + } void EmitCode(std::ostream &OS) const; }; @@ -201,6 +204,25 @@ return MismatchOperand; } +static void PrintCases(std::vector > &OpsToPrint, std::ostream &O) { + O << " case " << OpsToPrint.back().first << ": "; + AsmWriterOperand TheOp = OpsToPrint.back().second; + OpsToPrint.pop_back(); + + // Check to see if any other operands are identical in this list, and if so, + // emit a case label for them. + for (unsigned i = OpsToPrint.size(); i != 0; --i) + if (OpsToPrint[i-1].second == TheOp) { + O << "\n case " << OpsToPrint[i-1].first << ": "; + OpsToPrint.erase(OpsToPrint.begin()+i-1); + } + + // Finally, emit the code. + TheOp.EmitCode(O); + O << "break;\n"; +} + /// EmitInstructions - Emit the last instruction in the vector and any other /// instructions that are suitably similar to it. @@ -242,16 +264,20 @@ // If this is the operand that varies between all of the instructions, // emit a switch for just this operand now. O << " switch (MI->getOpcode()) {\n"; - O << " case " << Namespace << "::" - << FirstInst.CGI->TheDef->getName() << ": "; - FirstInst.Operands[i].EmitCode(O); - O << "break;\n"; + std::vector > OpsToPrint; + OpsToPrint.push_back(std::make_pair(Namespace+"::"+ + FirstInst.CGI->TheDef->getName(), + FirstInst.Operands[i])); + for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { - O << " case " << Namespace << "::" - << SimilarInsts[si].CGI->TheDef->getName() << ": "; - SimilarInsts[si].Operands[i].EmitCode(O); - O << "break;\n"; + AsmWriterInst &AWI = SimilarInsts[si]; + OpsToPrint.push_back(std::make_pair(Namespace+"::"+ + AWI.CGI->TheDef->getName(), + AWI.Operands[i])); } + std::reverse(OpsToPrint.begin(), OpsToPrint.end()); + while (!OpsToPrint.empty()) + PrintCases(OpsToPrint, O); O << " }"; } O << "\n"; From lattner at cs.uiuc.edu Sat Jan 22 14:59:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 14:59:53 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200501222059.j0MKxrkG015930@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.17 -> 1.18 --- Log message: Minor fix. --- Diffs of the changes: (+1 -1) AsmWriterEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.17 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.18 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.17 Sat Jan 22 14:31:17 2005 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Sat Jan 22 14:59:38 2005 @@ -90,7 +90,7 @@ if (OperandType == isLiteralTextOperand) OS << "O << \"" << Str << "\"; "; else - OS << Str << "(MI, " << MIOpNo << ", MVT::" << getName(OpVT) << "); "; + OS << Str << "(MI, " << MIOpNo << ", MVT::" << getEnumName(OpVT) << "); "; } From reid at x10sys.com Sat Jan 22 15:29:52 2005 From: reid at x10sys.com (Reid Spencer) Date: Sat, 22 Jan 2005 15:29:52 -0600 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200501222129.PAA29439@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.164 -> 1.165 --- Log message: We're working towards LLVM 1.5 now so bump the version number. This change won't be propagated to the configure script until there's a need to change configure.ac for some larger purpose. --- 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.164 llvm/autoconf/configure.ac:1.165 --- llvm/autoconf/configure.ac:1.164 Sun Jan 16 03:44:57 2005 +++ llvm/autoconf/configure.ac Sat Jan 22 15:29:42 2005 @@ -31,7 +31,7 @@ dnl===-----------------------------------------------------------------------=== dnl Initialize autoconf and define the package name, version number and dnl email address for reporting bugs. -AC_INIT([[llvm]],[[1.4]],[llvmbugs at cs.uiuc.edu]) +AC_INIT([[llvm]],[[1.5]],[llvmbugs at cs.uiuc.edu]) dnl Provide a copyright substitution and ensure the copyright notice is included dnl in the output of --version option of the generated configure script. From lattner at cs.uiuc.edu Sat Jan 22 15:40:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:40:39 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoDuraid.jpg Message-ID: <200501222140.j0MLedqH016021@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoDuraid.jpg added (r1.1) --- Log message: Add photo --- Diffs of the changes: (+0 -0) PhotoDuraid.jpg | 0 1 files changed Index: llvm-www/img/PhotoDuraid.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:44:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:44:45 -0600 Subject: [llvm-commits] CVS: llvm-www/PhotoReid.jpg Message-ID: <200501222144.j0MLijMn016051@apoc.cs.uiuc.edu> Changes in directory llvm-www: PhotoReid.jpg added (r1.1) --- Log message: Add reid's photo --- Diffs of the changes: (+0 -0) PhotoReid.jpg | 0 1 files changed Index: llvm-www/PhotoReid.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:47:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:47:17 -0600 Subject: [llvm-commits] CVS: llvm-www/PhotoReid.jpg Message-ID: <200501222147.j0MLlHSJ016097@apoc.cs.uiuc.edu> Changes in directory llvm-www: PhotoReid.jpg (r1.1) removed --- Log message: Reid should be in the img directory, not here. --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Sat Jan 22 15:47:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:47:25 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoReid.jpg Message-ID: <200501222147.j0MLlPnA016111@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoReid.jpg added (r1.1) --- Log message: Add Reid's photo --- Diffs of the changes: (+0 -0) PhotoReid.jpg | 0 1 files changed Index: llvm-www/img/PhotoReid.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:48:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:48:45 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoVikram.jpg Message-ID: <200501222148.j0MLmj7R016139@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoVikram.jpg added (r1.1) --- Log message: Add vadve's picture --- Diffs of the changes: (+0 -0) PhotoVikram.jpg | 0 1 files changed Index: llvm-www/img/PhotoVikram.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:49:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:49:44 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoBrad.jpg Message-ID: <200501222149.j0MLniqw016166@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoBrad.jpg added (r1.1) --- Log message: Add brad's photo --- Diffs of the changes: (+0 -0) PhotoBrad.jpg | 0 1 files changed Index: llvm-www/img/PhotoBrad.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:50:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:50:33 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoNate.jpg Message-ID: <200501222150.j0MLoX05016195@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoNate.jpg added (r1.1) --- Log message: Add nate's photo --- Diffs of the changes: (+0 -0) PhotoNate.jpg | 0 1 files changed Index: llvm-www/img/PhotoNate.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:54:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:54:44 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoJohn.jpg Message-ID: <200501222154.j0MLsi3W016240@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoJohn.jpg added (r1.1) --- Log message: Add John's "photo" --- Diffs of the changes: (+0 -0) PhotoJohn.jpg | 0 1 files changed Index: llvm-www/img/PhotoJohn.jpg From lattner at cs.uiuc.edu Sat Jan 22 15:55:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:55:18 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoJohn.gif PhotoJohn.jpg Message-ID: <200501222155.j0MLtI09016265@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoJohn.gif added (r1.1) PhotoJohn.jpg (r1.1) removed --- Log message: Except of course that this is a gif, not a jpg --- Diffs of the changes: (+0 -0) PhotoJohn.gif | 0 1 files changed Index: llvm-www/img/PhotoJohn.gif From lattner at cs.uiuc.edu Sat Jan 22 15:56:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:56:33 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoBrian.png Message-ID: <200501222156.j0MLuXj6016290@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoBrian.png added (r1.1) --- Log message: Add brg's picture. --- Diffs of the changes: (+0 -0) PhotoBrian.png | 0 1 files changed Index: llvm-www/img/PhotoBrian.png From lattner at cs.uiuc.edu Sat Jan 22 15:59:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 15:59:35 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoMisha.png Message-ID: <200501222159.j0MLxZTE016321@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoMisha.png added (r1.1) --- Log message: Add Misha's "photo" --- Diffs of the changes: (+0 -0) PhotoMisha.png | 0 1 files changed Index: llvm-www/img/PhotoMisha.png From lattner at cs.uiuc.edu Sat Jan 22 16:01:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 16:01:38 -0600 Subject: [llvm-commits] CVS: llvm-www/img/PhotoAlkis.jpg PhotoBill.jpg PhotoChris.jpg PhotoTanya.jpg AlkisPhoto.jpg BillWendlingPhoto.jpeg ChrisPhoto.jpg TanyaPhoto.jpg Message-ID: <200501222201.j0MM1cMY016378@apoc.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoAlkis.jpg added (r1.1) PhotoBill.jpg added (r1.1) PhotoChris.jpg added (r1.1) PhotoTanya.jpg added (r1.1) AlkisPhoto.jpg (r1.1) removed BillWendlingPhoto.jpeg (r1.1) removed ChrisPhoto.jpg (r1.1) removed TanyaPhoto.jpg (r1.1) removed --- Log message: Rename all photos to be "Photo" so they sort together. --- Diffs of the changes: (+0 -0) PhotoAlkis.jpg | 0 PhotoBill.jpg | 0 PhotoChris.jpg | 0 PhotoTanya.jpg | 0 4 files changed Index: llvm-www/img/PhotoAlkis.jpg Index: llvm-www/img/PhotoBill.jpg Index: llvm-www/img/PhotoChris.jpg Index: llvm-www/img/PhotoTanya.jpg From lattner at cs.uiuc.edu Sat Jan 22 16:01:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 16:01:44 -0600 Subject: [llvm-commits] CVS: llvm-www/Developers.html Message-ID: <200501222201.j0MM1iQR016387@apoc.cs.uiuc.edu> Changes in directory llvm-www: Developers.html updated: 1.20 -> 1.21 --- Log message: Add Duraid to the list (causing everyone to be pushed down) Move all images to the local server Add height and width tags to all of the images. Rename all photos to be "Photo" so they sort together. --- Diffs of the changes: (+32 -26) Developers.html | 58 ++++++++++++++++++++++++++++++-------------------------- 1 files changed, 32 insertions(+), 26 deletions(-) Index: llvm-www/Developers.html diff -u llvm-www/Developers.html:1.20 llvm-www/Developers.html:1.21 --- llvm-www/Developers.html:1.20 Mon Jan 10 02:30:20 2005 +++ llvm-www/Developers.html Sat Jan 22 16:01:32 2005 @@ -18,59 +18,65 @@ Vikram Adve - vadve + vadve - Brian Gaeke - - Repo^H^Hopt Man - + Brad Jones + + KungFooMaster Nate Begeman - Sampo + Sampo - Brad Jones - - KungFooMaster + + Chris Lattner + + Sabre Misha Brukman - Misha - Chris Lattner - - Sabre + + Tanya Lattner + + tonic + John Criswell Dogbert - Tanya Lattner - - tonic + Duraid Madina + + camel_ + Alkis Evlogimenos - alkis + alkis Reid Spencer - Reid + Reid -   -  + Brian Gaeke + + brg + Bill Wendling - Bill + Bill From lattner at cs.uiuc.edu Sat Jan 22 17:04:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 17:04:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200501222304.j0MN4qUA016685@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.28 -> 1.29 --- Log message: Get this to work for 64-bit systems. --- Diffs of the changes: (+11 -6) SelectionDAGISel.cpp | 17 +++++++++++------ 1 files changed, 11 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.28 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.29 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.28 Wed Jan 19 16:31:21 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Jan 22 17:04:37 2005 @@ -566,11 +566,13 @@ unsigned Align = TLI.getTargetData().getTypeAlignment(Ty); SDOperand AllocSize = getValue(I.getArraySize()); + MVT::ValueType IntPtr = TLI.getPointerTy(); + if (IntPtr < AllocSize.getValueType()) + AllocSize = DAG.getNode(ISD::TRUNCATE, IntPtr, AllocSize); + else if (IntPtr > AllocSize.getValueType()) + AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize); - assert(AllocSize.getValueType() == TLI.getPointerTy() && - "FIXME: should extend or truncate to pointer size!"); - - AllocSize = DAG.getNode(ISD::MUL, TLI.getPointerTy(), AllocSize, + AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize, getIntPtrConstant(TySize)); // Handle alignment. If the requested alignment is less than or equal to the @@ -679,8 +681,11 @@ SDOperand Src = getValue(I.getOperand(0)); MVT::ValueType IntPtr = TLI.getPointerTy(); - // FIXME: Extend or truncate to the intptr size. - assert(Src.getValueType() == IntPtr && "Need to adjust the amount!"); + + if (IntPtr < Src.getValueType()) + Src = DAG.getNode(ISD::TRUNCATE, IntPtr, Src); + else if (IntPtr > Src.getValueType()) + Src = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, Src); // Scale the source by the type size. uint64_t ElementSize = TD.getTypeSize(I.getType()->getElementType()); From alenhar2 at cs.uiuc.edu Sat Jan 22 17:39:36 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sat, 22 Jan 2005 17:39:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/ Message-ID: <200501222339.RAA19571@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/lib/Target/Alpha added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From alenhar2 at cs.uiuc.edu Sat Jan 22 17:42:10 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sat, 22 Jan 2005 17:42:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/Alpha.h Alpha.td AlphaAsmPrinter.cpp AlphaISelPattern.cpp AlphaInstrBuilder.h AlphaInstrFormats.td AlphaInstrInfo.cpp AlphaInstrInfo.h AlphaInstrInfo.td AlphaRegisterInfo.cpp AlphaRegisterInfo.h AlphaRegisterInfo.td AlphaTargetMachine.cpp AlphaTargetMachine.h Makefile Message-ID: <200501222342.RAA19641@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: Alpha.h added (r1.1) Alpha.td added (r1.1) AlphaAsmPrinter.cpp added (r1.1) AlphaISelPattern.cpp added (r1.1) AlphaInstrBuilder.h added (r1.1) AlphaInstrFormats.td added (r1.1) AlphaInstrInfo.cpp added (r1.1) AlphaInstrInfo.h added (r1.1) AlphaInstrInfo.td added (r1.1) AlphaRegisterInfo.cpp added (r1.1) AlphaRegisterInfo.h added (r1.1) AlphaRegisterInfo.td added (r1.1) AlphaTargetMachine.cpp added (r1.1) AlphaTargetMachine.h added (r1.1) Makefile added (r1.1) --- Log message: Let me introduce you to the early stages of the llvm backend for the alpha processor --- Diffs of the changes: (+2305 -0) Alpha.h | 41 ++ Alpha.td | 56 +++ AlphaAsmPrinter.cpp | 319 +++++++++++++++++++ AlphaISelPattern.cpp | 797 +++++++++++++++++++++++++++++++++++++++++++++++++ AlphaInstrFormats.td | 109 ++++++ AlphaInstrInfo.cpp | 43 ++ AlphaInstrInfo.h | 42 ++ AlphaInstrInfo.td | 295 ++++++++++++++++++ AlphaRegisterInfo.cpp | 268 ++++++++++++++++ AlphaRegisterInfo.h | 57 +++ AlphaRegisterInfo.td | 93 +++++ AlphaTargetMachine.cpp | 111 ++++++ AlphaTargetMachine.h | 54 +++ Makefile | 20 + 14 files changed, 2305 insertions(+) Index: llvm/lib/Target/Alpha/Alpha.h diff -c /dev/null llvm/lib/Target/Alpha/Alpha.h:1.1 *** /dev/null Sat Jan 22 17:42:05 2005 --- llvm/lib/Target/Alpha/Alpha.h Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,41 ---- + //===-- Alpha.h - Top-level interface for Alpha representation -*- C++ -*-// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains the entry points for global functions defined in the LLVM + // Alpha back-end. + // + //===----------------------------------------------------------------------===// + + #ifndef TARGET_ALPHA_H + #define TARGET_ALPHA_H + + #include + + namespace llvm { + + class FunctionPass; + class TargetMachine; + + FunctionPass *createAlphaSimpleInstructionSelector(TargetMachine &TM); + FunctionPass *createAlphaCodePrinterPass(std::ostream &OS, + TargetMachine &TM); + FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM); + + } // end namespace llvm; + + // Defines symbolic names for Alpha registers. This defines a mapping from + // register name to register number. + // + #include "AlphaGenRegisterNames.inc" + + // Defines symbolic names for the Alpha instructions. + // + #include "AlphaGenInstrNames.inc" + + #endif Index: llvm/lib/Target/Alpha/Alpha.td diff -c /dev/null llvm/lib/Target/Alpha/Alpha.td:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/Alpha.td Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,56 ---- + //===- Alpha.td - Describe the Alpha Target Machine ----*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // + //===----------------------------------------------------------------------===// + + // Get the target-independent interfaces which we are implementing... + // + include "../Target.td" + + //Alpha is little endian + + //===----------------------------------------------------------------------===// + // Register File Description + //===----------------------------------------------------------------------===// + + include "AlphaRegisterInfo.td" + + //===----------------------------------------------------------------------===// + // Instruction Descriptions + //===----------------------------------------------------------------------===// + + include "AlphaInstrInfo.td" + + def AlphaInstrInfo : InstrInfo { + let PHIInst = PHI; + + // Define how we want to layout our target-specific information field. + // let TSFlagsFields = []; + // let TSFlagsShifts = []; + } + + def Alpha : Target { + // Pointers on Alpha are 64-bits in size. + let PointerType = i64; + + let CalleeSavedRegisters = + //saved regs + [R9, R10, R11, R12, R13, R14, + //Frame pointer + R15, + //return address + R26, + //Stack Pointer + R30, + F2, F3, F4, F5, F6, F7, F8, F9]; + + // Pull in Instruction Info: + let InstructionSet = AlphaInstrInfo; + } Index: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,319 ---- + //===-- AlphaAsmPrinter.cpp - Alpha LLVM assembly writer --------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains a printer that converts from our internal representation + // of machine-dependent LLVM code to GAS-format Alpha assembly language. + // + //===----------------------------------------------------------------------===// + + #include "Alpha.h" + #include "AlphaInstrInfo.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Module.h" + #include "llvm/Assembly/Writer.h" + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineConstantPool.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/ValueTypes.h" + #include "llvm/CodeGen/AsmPrinter.h" + + #include "llvm/Target/TargetMachine.h" + #include "llvm/Target/MRegisterInfo.h" + #include "llvm/Target/TargetInstrInfo.h" + + #include "llvm/Support/Mangler.h" + #include "llvm/ADT/Statistic.h" + #include "llvm/ADT/StringExtras.h" + #include "llvm/Support/CommandLine.h" + #include + using namespace llvm; + + namespace { + Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); + + struct AlphaAsmPrinter : public AsmPrinter { + + /// Unique incrementer for label values for referencing Global values. + /// + unsigned LabelNumber; + + AlphaAsmPrinter(std::ostream &o, TargetMachine &tm) + : AsmPrinter(o, tm), LabelNumber(0) + { } + + /// We name each basic block in a Function with a unique number, so + /// that we can consistently refer to them later. This is cleared + /// at the beginning of each call to runOnMachineFunction(). + /// + typedef std::map ValueMapTy; + ValueMapTy NumberForBB; + + virtual const char *getPassName() const { + return "Alpha Assembly Printer"; + } + bool printInstruction(const MachineInstr *MI); + void printOp(const MachineOperand &MO, bool IsCallOp = false); + void printConstantPool(MachineConstantPool *MCP); + void printOperand(const MachineInstr *MI, int opNum, MVT::ValueType VT); + void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true); + void printMachineInstruction(const MachineInstr *MI); + bool runOnMachineFunction(MachineFunction &F); + bool doInitialization(Module &M); + bool doFinalization(Module &M); + }; + } // end of anonymous namespace + + /// createAlphaCodePrinterPass - Returns a pass that prints the Alpha + /// assembly code for a MachineFunction to the given output stream, + /// using the given target machine description. This should work + /// regardless of whether the function is in SSA form. + /// + FunctionPass *llvm::createAlphaCodePrinterPass (std::ostream &o, + TargetMachine &tm) { + return new AlphaAsmPrinter(o, tm); + } + + #include "AlphaGenAsmWriter.inc" + + void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum, MVT::ValueType VT) + { + const MachineOperand &MO = MI->getOperand(opNum); + if (MO.getType() == MachineOperand::MO_MachineRegister) { + assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); + O << LowercaseString(TM.getRegisterInfo()->get(MO.getReg()).Name); + } else if (MO.isImmediate()) { + O << MO.getImmedValue(); + } else { + printOp(MO); + } + } + + + void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { + const MRegisterInfo &RI = *TM.getRegisterInfo(); + int new_symbol; + + switch (MO.getType()) { + case MachineOperand::MO_VirtualRegister: + if (Value *V = MO.getVRegValueOrNull()) { + O << "<" << V->getName() << ">"; + return; + } + // FALLTHROUGH + case MachineOperand::MO_MachineRegister: + case MachineOperand::MO_CCRegister: + O << LowercaseString(RI.get(MO.getReg()).Name); + return; + + case MachineOperand::MO_SignExtendedImmed: + case MachineOperand::MO_UnextendedImmed: + std::cerr << "printOp() does not handle immediate values\n"; + abort(); + return; + + case MachineOperand::MO_PCRelativeDisp: + std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs"; + abort(); + return; + + case MachineOperand::MO_MachineBasicBlock: { + MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); + O << "$LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) + << "_" << MBBOp->getNumber() << "\t" << CommentString << " " + << MBBOp->getBasicBlock()->getName(); + return; + } + + case MachineOperand::MO_ConstantPoolIndex: + O << "$CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex(); + return; + + case MachineOperand::MO_ExternalSymbol: + O << MO.getSymbolName(); + return; + + case MachineOperand::MO_GlobalAddress: + //std::cerr << "Global Addresses? Are you kidding?\n" + //abort(); + O << Mang->getValueName(MO.getGlobal()); + return; + + default: + O << ""; + return; + } + } + + /// printMachineInstruction -- Print out a single Alpha MI to + /// the current output stream. + /// + void AlphaAsmPrinter::printMachineInstruction(const MachineInstr *MI) { + ++EmittedInsts; + if (printInstruction(MI)) + return; // Printer was automatically generated + + assert(0 && "Unhandled instruction in asm writer!"); + abort(); + return; + } + + + /// runOnMachineFunction - This uses the printMachineInstruction() + /// method to print assembly for each instruction. + /// + bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + setupMachineFunction(MF); + O << "\n\n"; + + if (CurrentFnName.compare("main") == 0) + { + O << "\n\n#HACK\n\t.text\n\t.ent __main\n__main:\n\tret $31,($26),1\n\t.end __main\n#ENDHACK\n\n"; + } + + // Print out constants referenced by the function + printConstantPool(MF.getConstantPool()); + + // Print out labels for the function. + O << "\t.text\n"; + emitAlignment(2); + O << "\t.globl\t" << CurrentFnName << "\n"; + O << "\t.ent\t" << CurrentFnName << "\n"; + + O << CurrentFnName << ":\n"; + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + O << "$LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" + << CommentString << " " << I->getBasicBlock()->getName() << "\n"; + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + O << "\t"; + printMachineInstruction(II); + } + } + ++LabelNumber; + + O << "\t.end\t" << CurrentFnName << "\n"; + + // We didn't modify anything. + return false; + } + + + /// printConstantPool - Print to the current output stream assembly + /// representations of the constants in the constant pool MCP. This is + /// used to print out constants which have been "spilled to memory" by + /// the code generator. + /// + void AlphaAsmPrinter::printConstantPool(MachineConstantPool *MCP) { + const std::vector &CP = MCP->getConstants(); + const TargetData &TD = TM.getTargetData(); + + if (CP.empty()) return; + + abort(); + // for (unsigned i = 0, e = CP.size(); i != e; ++i) { + // O << "\t.section\t.rodata\n"; + // emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); + // O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString + // << *CP[i] << "\n"; + // //emitGlobalConstant(CP[i]); + // } + } + + bool AlphaAsmPrinter::doInitialization(Module &M) + { + AsmPrinter::doInitialization(M); + O << "\t.arch ev56\n"; + return false; + } + + + // SwitchSection - Switch to the specified section of the executable if we are + // not already in it! + // + static void SwitchSection(std::ostream &OS, std::string &CurSection, + const char *NewSection) { + if (CurSection != NewSection) { + CurSection = NewSection; + if (!CurSection.empty()) + OS << "\t" << NewSection << "\n"; + } + } + + bool AlphaAsmPrinter::doFinalization(Module &M) { + const TargetData &TD = TM.getTargetData(); + std::string CurSection; + + for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) + if (I->hasInitializer()) { // External global require no code + O << "\n\n"; + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD.getTypeSize(C->getType()); + unsigned Align = TD.getTypeAlignmentShift(C->getType()); + + if (C->isNullValue() && + (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || + I->hasWeakLinkage() /* FIXME: Verify correct */)) { + SwitchSection(O, CurSection, ".data"); + if (I->hasInternalLinkage()) + O << "\t.local " << name << "\n"; + + O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) + << "," << (1 << Align); + O << "\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << "\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << "\n"; + SwitchSection(O, CurSection, ""); + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.globl " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + if (C->isNullValue()) + SwitchSection(O, CurSection, ".bss"); + else + SwitchSection(O, CurSection, ".data"); + break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; + abort(); + } + + emitAlignment(Align); + O << "\t.type " << name << ", at object\n"; + O << "\t.size " << name << "," << Size << "\n"; + O << name << ":\t\t\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << " = "; + WriteAsOperand(O, C, false, false, &M); + O << "\n"; + emitGlobalConstant(C); + } + } + + AsmPrinter::doFinalization(M); + return false; + } Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,797 ---- + //===-- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha -----===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines a pattern matching instruction selector for Alpha. + // + //===----------------------------------------------------------------------===// + + #include "Alpha.h" + //#include "X86InstrBuilder.h" + #include "AlphaRegisterInfo.h" + #include "llvm/Constants.h" // FIXME: REMOVE + #include "llvm/Function.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/TargetData.h" + #include "llvm/Target/TargetLowering.h" + #include "llvm/Support/MathExtras.h" + #include "llvm/ADT/Statistic.h" + #include + using namespace llvm; + + //===----------------------------------------------------------------------===// + // AlphaTargetLowering - Alpha Implementation of the TargetLowering interface + namespace { + class AlphaTargetLowering : public TargetLowering { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + unsigned GP; //GOT vreg + public: + AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { + // Set up the TargetLowering object. + addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); + addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); + + setOperationAction(ISD::EXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::EXTLOAD , MVT::i8 , Expand); + setOperationAction(ISD::EXTLOAD , MVT::i16 , Expand); + setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::ZEXTLOAD , MVT::i8 , Expand); + setOperationAction(ISD::ZEXTLOAD , MVT::i16 , Expand); + setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); + + computeRegisterProperties(); + + // setOperationUnsupported(ISD::MUL, MVT::i8); + // setOperationUnsupported(ISD::SELECT, MVT::i1); + // setOperationUnsupported(ISD::SELECT, MVT::i8); + + // addLegalFPImmediate(+0.0); // FLD0 + // addLegalFPImmediate(+1.0); // FLD1 + // addLegalFPImmediate(-0.0); // FLD0/FCHS + // addLegalFPImmediate(-1.0); // FLD1/FCHS + } + + /// LowerArguments - This hook must be implemented to indicate how we should + /// lower the arguments for the specified function, into the specified DAG. + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + + /// LowerCallTo - This hook lowers an abstract call to a function into an + /// actual call. + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG); + + virtual std::pair + LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + + virtual std::pair + LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG); + + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + + void restoreGP(MachineBasicBlock* BB) + { + BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); + } + }; + } + + //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21 + + //For now, just use variable size stack frame format + + //In a standard call, the first six items are passed in registers $16 + //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details + //of argument-to-register correspondence.) The remaining items are + //collected in a memory argument list that is a naturally aligned + //array of quadwords. In a standard call, this list, if present, must + //be passed at 0(SP). + //7 ... n 0(SP) ... (n-7)*8(SP) + + std::vector + AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) + { + std::vector ArgValues; + + // //#define FP $15 + // //#define RA $26 + // //#define PV $27 + // //#define GP $29 + // //#define SP $30 + + // assert(0 && "TODO"); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + MachineBasicBlock& BB = MF.front(); + + //Handle the return address + //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26); + + unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18, + Alpha::R19, Alpha::R20, Alpha::R21}; + std::vector argVreg; + + int count = 0; + for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) + { + ++count; + assert(count <= 6 && "More than 6 args not supported"); + assert(getValueType(I->getType()) != MVT::f64 && "No floats yet"); + BuildMI(&BB, Alpha::IDEF, 0, args[count - 1]); + argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64))); + } + + BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29); + BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29); + count = 0; + for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) + { + BuildMI(&BB, Alpha::BIS, 2, argVreg[count]).addReg(args[count]).addReg(args[count]); + + SDOperand argt, newroot; + switch (getValueType(I->getType())) + { + case MVT::i64: + argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); + break; + case MVT::i32: + argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i32, DAG.getRoot()); + break; + default: + newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); + argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot); + } + DAG.setRoot(newroot.getValue(1)); + ArgValues.push_back(argt); + ++count; + } + return ArgValues; + } + + std::pair + AlphaTargetLowering::LowerCallTo(SDOperand Chain, + const Type *RetTy, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { + int NumBytes = 0; + Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + std::vector args_to_use; + for (unsigned i = 0, e = Args.size(); i != e; ++i) + { + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + // Promote the integer to 64 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first); + else + Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); + break; + case MVT::i64: + break; + } + args_to_use.push_back(Args[i].first); + } + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + if (RetTyVT != MVT::isVoid) + RetVals.push_back(RetTyVT); + RetVals.push_back(MVT::Other); + + SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0); + Chain = TheCall.getValue(RetTyVT != MVT::isVoid); + Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + return std::make_pair(TheCall, Chain); + } + + std::pair + AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { + //vastart just returns the address of the VarArgsFrameIndex slot. + return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain); + } + + std::pair AlphaTargetLowering:: + LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG) { + abort(); + } + + + std::pair AlphaTargetLowering:: + LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + abort(); + } + + + + + + namespace { + + //===--------------------------------------------------------------------===// + /// ISel - Alpha specific code to select Alpha machine instructions for + /// SelectionDAG operations. + /// + class ISel : public SelectionDAGISel { + + /// AlphaLowering - This object fully describes how to lower LLVM code to an + /// Alpha-specific SelectionDAG. + AlphaTargetLowering AlphaLowering; + + + /// ExprMap - As shared expressions are codegen'd, we keep track of which + /// vreg the value is produced in, so we only emit one copy of each compiled + /// tree. + std::map ExprMap; + std::set LoweredTokens; + + public: + ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) { + } + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { + // Codegen the basic block. + Select(DAG.getRoot()); + + // Clear state used for selection. + ExprMap.clear(); + LoweredTokens.clear(); + } + + unsigned SelectExpr(SDOperand N); + void Select(SDOperand N); + }; + } + + unsigned ISel::SelectExpr(SDOperand N) { + unsigned Result; + unsigned Tmp1, Tmp2, Tmp3; + unsigned Opc = 0; + + SDNode *Node = N.Val; + + unsigned &Reg = ExprMap[N]; + if (Reg) return Reg; + + if (N.getOpcode() != ISD::CALL) + Reg = Result = (N.getValueType() != MVT::Other) ? + MakeReg(N.getValueType()) : 1; + else { + // If this is a call instruction, make sure to prepare ALL of the result + // values as well as the chain. + if (Node->getNumValues() == 1) + Reg = Result = 1; // Void call, just a chain. + else { + Result = MakeReg(Node->getValueType(0)); + ExprMap[N.getValue(0)] = Result; + for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i) + ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); + ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1; + } + } + + switch (N.getOpcode()) { + default: + Node->dump(); + assert(0 && "Node not handled!\n"); + + case ISD::FrameIndex: + Tmp1 = cast(N)->getIndex(); + BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30); + return Result; + + case ISD::EXTLOAD: + case ISD::SEXTLOAD: + // Make sure we generate both values. + if (Result != 1) + ExprMap[N.getValue(1)] = 1; // Generate the token + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + Select(Node->getOperand(0)); // chain + Tmp1 = SelectExpr(Node->getOperand(1)); + switch(Node->getValueType(0)) { + default: assert(0 && "Unknown type to sign extend to."); + case MVT::i64: + switch (cast(Node)->getExtraValueType()) { + default: + assert(0 && "Bad sign extend!"); + case MVT::i32: + BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1); + break; + case MVT::i16: + BuildMI(BB, Alpha::LDW, 2, Result).addImm(0).addReg(Tmp1); + break; + case MVT::i8: + BuildMI(BB, Alpha::LDB, 2, Result).addImm(0).addReg(Tmp1); + break; + } + break; + } + return Result; + + case ISD::GlobalAddress: + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::LOAD_ADDR, 1, Result) + .addGlobalAddress(cast(N)->getGlobal()); + return Result; + + case ISD::CALL: + { + Select(N.getOperand(0)); + + // The chain for this call is now lowered. + ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1)); + + //grab the arguments + std::vector argvregs; + assert(Node->getNumOperands() < 8 && "Only 6 args supported"); + for(int i = 2, e = Node->getNumOperands(); i < e; ++i) + { + argvregs.push_back(SelectExpr(N.getOperand(i))); + } + for(int i = 0, e = argvregs.size(); i < e; ++i) + { + unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18, + Alpha::R19, Alpha::R20, Alpha::R21}; + + BuildMI(BB, Alpha::BIS, 2, args[i]).addReg(argvregs[i]).addReg(argvregs[i]); + } + + //build the right kind of call + if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(1))) + { + Select(N.getOperand(0)); + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true); + } + else if (ExternalSymbolSDNode *ESSDN = + dyn_cast(N.getOperand(1))) + { + Select(N.getOperand(0)); + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true); + } + else { + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1); + AlphaLowering.restoreGP(BB); + } + + //push the result into a virtual register + // if (Result != 1) + // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); + + switch (Node->getValueType(0)) { + default: assert(0 && "Unknown value type for call result!"); + case MVT::Other: return 1; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); + break; + } + return Result+N.ResNo; + } + + case ISD::SIGN_EXTEND: + { + std::cerr << "DestT: " << N.getValueType() << "\n"; + std::cerr << "SrcT: " << N.getOperand(0).getValueType() << "\n"; + assert(0 && "Sign Extend not there yet"); + return Result; + } + case ISD::SIGN_EXTEND_INREG: + { + Tmp1 = SelectExpr(N.getOperand(0)); + MVTSDNode* MVN = dyn_cast(Node); + std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; + switch(MVN->getExtraValueType()) + { + default: + assert(0 && "Sign Extend InReg not there yet"); + break; + case MVT::i32: + { + Tmp2 = MakeReg(MVT::i64); + unsigned Tmp3 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(16); + BuildMI(BB, Alpha::SL, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, Alpha::SRA, 2, Result).addReg(Tmp3).addReg(Tmp2); + break; + } + case MVT::i16: + BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1); + break; + case MVT::i8: + BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1); + break; + } + return Result; + } + case ISD::ZERO_EXTEND_INREG: + { + Tmp1 = SelectExpr(N.getOperand(0)); + MVTSDNode* MVN = dyn_cast(Node); + std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; + switch(MVN->getExtraValueType()) + { + default: + assert(0 && "Zero Extend InReg not there yet"); + break; + case MVT::i32: + { + Tmp2 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xf0); + BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + } + case MVT::i16: + Tmp2 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xfc); + BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case MVT::i8: + Tmp2 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xfe); + BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + } + return Result; + } + + case ISD::SETCC: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + if (SetCCSDNode *SetCC = dyn_cast(Node)) { + if (MVT::isInteger(SetCC->getOperand(0).getValueType())) { + switch (SetCC->getCondition()) { + default: assert(0 && "Unknown integer comparison!"); + case ISD::SETEQ: + BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case ISD::SETGT: + BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp2).addReg(Tmp1); + break; + case ISD::SETGE: + BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp2).addReg(Tmp1); + break; + case ISD::SETLT: + BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case ISD::SETLE: + BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case ISD::SETNE: + { + unsigned Tmp3 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp3).addReg(Alpha::R31); + break; + } + case ISD::SETULT: + BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case ISD::SETUGT: + BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp2).addReg(Tmp1); + break; + case ISD::SETULE: + BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case ISD::SETUGE: + BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp2).addReg(Tmp1); + break; + } + } + else + assert(0 && "only integer"); + } + else + assert(0 && "Not a setcc in setcc"); + + return Result; + + case ISD::CopyFromReg: + { + if (Result == 1) + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + SDOperand Chain = N.getOperand(0); + + Select(Chain); + unsigned r = dyn_cast(Node)->getReg(); + //std::cerr << "CopyFromReg " << Result << " = " << r << "\n"; + BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r); + return Result; + } + + case ISD::ADD: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::ADDQ, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SUB: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::AND: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::AND, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::OR: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::BIS, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::XOR: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::MUL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::MULQ, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::UREM: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::REMQU, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::SELECT: + { + Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE + Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE + Tmp1 = SelectExpr(N.getOperand(0)); //Cond + // Get the condition into the zero flag. + unsigned dummy = MakeReg(MVT::i64); + BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3); + BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + return Result; + } + + case ISD::SHL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::SL, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SRL: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::SRL, 1, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SRA: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::SRA, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::Constant: + { + long val = cast(N)->getValue(); + BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val); + return Result; + } + + + + case ISD::LOAD: + { + // Make sure we generate both values. + if (Result != 1) + ExprMap[N.getValue(1)] = 1; // Generate the token + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + SDOperand Chain = N.getOperand(0); + SDOperand Address = N.getOperand(1); + + if (Address.getOpcode() == ISD::GlobalAddress) + { + Select(Chain); + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); + } + else + { + Select(Chain); + Tmp2 = SelectExpr(Address); + BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2); + } + return Result; + } + } + + return 0; + } + + void ISel::Select(SDOperand N) { + unsigned Tmp1, Tmp2, Opc; + + // FIXME: Disable for our current expansion model! + if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second) + return; // Already selected. + + SDNode *Node = N.Val; + + switch (N.getOpcode()) { + + default: + Node->dump(); std::cerr << "\n"; + assert(0 && "Node not handled yet!"); + + case ISD::BRCOND: { + MachineBasicBlock *Dest = + cast(N.getOperand(2))->getBasicBlock(); + + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest); + return; + } + + case ISD::BR: { + MachineBasicBlock *Dest = + cast(N.getOperand(1))->getBasicBlock(); + + Select(N.getOperand(0)); + BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest); + return; + } + + case ISD::ImplicitDef: + Select(N.getOperand(0)); + BuildMI(BB, Alpha::IDEF, 0, cast(N)->getReg()); + return; + + case ISD::EntryToken: return; // Noop + + case ISD::TokenFactor: + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) + Select(Node->getOperand(i)); + + //N.Val->dump(); std::cerr << "\n"; + //assert(0 && "Node not handled yet!"); + + return; + + case ISD::CopyToReg: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = cast(N)->getReg(); + + if (Tmp1 != Tmp2) { + BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); + } + return; + + case ISD::RET: + switch (N.getNumOperands()) { + default: + std::cerr << N.getNumOperands() << "\n"; + for (unsigned i = 0; i < N.getNumOperands(); ++i) + std::cerr << N.getOperand(i).getValueType() << "\n"; + assert(0 && "Unknown return instruction!"); + case 2: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + switch (N.getOperand(1).getValueType()) { + default: assert(0 && "All other types should have been promoted!!"); + case MVT::i64: + BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1); + break; + } + break; + case 1: + Select(N.getOperand(0)); + break; + } + //Tmp2 = AlphaLowering.getRetAddr(); + //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2); + BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction + return; + + case ISD::STORE: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); //value + if (N.getOperand(2).getOpcode() == ISD::GlobalAddress) + { + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast(N.getOperand(2))->getGlobal()); + } + else + { + Tmp2 = SelectExpr(N.getOperand(2)); //address + BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2); + } + return; + + case ISD::EXTLOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: + case ISD::LOAD: + case ISD::CopyFromReg: + case ISD::CALL: + // case ISD::DYNAMIC_STACKALLOC: + SelectExpr(N); + return; + + + case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety + MVT::ValueType StoredTy = cast(Node)->getExtraValueType(); + assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!"); + + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = SelectExpr(N.getOperand(2)); + + switch (StoredTy) { + default: assert(0 && "Unhandled Type"); break; + case MVT::i8: Opc = Alpha::STB; break; + case MVT::i16: Opc = Alpha::STW; break; + case MVT::i32: Opc = Alpha::STL; break; + } + + BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2); + return; + } + + case ISD::ADJCALLSTACKDOWN: + case ISD::ADJCALLSTACKUP: + Select(N.getOperand(0)); + Tmp1 = cast(N.getOperand(1))->getValue(); + + Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN : + Alpha::ADJUSTSTACKUP; + BuildMI(BB, Opc, 1).addImm(Tmp1); + return; + } + assert(0 && "Should not be reached!"); + } + + + /// createAlphaPatternInstructionSelector - This pass converts an LLVM function + /// into a machine code representation using pattern matching and a machine + /// description file. + /// + FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) { + return new ISel(TM); + } Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -c /dev/null llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,109 ---- + //===- AlphaInstrFormats.td - Alpha Instruction Formats --*- tablegen -*-=// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // + //===----------------------------------------------------------------------===// + + //3.3: + //Memory + //Branch + //Operate + //Floating-point + //PALcode + + //===----------------------------------------------------------------------===// + // Instruction format superclass + //===----------------------------------------------------------------------===// + + class InstAlpha op, dag OL, string asmstr> : Instruction { // Alpha instruction baseline + field bits<32> Inst; + // let Name = asmstr; + let Namespace = "Alpha"; + let OperandList = OL; + let AsmString = asmstr; + + + let Inst{31-26} = op; + } + + //3.3.1 + class MForm opcode, dag OL, string asmstr> : InstAlpha { + bits<5> Ra; + bits<5> Rb; + bits<16> disp; + + let Inst{25-21} = Ra; + let Inst{20-16} = Rb; + let Inst{15-0} = disp; + } + + //3.3.2 + let isBranch = 1, isTerminator = 1 in + class BForm opcode, dag OL, string asmstr> : InstAlpha { + bits<5> Ra; + bits<21> disp; + + let Inst{25-21} = Ra; + let Inst{20-0} = disp; + } + + //3.3.3 + class OForm opcode, bits<7> fun, dag OL, string asmstr> : InstAlpha { + bits<5> Ra; + bits<5> Rb; + bits<3> SBZ; + bits<7> Function = fun; + bits<5> Rc; + + let Inst{25-21} = Ra; + let Inst{20-16} = Rb; + let Inst{15-13} = SBZ; + let Inst{12} = 0; + let Inst{11-5} = Function; + let Inst{4-0} = Rc; + } + + + class OFormL opcode, dag OL, string asmstr> : InstAlpha { + bits<5> Ra; + bits<8> LIT; + bits<7> Function; + bits<5> Rc; + + let Inst{25-21} = Ra; + let Inst{20-13} = LIT; + let Inst{12} = 1; + let Inst{11-5} = Function; + let Inst{4-0} = Rc; + } + + //3.3.4 + class FPForm opcode, dag OL, string asmstr> : InstAlpha { + bits<5> Fa; + bits<5> Fb; + bits<11> Function; + bits<5> Fc; + + let Inst{25-21} = Fa; + let Inst{20-16} = Fb; + let Inst{15-5} = Function; + let Inst{4-0} = Fc; + } + + //3.3.5 + class PALForm opcode, dag OL, string asmstr> : InstAlpha { + bits<26> Function; + + let Inst{25-0} = Function; + } + + + // Pseudo instructions. + class PseudoInstAlpha : InstAlpha<0, OL, nm> { + } Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,43 ---- + //===- AlphaInstrInfo.cpp - Alpha Instruction Information ---*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains the Alpha implementation of the TargetInstrInfo class. + // + //===----------------------------------------------------------------------===// + + #include "Alpha.h" + #include "AlphaInstrInfo.h" + #include "AlphaGenInstrInfo.inc" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include + using namespace llvm; + + AlphaInstrInfo::AlphaInstrInfo() + : TargetInstrInfo(AlphaInsts, sizeof(AlphaInsts)/sizeof(AlphaInsts[0])) { } + + + bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const { + //assert(0 && "TODO"); + MachineOpCode oc = MI.getOpcode(); + if (oc == Alpha::BIS) { // or r1, r2, r2 + assert(MI.getNumOperands() == 3 && + MI.getOperand(0).isRegister() && + MI.getOperand(1).isRegister() && + MI.getOperand(2).isRegister() && + "invalid Alpha BIS instruction!"); + if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { + sourceReg = MI.getOperand(1).getReg(); + destReg = MI.getOperand(0).getReg(); + return true; + } + } + return false; + } Index: llvm/lib/Target/Alpha/AlphaInstrInfo.h diff -c /dev/null llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaInstrInfo.h Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,42 ---- + //===- AlphaInstrInfo.h - Alpha Instruction Information -----*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains the Alpha implementation of the TargetInstrInfo class. + // + //===----------------------------------------------------------------------===// + + #ifndef ALPHAINSTRUCTIONINFO_H + #define ALPHAINSTRUCTIONINFO_H + + #include "llvm/Target/TargetInstrInfo.h" + #include "AlphaRegisterInfo.h" + + namespace llvm { + + class AlphaInstrInfo : public TargetInstrInfo { + const AlphaRegisterInfo RI; + public: + AlphaInstrInfo(); + + /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As + /// such, whenever a client has an instance of instruction info, it should + /// always be able to get register info as well (through this method). + /// + virtual const MRegisterInfo &getRegisterInfo() const { return RI; } + + /// Return true if the instruction is a register to register move and + /// leave the source and dest operands in the passed parameters. + /// + virtual bool isMoveInstr(const MachineInstr &MI, + unsigned &SrcReg, unsigned &DstReg) const; + }; + + } + + #endif Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -c /dev/null llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,295 ---- + //===- AlphaInstrInfo.td - The Alpha Instruction Set -----*- tablegen -*-=// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // + //===----------------------------------------------------------------------===// + + include "AlphaInstrFormats.td" + + // //#define FP $15 + // //#define RA $26 + // //#define PV $27 + // //#define GP $29 + // //#define SP $30 + + def s14imm : Operand; + def s16imm : Operand; + def s21imm : Operand; + def s64imm : Operand; + + def PHI : PseudoInstAlpha<(ops ), "#phi">; + def IDEF : PseudoInstAlpha<(ops ), "#idef">; + def WTF : PseudoInstAlpha<(ops ), "#wtf">; + def ADJUSTSTACKUP : PseudoInstAlpha<(ops ), "ADJUP">; + def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops ), "ADJDOWN">; + + //***************** + //These are shortcuts, the assembler expands them + //***************** + //AT = R28 + //T0-T7 = R1 - R8 + //T8-T11 = R22-R25 + + let Defs = [R29] in + let Uses = [R27] in + def LDGP : PseudoInstAlpha<(ops), "ldgp $$29, 0($$27)">; + + let isCall = 1, + Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R29], + Uses = [R27, R29] in + def CALL : PseudoInstAlpha< (ops s64imm:$TARGET), "jsr $TARGET">; //Jump to subroutine + + let isReturn = 1, isTerminator = 1 in + def RETURN : PseudoInstAlpha<(ops ), "ret $$31,($$26),1">; //Return from subroutine + + def LOAD_IMM : PseudoInstAlpha<(ops GPRC:$RC, s64imm:$IMM), "ldiq $RC,$IMM">; //Load Immediate Quadword + + let Uses = [R29] in + def STORE : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "stq $RA,$DISP">; //Store quadword + + let Uses = [R29] in + def LOAD_ADDR : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "lda $RA,$DISP">; //Load address + + let Uses = [R29] in + def LOAD : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "ldq $RA,$DISP">; //Load quadword + + def LDW : PseudoInstAlpha<(ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldw $RA,$DISP($RB)">; // Load sign-extended word + def LDB : PseudoInstAlpha<(ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldb $RA,$DISP($RB)">; //Load byte + + let Uses = [R28, R23, R24, R25, R26] in + def REMQU : PseudoInstAlpha<(ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "remqu $RA,$RB,$RC">; //unsigned remander + + //*********************** + //Real instructions + //*********************** + + //Operation Form: + def ADDL : OForm<0x10, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "addl $RA,$RB,$RC">; //Add longword + def ADDL_V : OForm< 0x10, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ADDL/V $RA,$RB,$RC">; + def ADDQ : OForm< 0x10, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "addq $RA,$RB,$RC">; //Add quadword + def ADDQ_V : OForm< 0x10, 0x60, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ADDQ/V $RA,$RB,$RC">; + def AMASK : OForm< 0x11, 0x61, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "AMASK $RA,$RB,$RC">; //Architecture mask + def AND : OForm< 0x11, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "AND $RA,$RB,$RC">; //Logical product + def BIC : OForm< 0x11, 0x08, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "BIC $RA,$RB,$RC">; //Bit clear + def BIS : OForm<0x11, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "bis $RA,$RB,$RC">; //Logical sum + + //let isTwoAddress = 1 in { + def CMOVEQ : OForm< 0x11, 0x24, + (ops GPRC:$RDEST, GPRC:$RSRC, GPRC:$RCOND), + "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND = zero + def CMOVGE : OForm< 0x11, 0x46, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVGE $RA,$RB,$RC">; //CMOVE if ? zero + def CMOVGT : OForm<0x11, 0x66, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVGT $RA,$RB,$RC">; //CMOVE if > zero + def CMOVLBC : OForm< 0x11, 0x16, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLBC $RA,$RB,$RC">; //CMOVE if low bit clear + def CMOVLBS : OForm< 0x11, 0x14, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLBS $RA,$RB,$RC">; //CMOVE if low bit set + def CMOVLE : OForm<0x11, 0x64, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLE $RA,$RB,$RC">; //CMOVE if ? zero + def CMOVLT : OForm< 0x11, 0x44, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLT $RA,$RB,$RC">; //CMOVE if < zero + def CMOVNE : OForm< 0x11, 0x26, + (ops GPRC:$RC, GPRC:$DUMMY, GPRC:$RA, GPRC:$RB), + "cmovne $RA,$RB,$RC">; //CMOVE if ? zero + //} + + def CMPBGE : OForm< 0x10, 0x0F, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPBGE $RA,$RB,$RC">; //Compare byte + def CMPEQ : OForm< 0x10, 0x2D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPEQ $RA,$RB,$RC">; //Compare signed quadword equal + def CMPLE : OForm< 0x10, 0x6D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPLE $RA,$RB,$RC">; //Compare signed quadword less than or equal + def CMPLT : OForm< 0x10, 0x4D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPLT $RA,$RB,$RC">; //Compare signed quadword less than + def CMPULE : OForm< 0x10, 0x3D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPULE $RA,$RB,$RC">; //Compare unsigned quadword less than or equal + def CMPULT : OForm< 0x10, 0x1D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPULT $RA,$RB,$RC">; //Compare unsigned quadword less than + def CTLZ : OForm< 0x1C, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTLZ $RA,$RB,$RC">; //Count leading zero + def CTPOP : OForm< 0x1C, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTPOP $RA,$RB,$RC">; //Count population + def CTTZ : OForm<0x1C, 0x33, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTTZ $RA,$RB,$RC">; //Count trailing zero + def EQV : OForm< 0x11, 0x48, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EQV $RA,$RB,$RC">; //Logical equivalence + def EXTBL : OForm< 0x12, 0x06, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTBL $RA,$RB,$RC">; //Extract byte low + def EXTLH : OForm< 0x12, 0x6A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTLH $RA,$RB,$RC">; //Extract longword high + def EXTLL : OForm< 0x12, 0x26, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTLL $RA,$RB,$RC">; //Extract longword low + def EXTQH : OForm< 0x12, 0x7A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTQH $RA,$RB,$RC">; //Extract quadword high + def EXTQ : OForm< 0x12, 0x36, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTQ $RA,$RB,$RC">; //Extract quadword low + def EXTWH : OForm< 0x12, 0x5A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTWH $RA,$RB,$RC">; //Extract word high + def EXTWL : OForm< 0x12, 0x16, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTWL $RA,$RB,$RC">; //Extract word low + def IMPLVER : OForm< 0x11, 0x6C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "IMPLVER $RA,$RB,$RC">; //Implementation version + def INSBL : OForm< 0x12, 0x0B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSBL $RA,$RB,$RC">; //Insert byte low + def INSLH : OForm< 0x12, 0x67, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSLH $RA,$RB,$RC">; //Insert longword high + def INSLL : OForm< 0x12, 0x2B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSLL $RA,$RB,$RC">; //Insert longword low + def INSQH : OForm< 0x12, 0x77, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSQH $RA,$RB,$RC">; //Insert quadword high + def INSQL : OForm< 0x12, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSQL $RA,$RB,$RC">; //Insert quadword low + def INSWH : OForm< 0x12, 0x57, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSWH $RA,$RB,$RC">; //Insert word high + def INSWL : OForm< 0x12, 0x1B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSWL $RA,$RB,$RC">; //Insert word low + def MAXSB8 : OForm<0x1C, 0x3E, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum + def MAXSW4 : OForm< 0x1C, 0x3F, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum + def MAXUB8 : OForm<0x1C, 0x3C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum + def MAXUW4 : OForm< 0x1C, 0x3D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum + def MINSB8 : OForm< 0x1C, 0x38, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum + def MINSW4 : OForm< 0x1C, 0x39, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum + def MINUB8 : OForm< 0x1C, 0x3A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum + def MINUW4 : OForm< 0x1C, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum + def MSKBL : OForm< 0x12, 0x02, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKBL $RA,$RB,$RC">; //Mask byte low + def MSKLH : OForm< 0x12, 0x62, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKLH $RA,$RB,$RC">; //Mask longword high + def MSKLL : OForm< 0x12, 0x22, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKLL $RA,$RB,$RC">; //Mask longword low + def MSKQH : OForm< 0x12, 0x72, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKQH $RA,$RB,$RC">; //Mask quadword high + def MSKQL : OForm< 0x12, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKQL $RA,$RB,$RC">; //Mask quadword low + def MSKWH : OForm< 0x12, 0x52, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKWH $RA,$RB,$RC">; //Mask word high + def MSKWL : OForm< 0x12, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKWL $RA,$RB,$RC">; //Mask word low + def MULL : OForm< 0x13, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULL $RA,$RB,$RC">; //Multiply longword + def MULL_V : OForm< 0x13, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULL/V $RA,$RB,$RC">; + def MULQ : OForm< 0x13, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULQ $RA,$RB,$RC">; //Multiply quadword + def MULQ_V : OForm< 0x13, 0x60, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULQ/V $RA,$RB,$RC">; + def ORNOT : OForm< 0x11, 0x28, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ORNOT $RA,$RB,$RC">; //Logical sum with complement + def PERR : OForm< 0x1C, 0x31, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "PERR $RA,$RB,$RC">; //Pixel error + def PKLB : OForm< 0x1C, 0x37, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "PKLB $RA,$RB,$RC">; //Pack longwords to bytes + def PKWB : OForm<0x1C, 0x36, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "PKWB $RA,$RB,$RC">; //Pack words to bytes + def S4ADDL : OForm< 0x10, 0x02, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4ADDL $RA,$RB,$RC">; //Scaled add longword by 4 + def S4ADDQ : OForm< 0x10, 0x22, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4ADDQ $RA,$RB,$RC">; //Scaled add quadword by 4 + def S4SUBL : OForm< 0x10, 0x0B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4SUBL $RA,$RB,$RC">; //Scaled subtract longword by 4 + def S4SUBQ : OForm< 0x10, 0x2B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4SUBQ $RA,$RB,$RC">; //Scaled subtract quadword by 4 + def S8ADDL : OForm< 0x10, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8ADDL $RA,$RB,$RC">; //Scaled add longword by 8 + def S8ADDQ : OForm< 0x10, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8ADDQ $RA,$RB,$RC">; //Scaled add quadword by 8 + def S8SUBL : OForm< 0x10, 0x1B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8SUBL $RA,$RB,$RC">; //Scaled subtract longword by 8 + def S8SUBQ : OForm< 0x10, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8SUBQ $RA,$RB,$RC">; //Scaled subtract quadword by 8 + def SEXTB : OForm< 0x1C, 0x00, (ops GPRC:$RC, GPRC:$RB), "sextb $RB,$RC">; //Sign extend byte + def SEXTW : OForm< 0x1C, 0x01, (ops GPRC:$RC, GPRC:$RB), "sextw $RB,$RC">; //Sign extend word + def SL : OForm< 0x12, 0x39, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SLL $RA,$RB,$RC">; //Shift left logical + def SRA : OForm< 0x12, 0x3C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SRA $RA,$RB,$RC">; //Shift right arithmetic + def SRL : OForm< 0x12, 0x34, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SRL $RA,$RB,$RC">; //Shift right logical + def SUBL : OForm< 0x10, 0x09, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBL $RA,$RB,$RC">; //Subtract longword + def SUBL_V : OForm< 0x10, 0x49, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBL/V $RA,$RB,$RC">; + def SUBQ : OForm< 0x10, 0x29, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBQ $RA,$RB,$RC">; //Subtract quadword + def SUBQ_V : OForm< 0x10, 0x69, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBQ/V $RA,$RB,$RC">; + def UMULH : OForm< 0x13, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UMULH $RA,$RB,$RC">; //Unsigned multiply quadword high + def UNPKBL : OForm< 0x1C, 0x35, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords + def UNPKBW : OForm< 0x1C, 0x34, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words + def XOR : OForm< 0x11, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "XOR $RA,$RB,$RC">; //Logical difference + def ZAP : OForm< 0x12, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ZAP $RA,$RB,$RC">; //Zero bytes + def ZAPNOT : OForm< 0x12, 0x31, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ZAPNOT $RA,$RB,$RC">; //Zero bytes not + + let isReturn = 1, isTerminator = 1 in + def RET : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "ret $RD,($RS),1">; //Return from subroutine + + def JMP : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jmp $RD,($RS),0">; //Jump + let isCall = 1 in + let Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R27, R29] in + def JSR : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine + def JSR_COROUTINE : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jsr_coroutine $RD,($RS),1">; //Jump to subroutine return + + def BR : BForm<0x30, (ops GPRC:$RD, s21imm:$DISP), "br $RD,$DISP">; //Branch + let isCall = 1 in + let Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R27, R29] in + def BSR : BForm<0x34, (ops GPRC:$RD, s21imm:$DISP), "bsr $RD,$DISP">; //Branch to subroutine + + def STB : MForm<0x0E, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stb $RA,$DISP($RB)">; // Store byte + def STW : MForm<0x0D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stw $RA,$DISP($RB)">; // Store word + def STL : MForm<0x2C, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stl $RA,$DISP($RB)">; // Store longword + def STQ : MForm<0x2D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stq $RA,$DISP($RB)">; //Store quadword + + def LDA : MForm<0x08, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "lda $RA,$DISP($RB)">; //Load address + + def LDL : MForm<0x28, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldq $RA,$DISP($RB)">; // Load sign-extended longword + def LDQ : MForm<0x29, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldq $RA,$DISP($RB)">; //Load quadword + + def BEQ : BForm<0x39, (ops GPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Branch if = zero + def BGE : BForm<0x3E, (ops GPRC:$RA, s21imm:$DISP), "bge $RA,$DISP">; //Branch if >= zero + def BGT : BForm<0x3F, (ops GPRC:$RA, s21imm:$DISP), "bgt $RA,$DISP">; //Branch if > zero + def BLBC : BForm<0x38, (ops GPRC:$RA, s21imm:$DISP), "blbc $RA,$DISP">; //Branch if low bit clear + def BLBS : BForm<0x3C, (ops GPRC:$RA, s21imm:$DISP), "blbs $RA,$DISP">; //Branch if low bit set + def BLE : BForm<0x3B, (ops GPRC:$RA, s21imm:$DISP), "ble $RA,$DISP">; //Branch if <= zero + def BLT : BForm<0x3A, (ops GPRC:$RA, s21imm:$DISP), "blt $RA,$DISP">; //Branch if < zero + def BNE : BForm<0x3D, (ops GPRC:$RA, s21imm:$DISP), "bne $RA,$DISP">; //Branch if != zero + + //Mnemonic Format Opcode Description + //ADDF F-P 15.080 Add F_floating + //ADDG F-P 15.0A0 Add G_floating + //ADDS F-P 16.080 Add S_floating + //ADDT F-P 16.0A0 Add T_floating + //CALL_PAL Pcd 00 Trap to PALcode + //ECB Mfc 18.E800 Evict cache block + //EXCB Mfc 18.0400 Exception barrier + //FETCH Mfc 18.8000 Prefetch data + //FETCH_M Mfc 18.A000 Prefetch data, modify intent + //LDAH Mem 09 Load address high + //LDBU Mem 0A Load zero-extended byte + //LDWU Mem 0C Load zero-extended word + //LDL_L Mem 2A Load sign-extended longword locked + //LDQ_L Mem 2B Load quadword locked + //LDQ_U Mem 0B Load unaligned quadword + //MB Mfc 18.4000 Memory barrier + //RC Mfc 18.E000 Read and clear + //RPCC Mfc 18.C000 Read process cycle counter + //RS Mfc 18.F000 Read and set + //STL_C Mem 2E Store longword conditional + //STQ_C Mem 2F Store quadword conditional + //STQ_U Mem 0F Store unaligned quadword + //TRAPB Mfc 18.0000 Trap barrier + //WH64 Mfc 18.F800 Write hint  64 bytes + //WMB Mfc 18.4400 Write memory barrier + + + //CMPGEQ F-P 15.0A5 Compare G_floating equal + //CMPGLE F-P 15.0A7 Compare G_floating less than or equal + //CMPGLT F-P 15.0A6 Compare G_floating less than + //CMPTEQ F-P 16.0A5 Compare T_floating equal + //CMPTLE F-P 16.0A7 Compare T_floating less than or equal + //CMPTLT F-P 16.0A6 Compare T_floating less than + //CMPTUN F-P 16.0A4 Compare T_floating unordered + //CPYS F-P 17.020 Copy sign + //CPYSE F-P 17.022 Copy sign and exponent + //CPYSN F-P 17.021 Copy sign negate + //CVTDG F-P 15.09E Convert D_floating to G_floating + //CVTGD F-P 15.0AD Convert G_floating to D_floating + //CVTGF F-P 15.0AC Convert G_floating to F_floating + //CVTGQ F-P 15.0AF Convert G_floating to quadword + //CVTLQ F-P 17.010 Convert longword to quadword + //CVTQF F-P 15.0BC Convert quadword to F_floating + //CVTQG F-P 15.0BE Convert quadword to G_floating + //CVTQL F-P 17.030 Convert quadword to longword + //CVTQS F-P 16.0BC Convert quadword to S_floating + //CVTQT F-P 16.0BE Convert quadword to T_floating + //CVTST F-P 16.2AC Convert S_floating to T_floating + //CVTTQ F-P 16.0AF Convert T_floating to quadword + //CVTTS F-P 16.0AC Convert T_floating to S_floating + //DIVF F-P 15.083 Divide F_floating + //DIVG F-P 15.0A3 Divide G_floating + //DIVS F-P 16.083 Divide S_floating + //DIVT F-P 16.0A3 Divide T_floating + //FBEQ Bra 31 Floating branch if = zero + //FBGE Bra 36 Floating branch if ? zero + //FBGT Bra 37 Floating branch if > zero + //FBLE Bra 33 Floating branch if ? zero + //FBLT Bra 32 Floating branch if < zero + //FBNE Bra 35 Floating branch if ? zero + //FCMOVEQ F-P 17.02A FCMOVE if = zero + //FCMOVGE F-P 17.02D FCMOVE if ? zero + //FCMOVGT F-P 17.02F FCMOVE if > zero + //FCMOVLE F-P 17.02E FCMOVE if ? zero + //FCMOVLT F-P 17.02C FCMOVE if < zero + //FCMOVNE F-P 17.02B FCMOVE if ? zero + //FTOIS F-P 1C.78 Floating to integer move, S_floating + //FTOIT F-P 1C.70 Floating to integer move, T_floating + //ITOFF F-P 14.014 Integer to floating move, F_floating + //ITOFS F-P 14.004 Integer to floating move, S_floating + //ITOFT F-P 14.024 Integer to floating move, T_floating + //LDF Mem 20 Load F_floating + //LDG Mem 21 Load G_floating + //LDS Mem 22 Load S_floating + //LDT Mem 23 Load T_floating + //MF_FPCR F-P 17.025 Move from FPCR + //MT_FPCR F-P 17.024 Move to FPCR + //MULF F-P 15.082 Multiply F_floating + //MULG F-P 15.0A2 Multiply G_floating + //MULS F-P 16.082 Multiply S_floating + //MULT F-P 16.0A2 Multiply T_floating + //SQRTF F-P 14.08A Square root F_floating + //SQRTG F-P 14.0AA Square root G_floating + //SQRTS F-P 14.08B Square root S_floating + //SQRTT F-P 14.0AB Square root T_floating + //STF Mem 24 Store F_floating + //STG Mem 25 Store G_floating + //STS Mem 26 Store S_floating + //STT Mem 27 Store T_floating + //SUBF F-P 15.081 Subtract F_floating + //SUBG F-P 15.0A1 Subtract G_floating + //SUBS F-P 16.081 Subtract S_floating + //SUBT F-P 16.0A1 Subtract T_floating Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,268 ---- + //===- PPC64RegisterInfo.cpp - PowerPC64 Register Information ---*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains the PowerPC64 implementation of the MRegisterInfo class. + // + //===----------------------------------------------------------------------===// + + #define DEBUG_TYPE "reginfo" + #include "Alpha.h" + #include "AlphaInstrBuilder.h" + #include "AlphaRegisterInfo.h" + #include "llvm/Constants.h" + #include "llvm/Type.h" + #include "llvm/CodeGen/ValueTypes.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/Target/TargetFrameInfo.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Target/TargetOptions.h" + #include "llvm/Support/CommandLine.h" + #include "llvm/Support/Debug.h" + #include "llvm/ADT/STLExtras.h" + #include + #include + using namespace llvm; + + + AlphaRegisterInfo::AlphaRegisterInfo() + : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP) + { + } + + static const TargetRegisterClass *getClass(unsigned SrcReg) { + if (Alpha::FPRCRegisterClass->contains(SrcReg)) + return Alpha::FPRCRegisterClass; + assert(Alpha::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR"); + return Alpha::GPRCRegisterClass; + } + + void + AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, int FrameIdx) const { + std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n"; + //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); + BuildMI(MBB, MI, Alpha::STQ, 3).addReg(SrcReg).addImm(FrameIdx * 8).addReg(Alpha::R30); + // assert(0 && "TODO"); + } + + void + AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIdx) const{ + std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n"; + //BuildMI(MBB, MI, Alpha::WTF, 0, DestReg); + BuildMI(MBB, MI, Alpha::LDQ, 2, DestReg).addImm(FrameIdx * 8).addReg(Alpha::R30); + // assert(0 && "TODO"); + } + + void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *RC) const { + // std::cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; + if (RC == Alpha::GPRCRegisterClass) { + BuildMI(MBB, MI, Alpha::BIS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); + // } else if (RC == Alpha::FPRCRegisterClass) { + // BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg); + } else { + std::cerr << "Attempt to copy register that is not GPR or FPR"; + abort(); + } + } + + //===----------------------------------------------------------------------===// + // Stack Frame Processing methods + //===----------------------------------------------------------------------===// + + // hasFP - Return true if the specified function should have a dedicated frame + // pointer register. This is true if the function has variable sized allocas or + // if frame pointer elimination is disabled. + // + static bool hasFP(MachineFunction &MF) { + MachineFrameInfo *MFI = MF.getFrameInfo(); + return MFI->hasVarSizedObjects(); + } + + void AlphaRegisterInfo:: + eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + if (hasFP(MF)) { + assert(0 && "TODO"); + // If we have a frame pointer, turn the adjcallstackup instruction into a + // 'sub ESP, ' and the adjcallstackdown instruction into 'add ESP, + // ' + MachineInstr *Old = I; + unsigned Amount = Old->getOperand(0).getImmedValue(); + if (Amount != 0) { + // We need to keep the stack aligned properly. To do this, we round the + // amount of space needed for the outgoing arguments up to the next + // alignment boundary. + unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); + Amount = (Amount+Align-1)/Align*Align; + + MachineInstr *New; + // if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) { + // New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef) + // .addZImm(Amount); + // } else { + // assert(Old->getOpcode() == X86::ADJCALLSTACKUP); + // New=BuildMI(X86::ADD32ri, 1, X86::ESP, MachineOperand::UseAndDef) + // .addZImm(Amount); + // } + + // Replace the pseudo instruction with a new instruction... + MBB.insert(I, New); + } + } + + MBB.erase(I); + } + + void + AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { + assert(0 && "TODO"); + // unsigned i = 0; + // MachineInstr &MI = *II; + // MachineBasicBlock &MBB = *MI.getParent(); + // MachineFunction &MF = *MBB.getParent(); + + // while (!MI.getOperand(i).isFrameIndex()) { + // ++i; + // assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); + // } + + // int FrameIndex = MI.getOperand(i).getFrameIndex(); + + // // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP). + // MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1); + + // // Take into account whether it's an add or mem instruction + // unsigned OffIdx = (i == 2) ? 1 : 2; + + // // Now add the frame object offset to the offset from r1. + // int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + + // MI.getOperand(OffIdx).getImmedValue(); + + // // If we're not using a Frame Pointer that has been set to the value of the + // // SP before having the stack size subtracted from it, then add the stack size + // // to Offset to get the correct offset. + // Offset += MF.getFrameInfo()->getStackSize(); + + // if (Offset > 32767 || Offset < -32768) { + // // Insert a set of r0 with the full offset value before the ld, st, or add + // MachineBasicBlock *MBB = MI.getParent(); + // MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16)); + // MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0) + // .addImm(Offset)); + // // convert into indexed form of the instruction + // // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0 + // // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0 + // unsigned NewOpcode = + // const_cast& >(ImmToIdxMap)[MI.getOpcode()]; + // assert(NewOpcode && "No indexed form of load or store available!"); + // MI.setOpcode(NewOpcode); + // MI.SetMachineOperandReg(1, MI.getOperand(i).getReg()); + // MI.SetMachineOperandReg(2, PPC::R0); + // } else { + // MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed, + // Offset); + // } + } + + + void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const { + MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB + MachineBasicBlock::iterator MBBI = MBB.begin(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineInstr *MI; + + //handle GOP offset + MI = BuildMI(Alpha::LDGP, 0); + MBB.insert(MBBI, MI); + + // Get the number of bytes to allocate from the FrameInfo + unsigned NumBytes = MFI->getStackSize(); + + // Do we need to allocate space on the stack? + if (NumBytes == 0) return; + + // Add the size of R30 to NumBytes size for the store of R30 to the + // stack + // std::cerr << "Spillsize of R30 is " << getSpillSize(Alpha::R30) << "\n"; + // NumBytes = NumBytes + getSpillSize(Alpha::R30)/8; + + // Update frame info to pretend that this is part of the stack... + MFI->setStackSize(NumBytes); + + // adjust stack pointer: r30 -= numbytes + + if (NumBytes <= 32000) //FIXME: do this better + { + MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(-NumBytes).addReg(Alpha::R30); + MBB.insert(MBBI, MI); + } else { + std::cerr << "Too big a stack frame\n"; + abort(); + } + } + + void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineBasicBlock::iterator MBBI = prior(MBB.end()); + MachineInstr *MI; + assert((MBBI->getOpcode() == Alpha::RET || MBBI->getOpcode() == Alpha::RETURN) && + "Can only insert epilog into returning blocks"); + + // Get the number of bytes allocated from the FrameInfo... + unsigned NumBytes = MFI->getStackSize(); + + if (NumBytes != 0) + { + if (NumBytes <= 32000) //FIXME: do this better + { + MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(NumBytes).addReg(Alpha::R30); + MBB.insert(MBBI, MI); + } else { + std::cerr << "Too big a stack frame\n"; + abort(); + } + } + } + + #include "AlphaGenRegisterInfo.inc" + + const TargetRegisterClass* + AlphaRegisterInfo::getRegClassForType(const Type* Ty) const { + switch (Ty->getTypeID()) { + default: assert(0 && "Invalid type to getClass!"); + case Type::BoolTyID: + case Type::SByteTyID: + case Type::UByteTyID: + case Type::ShortTyID: + case Type::UShortTyID: + case Type::IntTyID: + case Type::UIntTyID: + case Type::PointerTyID: + case Type::LongTyID: + case Type::ULongTyID: return &GPRCInstance; + + case Type::FloatTyID: + case Type::DoubleTyID: return &FPRCInstance; + } + } + + std::string AlphaRegisterInfo::getPrettyName(unsigned reg) + { + std::string s(RegisterDescriptors[reg].Name); + return s; + } Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.h diff -c /dev/null llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.h Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,57 ---- + //===- AlphaRegisterInfo.h - Alpha Register Information Impl -*- C++ -*-==// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains the Alpha implementation of the MRegisterInfo class. + // + //===----------------------------------------------------------------------===// + + #ifndef ALPHAREGISTERINFO_H + #define ALPHAREGISTERINFO_H + + #include "llvm/Target/MRegisterInfo.h" + #include "AlphaGenRegisterInfo.h.inc" + + namespace llvm { + + class Type; + + struct AlphaRegisterInfo : public AlphaGenRegisterInfo { + AlphaRegisterInfo(); + const TargetRegisterClass* getRegClassForType(const Type* Ty) const; + + /// Code Generation virtual methods... + void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned SrcReg, int FrameIndex) const; + + void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, int FrameIndex) const; + + void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *RC) const; + + void eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const; + + void eliminateFrameIndex(MachineBasicBlock::iterator II) const; + + //void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; + + void emitPrologue(MachineFunction &MF) const; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + + static std::string getPrettyName(unsigned reg); + }; + + } // end namespace llvm + + #endif Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.td diff -c /dev/null llvm/lib/Target/Alpha/AlphaRegisterInfo.td:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.td Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,93 ---- + //===- AlphaRegisterInfo.td - The Alpha Register File --*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // + //===----------------------------------------------------------------------===// + + class AlphaReg : Register { + field bits<5> Num; + let Namespace = "Alpha"; + } + + // We identify all our registers with a 5-bit ID, for consistency's sake. + + // GPR - One of the 32 32-bit general-purpose registers + class GPR num, string n> : AlphaReg { + let Num = num; + } + + // FPR - One of the 32 64-bit floating-point registers + class FPR num, string n> : AlphaReg { + let Num = num; + } + + //#define FP $15 + //#define RA $26 + //#define PV $27 + //#define GP $29 + //#define SP $30 + + // General-purpose registers + def R0 : GPR< 0, "$0">; def R1 : GPR< 1, "$1">; + def R2 : GPR< 2, "$2">; def R3 : GPR< 3, "$3">; + def R4 : GPR< 4, "$4">; def R5 : GPR< 5, "$5">; + def R6 : GPR< 6, "$6">; def R7 : GPR< 7, "$7">; + def R8 : GPR< 8, "$8">; def R9 : GPR< 9, "$9">; + def R10 : GPR<10, "$10">; def R11 : GPR<11, "$11">; + def R12 : GPR<12, "$12">; def R13 : GPR<13, "$13">; + def R14 : GPR<14, "$14">; def R15 : GPR<15, "$15">; + def R16 : GPR<16, "$16">; def R17 : GPR<17, "$17">; + def R18 : GPR<18, "$18">; def R19 : GPR<19, "$19">; + def R20 : GPR<20, "$20">; def R21 : GPR<21, "$21">; + def R22 : GPR<22, "$22">; def R23 : GPR<23, "$23">; + def R24 : GPR<24, "$24">; def R25 : GPR<25, "$25">; + def R26 : GPR<26, "$26">; def R27 : GPR<27, "$27">; + def R28 : GPR<28, "$28">; def R29 : GPR<29, "$29">; + def R30 : GPR<30, "$30">; def R31 : GPR<31, "$31">; + + // Floating-point registers + def F0 : FPR< 0, "F0">; def F1 : FPR< 1, "F1">; + def F2 : FPR< 2, "F2">; def F3 : FPR< 3, "F3">; + def F4 : FPR< 4, "F4">; def F5 : FPR< 5, "F5">; + def F6 : FPR< 6, "F6">; def F7 : FPR< 7, "F7">; + def F8 : FPR< 8, "F8">; def F9 : FPR< 9, "F9">; + def F10 : FPR<10, "F10">; def F11 : FPR<11, "F11">; + def F12 : FPR<12, "F12">; def F13 : FPR<13, "F13">; + def F14 : FPR<14, "F14">; def F15 : FPR<15, "F15">; + def F16 : FPR<16, "F16">; def F17 : FPR<17, "F17">; + def F18 : FPR<18, "F18">; def F19 : FPR<19, "F19">; + def F20 : FPR<20, "F20">; def F21 : FPR<21, "F21">; + def F22 : FPR<22, "F22">; def F23 : FPR<23, "F23">; + def F24 : FPR<24, "F24">; def F25 : FPR<25, "F25">; + def F26 : FPR<26, "F26">; def F27 : FPR<27, "F27">; + def F28 : FPR<28, "F28">; def F29 : FPR<29, "F29">; + def F30 : FPR<30, "F30">; def F31 : FPR<31, "F31">; + + // //#define FP $15 + // //#define RA $26 + // //#define PV $27 + // //#define GP $29 + // //#define SP $30 + // $28 is undefined after any and all calls + + /// Register classes + def GPRC : RegisterClass; + //R28 is reserved for the assembler + + //Don't allocate 15, 29, 30, 31 + //Allocation volatiles only for now + def FPRC : RegisterClass; + + Index: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,111 ---- + //===-- AlphaTargetMachine.cpp - Define TargetMachine for Alpha -------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // + //===----------------------------------------------------------------------===// + + #include "Alpha.h" + #include "AlphaTargetMachine.h" + #include "llvm/Module.h" + #include "llvm/CodeGen/IntrinsicLowering.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/Passes.h" + #include "llvm/Target/TargetOptions.h" + #include "llvm/Target/TargetMachineRegistry.h" + #include "llvm/Transforms/Scalar.h" + #include "llvm/Support/CommandLine.h" + #include + using namespace llvm; + + namespace { + // Register the targets + RegisterTarget X("alpha", " Alpha (incomplete)"); + } + + AlphaTargetMachine::AlphaTargetMachine( const Module &M, IntrinsicLowering *IL) + : TargetMachine("alpha", IL, true), + FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) //TODO: check these + //JITInfo(*this) + {} + + bool AlphaTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, + MachineCodeEmitter &MCE) + { + assert(0 && "TODO"); + return false; + } + + + /// addPassesToEmitAssembly - Add passes to the specified pass manager + /// to implement a static compiler for this target. + /// + bool AlphaTargetMachine::addPassesToEmitAssembly(PassManager &PM, + std::ostream &Out) { + + // FIXME: Implement efficient support for garbage collection intrinsics. + PM.add(createLowerGCPass()); + + // FIXME: Implement the invoke/unwind instructions! + PM.add(createLowerInvokePass()); + + // FIXME: Implement the switch instruction in the instruction selector! + PM.add(createLowerSwitchPass()); + + PM.add(createLowerConstantExpressionsPass()); + + // Make sure that no unreachable blocks are instruction selected. + PM.add(createUnreachableBlockEliminationPass()); + + PM.add(createAlphaPatternInstructionSelector(*this)); + + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); + + PM.add(createRegisterAllocator()); + + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); + + PM.add(createPrologEpilogCodeInserter()); + + // Must run branch selection immediately preceding the asm printer + //PM.add(createAlphaBranchSelectionPass()); + + PM.add(createAlphaCodePrinterPass(Out, *this)); + + PM.add(createMachineCodeDeleter()); + return false; + } + + //void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { + // // FIXME: Implement efficient support for garbage collection intrinsics. + // PM.add(createLowerGCPass()); + + // // FIXME: Implement the invoke/unwind instructions! + // PM.add(createLowerInvokePass()); + + // // FIXME: Implement the switch instruction in the instruction selector! + // PM.add(createLowerSwitchPass()); + + // PM.add(createLowerConstantExpressionsPass()); + + // // Make sure that no unreachable blocks are instruction selected. + // PM.add(createUnreachableBlockEliminationPass()); + + // PM.add(createPPC32ISelSimple(TM)); + // PM.add(createRegisterAllocator()); + // PM.add(createPrologEpilogCodeInserter()); + + // // Must run branch selection immediately preceding the asm printer + // PM.add(createPPCBranchSelectionPass()); + + // if (PrintMachineCode) + // PM.add(createMachineFunctionPrinterPass(&std::cerr)); + //} + Index: llvm/lib/Target/Alpha/AlphaTargetMachine.h diff -c /dev/null llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/AlphaTargetMachine.h Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,54 ---- + //===-- AlphaTargetMachine.h - Define TargetMachine for PowerPC -*- C++ -*-=// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file declares the Alpha-specific subclass of TargetMachine. + // + //===----------------------------------------------------------------------===// + + #ifndef ALPHA_TARGETMACHINE_H + #define ALPHA_TARGETMACHINE_H + + #include "llvm/Target/TargetMachine.h" + #include "llvm/Target/TargetFrameInfo.h" + #include "llvm/PassManager.h" + #include "AlphaInstrInfo.h" + //#include "AlphaJITInfo.h" + + namespace llvm { + + class GlobalValue; + class IntrinsicLowering; + + class AlphaTargetMachine : public TargetMachine { + AlphaInstrInfo InstrInfo; + TargetFrameInfo FrameInfo; + // AlphaJITInfo JITInfo; + + public: + AlphaTargetMachine(const Module &M, IntrinsicLowering *IL); + + virtual const AlphaInstrInfo *getInstrInfo() const { return &InstrInfo; } + virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual const MRegisterInfo *getRegisterInfo() const { + return &InstrInfo.getRegisterInfo(); + } + // virtual TargetJITInfo *getJITInfo() { + // return &JITInfo; + // } + + virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, + MachineCodeEmitter &MCE); + + virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out); + + }; + + } // end namespace llvm + + #endif Index: llvm/lib/Target/Alpha/Makefile diff -c /dev/null llvm/lib/Target/Alpha/Makefile:1.1 *** /dev/null Sat Jan 22 17:42:10 2005 --- llvm/lib/Target/Alpha/Makefile Sat Jan 22 17:41:55 2005 *************** *** 0 **** --- 1,20 ---- + ##===- lib/Target/Alpha/Makefile -------------------------*- Makefile -*-===## + # + # The LLVM Compiler Infrastructure + # + # This file was developed by the LLVM research group and is distributed under + # the University of Illinois Open Source License. See LICENSE.TXT for details. + # + ##===----------------------------------------------------------------------===## + LEVEL = ../../.. + LIBRARYNAME = LLVMAlpha + TARGET = Alpha + SHARED_LIBRARY=1 + + # Make sure that tblgen is run, first thing. + BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \ + AlphaGenRegisterInfo.inc AlphaGenInstrNames.inc \ + AlphaGenInstrInfo.inc AlphaGenCodeEmitter.inc \ + AlphaGenAsmWriter.inc + + include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Sat Jan 22 21:11:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:11:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/FileUtilities.h Message-ID: <200501230311.j0N3BsUO017895@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: FileUtilities.h updated: 1.28 -> 1.29 --- Log message: New method. --- Diffs of the changes: (+13 -0) FileUtilities.h | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/include/llvm/Support/FileUtilities.h diff -u llvm/include/llvm/Support/FileUtilities.h:1.28 llvm/include/llvm/Support/FileUtilities.h:1.29 --- llvm/include/llvm/Support/FileUtilities.h:1.28 Thu Jan 20 17:31:35 2005 +++ llvm/include/llvm/Support/FileUtilities.h Sat Jan 22 21:11:38 2005 @@ -28,6 +28,19 @@ bool DiffFiles(const std::string &FileA, const std::string &FileB, std::string *Error = 0); +/// DiffFilesWithTolerance - Compare the two files specified, returning 0 if the +/// files match, 1 if they are different, and 2 if there is a file error. This +/// function differs from DiffFiles in that you can specify an absolete and +/// relative FP error that is allowed to exist. If you specify a string to fill +/// in for the error option, it will set the string to an error message if an +/// error occurs, allowing the caller to distinguish between a failed diff and a +/// file system error. +/// +int DiffFilesWithTolerance(const std::string &FileA, const std::string &FileB, + double AbsTol, double RelTol, + std::string *Error = 0); + + /// MoveFileOverIfUpdated - If the file specified by New is different than Old, /// or if Old does not exist, move the New file over the Old file. Otherwise, /// remove the New file. From lattner at cs.uiuc.edu Sat Jan 22 21:13:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:13:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200501230313.j0N3Duii018127@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.35 -> 1.36 --- Log message: Add a new method, refactored out of fpcmp --- Diffs of the changes: (+184 -0) FileUtilities.cpp | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 184 insertions(+) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.35 llvm/lib/Support/FileUtilities.cpp:1.36 --- llvm/lib/Support/FileUtilities.cpp:1.35 Sat Jan 22 11:36:16 2005 +++ llvm/lib/Support/FileUtilities.cpp Sat Jan 22 21:13:43 2005 @@ -14,6 +14,9 @@ #include "llvm/Support/FileUtilities.h" #include "llvm/System/Path.h" +#include "llvm/System/MappedFile.h" +#include "llvm/ADT/StringExtras.h" +#include #include #include @@ -64,3 +67,184 @@ std::remove(New.c_str()); } } + +static bool isNumberChar(char C) { + switch (C) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '.': case '+': case '-': + case 'e': + case 'E': return true; + default: return false; + } +} + +static char *BackupNumber(char *Pos, char *FirstChar) { + // If we didn't stop in the middle of a number, don't backup. + if (!isNumberChar(*Pos)) return Pos; + + // Otherwise, return to the start of the number. + while (Pos > FirstChar && isNumberChar(Pos[-1])) + --Pos; + return Pos; +} + +/// CompareNumbers - compare two numbers, returning true if they are different. +static bool CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End, + double AbsTolerance, double RelTolerance, + std::string *ErrorMsg) { + char *F1NumEnd, *F2NumEnd; + double V1 = 0.0, V2 = 0.0; + // If we stop on numbers, compare their difference. + if (isNumberChar(*F1P) && isNumberChar(*F2P)) { + V1 = strtod(F1P, &F1NumEnd); + V2 = strtod(F2P, &F2NumEnd); + } else { + // Otherwise, the diff failed. + F1NumEnd = F1P; + F2NumEnd = F2P; + } + + if (F1NumEnd == F1P || F2NumEnd == F2P) { + if (ErrorMsg) *ErrorMsg = "Comparison failed, not a numeric difference."; + return true; + } + + // Check to see if these are inside the absolute tolerance + if (AbsTolerance < std::abs(V1-V2)) { + // Nope, check the relative tolerance... + double Diff; + if (V2) + Diff = std::abs(V1/V2 - 1.0); + else if (V1) + Diff = std::abs(V2/V1 - 1.0); + else + Diff = 0; // Both zero. + if (Diff > RelTolerance) { + if (ErrorMsg) { + *ErrorMsg = "Compared: " + ftostr(V1) + " and " + ftostr(V2) + + ": diff = " + ftostr(Diff) + "\n"; + *ErrorMsg += "Out of tolerance: rel/abs: " + ftostr(RelTolerance) + + "/" + ftostr(AbsTolerance); + } + return true; + } + } + + // Otherwise, advance our read pointers to the end of the numbers. + F1P = F1NumEnd; F2P = F2NumEnd; + return false; +} + +// PadFileIfNeeded - If the files are not identical, we will have to be doing +// numeric comparisons in here. There are bad cases involved where we (i.e., +// strtod) might run off the beginning or end of the file if it starts or ends +// with a number. Because of this, if needed, we pad the file so that it starts +// and ends with a null character. +static void PadFileIfNeeded(char *&FileStart, char *&FileEnd, char *&FP) { + if (isNumberChar(FileStart[0]) || isNumberChar(FileEnd[-1])) { + unsigned FileLen = FileEnd-FileStart; + char *NewFile = new char[FileLen+2]; + NewFile[0] = 0; // Add null padding + NewFile[FileLen+1] = 0; // Add null padding + memcpy(NewFile+1, FileStart, FileLen); + FP = NewFile+(FP-FileStart)+1; + FileStart = NewFile+1; + FileEnd = FileStart+FileLen; + } +} + +/// DiffFilesWithTolerance - Compare the two files specified, returning 0 if the +/// files match, 1 if they are different, and 2 if there is a file error. This +/// function differs from DiffFiles in that you can specify an absolete and +/// relative FP error that is allowed to exist. If you specify a string to fill +/// in for the error option, it will set the string to an error message if an +/// error occurs, allowing the caller to distinguish between a failed diff and a +/// file system error. +/// +int llvm::DiffFilesWithTolerance(const std::string &FileA, + const std::string &FileB, + double AbsTol, double RelTol, + std::string *Error) { + try { + // Map in the files into memory. + sys::MappedFile F1((sys::Path(FileA))); + sys::MappedFile F2((sys::Path(FileB))); + F1.map(); + F2.map(); + + // Okay, now that we opened the files, scan them for the first difference. + char *File1Start = F1.charBase(); + char *File2Start = F2.charBase(); + char *File1End = File1Start+F1.size(); + char *File2End = File2Start+F2.size(); + char *F1P = File1Start; + char *F2P = File2Start; + + // Scan for the end of file or first difference. + while (F1P < File1End && F2P < File2End && *F1P == *F2P) + ++F1P, ++F2P; + + // Common case: identifical files. + if (F1P == File1End && F2P == File2End) return 0; + + char *OrigFile1Start = File1Start; + char *OrigFile2Start = File2Start; + + // If the files need padding, do so now. + PadFileIfNeeded(File1Start, File1End, F1P); + PadFileIfNeeded(File2Start, File2End, F2P); + + bool CompareFailed = false; + while (1) { + // Scan for the end of file or next difference. + while (F1P < File1End && F2P < File2End && *F1P == *F2P) + ++F1P, ++F2P; + + if (F1P >= File1End || F2P >= File2End) break; + + // Okay, we must have found a difference. Backup to the start of the + // current number each stream is at so that we can compare from the + // beginning. + F1P = BackupNumber(F1P, File1Start); + F2P = BackupNumber(F2P, File2Start); + + // Now that we are at the start of the numbers, compare them, exiting if + // they don't match. + if (CompareNumbers(F1P, F2P, File1End, File2End, AbsTol, RelTol, Error)) { + CompareFailed = true; + break; + } + } + + // Okay, we reached the end of file. If both files are at the end, we + // succeeded. + bool F1AtEnd = F1P >= File1End; + bool F2AtEnd = F2P >= File2End; + if (!CompareFailed && (!F1AtEnd || !F2AtEnd)) { + // Else, we might have run off the end due to a number: backup and retry. + if (F1AtEnd && isNumberChar(F1P[-1])) --F1P; + if (F2AtEnd && isNumberChar(F2P[-1])) --F2P; + F1P = BackupNumber(F1P, File1Start); + F2P = BackupNumber(F2P, File2Start); + + // Now that we are at the start of the numbers, compare them, exiting if + // they don't match. + if (CompareNumbers(F1P, F2P, File1End, File2End, AbsTol, RelTol, Error)) + CompareFailed = true; + + // If we found the end, we succeeded. + if (F1P < File1End || F2P < File2End) + CompareFailed = true; + } + + if (OrigFile1Start != File1Start) + delete[] File1Start; + if (OrigFile2Start != File2Start) + delete[] File2Start; + return CompareFailed; + } catch (const std::string &Msg) { + if (Error) *Error = Msg; + return 2; + } +} From lattner at cs.uiuc.edu Sat Jan 22 21:16:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:16:00 -0600 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/fpcmp.cpp Message-ID: <200501230316.j0N3G0a1018301@apoc.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: fpcmp.cpp updated: 1.11 -> 1.12 --- Log message: The meat of this utility has been moved to FileUtilities, where it can be used by other tools. --- Diffs of the changes: (+8 -153) fpcmp.cpp | 161 +++----------------------------------------------------------- 1 files changed, 8 insertions(+), 153 deletions(-) Index: llvm/utils/fpcmp/fpcmp.cpp diff -u llvm/utils/fpcmp/fpcmp.cpp:1.11 llvm/utils/fpcmp/fpcmp.cpp:1.12 --- llvm/utils/fpcmp/fpcmp.cpp:1.11 Mon Dec 13 11:41:13 2004 +++ llvm/utils/fpcmp/fpcmp.cpp Sat Jan 22 21:15:47 2005 @@ -8,12 +8,12 @@ //===----------------------------------------------------------------------===// // // fpcmp is a tool that basically works like the 'cmp' tool, except that it can -// tolerate errors due to floating point noise, with the -r option. +// tolerate errors due to floating point noise, with the -r and -a options. // //===----------------------------------------------------------------------===// #include "llvm/Support/CommandLine.h" -#include "llvm/System/MappedFile.h" +#include "llvm/Support/FileUtilities.h" #include #include @@ -31,159 +31,14 @@ AbsTolerance("a", cl::desc("Absolute error tolerated"), cl::init(0)); } -static bool isNumberChar(char C) { - switch (C) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': case '+': case '-': - case 'e': - case 'E': return true; - default: return false; - } -} - -static char *BackupNumber(char *Pos, char *FirstChar) { - // If we didn't stop in the middle of a number, don't backup. - if (!isNumberChar(*Pos)) return Pos; - - // Otherwise, return to the start of the number. - while (Pos > FirstChar && isNumberChar(Pos[-1])) - --Pos; - return Pos; -} - -static void CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End) { - char *F1NumEnd, *F2NumEnd; - double V1 = 0.0, V2 = 0.0; - // If we stop on numbers, compare their difference. - if (isNumberChar(*F1P) && isNumberChar(*F2P)) { - V1 = strtod(F1P, &F1NumEnd); - V2 = strtod(F2P, &F2NumEnd); - } else { - // Otherwise, the diff failed. - F1NumEnd = F1P; - F2NumEnd = F2P; - } - - if (F1NumEnd == F1P || F2NumEnd == F2P) { - std::cerr << "Comparison failed, not a numeric difference.\n"; - exit(1); - } - - // Check to see if these are inside the absolute tolerance - if (AbsTolerance < std::abs(V1-V2)) { - // Nope, check the relative tolerance... - double Diff; - if (V2) - Diff = std::abs(V1/V2 - 1.0); - else if (V1) - Diff = std::abs(V2/V1 - 1.0); - else - Diff = 0; // Both zero. - if (Diff > RelTolerance) { - std::cerr << "Compared: " << V1 << " and " << V2 << ": diff = " - << Diff << "\n"; - std::cerr << "Out of tolerance: rel/abs: " << RelTolerance - << "/" << AbsTolerance << "\n"; - exit(1); - } - } - - // Otherwise, advance our read pointers to the end of the numbers. - F1P = F1NumEnd; F2P = F2NumEnd; -} - -// PadFileIfNeeded - If the files are not identical, we will have to be doing -// numeric comparisons in here. There are bad cases involved where we (i.e., -// strtod) might run off the beginning or end of the file if it starts or ends -// with a number. Because of this, if needed, we pad the file so that it starts -// and ends with a null character. -static void PadFileIfNeeded(char *&FileStart, char *&FileEnd, char *&FP) { - if (isNumberChar(FileStart[0]) || isNumberChar(FileEnd[-1])) { - unsigned FileLen = FileEnd-FileStart; - char *NewFile = new char[FileLen+2]; - NewFile[0] = 0; // Add null padding - NewFile[FileLen+1] = 0; // Add null padding - memcpy(NewFile+1, FileStart, FileLen); - FP = NewFile+(FP-FileStart)+1; - FileStart = NewFile+1; - FileEnd = FileStart+FileLen; - } -} - int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); - try { - // map in the files into memory - sys::Path F1Path(File1); - sys::Path F2Path(File2); - sys::MappedFile F1 ( F1Path ); - sys::MappedFile F2 ( F2Path ); - F1.map(); - F2.map(); - - // Okay, now that we opened the files, scan them for the first difference. - char *File1Start = F1.charBase(); - char *File2Start = F2.charBase(); - char *File1End = File1Start+F1.size(); - char *File2End = File2Start+F2.size(); - char *F1P = File1Start; - char *F2P = File2Start; - - // Scan for the end of file or first difference. - while (F1P < File1End && F2P < File2End && *F1P == *F2P) - ++F1P, ++F2P; - - // Common case: identifical files. - if (F1P == File1End && F2P == File2End) return 0; - - // If the files need padding, do so now. - PadFileIfNeeded(File1Start, File1End, F1P); - PadFileIfNeeded(File2Start, File2End, F2P); - - while (1) { - // Scan for the end of file or next difference. - while (F1P < File1End && F2P < File2End && *F1P == *F2P) - ++F1P, ++F2P; - - if (F1P >= File1End || F2P >= File2End) break; - - // Okay, we must have found a difference. Backup to the start of the - // current number each stream is at so that we can compare from the - // beginning. - F1P = BackupNumber(F1P, File1Start); - F2P = BackupNumber(F2P, File2Start); - - // Now that we are at the start of the numbers, compare them, exiting if - // they don't match. - CompareNumbers(F1P, F2P, File1End, File2End); - } - - // Okay, we reached the end of file. If both files are at the end, we - // succeeded. - bool F1AtEnd = F1P >= File1End; - bool F2AtEnd = F2P >= File2End; - if (F1AtEnd & F2AtEnd) return 0; - - // Else, we might have run off the end due to a number: backup and retry. - if (F1AtEnd && isNumberChar(F1P[-1])) --F1P; - if (F2AtEnd && isNumberChar(F2P[-1])) --F2P; - F1P = BackupNumber(F1P, File1Start); - F2P = BackupNumber(F2P, File2Start); - - // Now that we are at the start of the numbers, compare them, exiting if - // they don't match. - CompareNumbers(F1P, F2P, File1End, File2End); - - // If we found the end, we succeeded. - if (F1P >= File1End && F2P >= File2End) return 0; - - } catch (const std::string& msg) { - std::cerr << argv[0] << ": error: " << msg << "\n"; - return 2; - } - - return 1; + std::string ErrorMsg; + int DF = DiffFilesWithTolerance(File1, File2, AbsTolerance, RelTolerance, + &ErrorMsg); + if (!ErrorMsg.empty()) + std::cerr << argv[0] << ": " << ErrorMsg << "\n"; + return DF; } From lattner at cs.uiuc.edu Sat Jan 22 21:17:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:17:09 -0600 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/fpcmp.cpp Message-ID: <200501230317.j0N3H9mg018511@apoc.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: fpcmp.cpp updated: 1.12 -> 1.13 --- Log message: Drop dead #include --- Diffs of the changes: (+0 -2) fpcmp.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/utils/fpcmp/fpcmp.cpp diff -u llvm/utils/fpcmp/fpcmp.cpp:1.12 llvm/utils/fpcmp/fpcmp.cpp:1.13 --- llvm/utils/fpcmp/fpcmp.cpp:1.12 Sat Jan 22 21:15:47 2005 +++ llvm/utils/fpcmp/fpcmp.cpp Sat Jan 22 21:16:56 2005 @@ -15,8 +15,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include -#include - using namespace llvm; namespace { From lattner at cs.uiuc.edu Sat Jan 22 21:19:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:19:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200501230319.j0N3JQHQ018529@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.36 -> 1.37 --- Log message: Fix a bug in previous checkin --- Diffs of the changes: (+2 -2) FileUtilities.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.36 llvm/lib/Support/FileUtilities.cpp:1.37 --- llvm/lib/Support/FileUtilities.cpp:1.36 Sat Jan 22 21:13:43 2005 +++ llvm/lib/Support/FileUtilities.cpp Sat Jan 22 21:19:13 2005 @@ -239,9 +239,9 @@ } if (OrigFile1Start != File1Start) - delete[] File1Start; + delete[] File1Start-1; // Back up past null byte if (OrigFile2Start != File2Start) - delete[] File2Start; + delete[] File2Start-1; // Back up past null byte return CompareFailed; } catch (const std::string &Msg) { if (Error) *Error = Msg; From lattner at cs.uiuc.edu Sat Jan 22 21:30:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:30:52 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/FileUtilities.h Message-ID: <200501230330.j0N3Uqgh029196@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: FileUtilities.h updated: 1.29 -> 1.30 --- Log message: Remove two dead methods and improve the comments for DiffFilesWithTolerance. Also, make DiffFilesWithTolerance take sys::Path objects instead of std::strings. --- Diffs of the changes: (+10 -26) FileUtilities.h | 36 ++++++++++-------------------------- 1 files changed, 10 insertions(+), 26 deletions(-) Index: llvm/include/llvm/Support/FileUtilities.h diff -u llvm/include/llvm/Support/FileUtilities.h:1.29 llvm/include/llvm/Support/FileUtilities.h:1.30 --- llvm/include/llvm/Support/FileUtilities.h:1.29 Sat Jan 22 21:11:38 2005 +++ llvm/include/llvm/Support/FileUtilities.h Sat Jan 22 21:30:39 2005 @@ -19,34 +19,18 @@ namespace llvm { -/// DiffFiles - Compare the two files specified, returning true if they are -/// different or if there is a file error. If you specify a string to fill in -/// for the error option, it will set the string to an error message if an error -/// occurs, allowing the caller to distinguish between a failed diff and a file -/// system error. -/// -bool DiffFiles(const std::string &FileA, const std::string &FileB, - std::string *Error = 0); - -/// DiffFilesWithTolerance - Compare the two files specified, returning 0 if the -/// files match, 1 if they are different, and 2 if there is a file error. This -/// function differs from DiffFiles in that you can specify an absolete and -/// relative FP error that is allowed to exist. If you specify a string to fill -/// in for the error option, it will set the string to an error message if an -/// error occurs, allowing the caller to distinguish between a failed diff and a -/// file system error. -/// -int DiffFilesWithTolerance(const std::string &FileA, const std::string &FileB, - double AbsTol, double RelTol, - std::string *Error = 0); + /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if + /// the files match, 1 if they are different, and 2 if there is a file error. + /// This function allows you to specify an absolete and relative FP error that + /// is allowed to exist. If you specify a string to fill in for the error + /// option, it will set the string to an error message if an error occurs, or + /// if the files are different. + /// + int DiffFilesWithTolerance(const sys::Path &FileA, const sys::Path &FileB, + double AbsTol, double RelTol, + std::string *Error = 0); -/// MoveFileOverIfUpdated - If the file specified by New is different than Old, -/// or if Old does not exist, move the New file over the Old file. Otherwise, -/// remove the New file. -/// -void MoveFileOverIfUpdated(const std::string &New, const std::string &Old); - /// FileRemover - This class is a simple object meant to be stack allocated. /// If an exception is thrown from a region, the object removes the filename /// specified (if deleteIt is true). From lattner at cs.uiuc.edu Sat Jan 22 21:31:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:31:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200501230331.j0N3VFw7029211@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.37 -> 1.38 --- Log message: Make DiffFilesWithTolerance take sys::Path's instead of std::strings Delete dead functions. --- Diffs of the changes: (+9 -55) FileUtilities.cpp | 64 +++++++----------------------------------------------- 1 files changed, 9 insertions(+), 55 deletions(-) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.37 llvm/lib/Support/FileUtilities.cpp:1.38 --- llvm/lib/Support/FileUtilities.cpp:1.37 Sat Jan 22 21:19:13 2005 +++ llvm/lib/Support/FileUtilities.cpp Sat Jan 22 21:31:02 2005 @@ -17,57 +17,8 @@ #include "llvm/System/MappedFile.h" #include "llvm/ADT/StringExtras.h" #include -#include -#include - using namespace llvm; -/// DiffFiles - Compare the two files specified, returning true if they are -/// different or if there is a file error. If you specify a string to fill in -/// for the error option, it will set the string to an error message if an error -/// occurs, allowing the caller to distinguish between a failed diff and a file -/// system error. -/// -bool llvm::DiffFiles(const std::string &FileA, const std::string &FileB, - std::string *Error) { - std::ios::openmode io_mode = std::ios::in | std::ios::binary; - std::ifstream FileAStream(FileA.c_str(), io_mode); - if (!FileAStream) { - if (Error) *Error = "Couldn't open file '" + FileA + "'"; - return true; - } - - std::ifstream FileBStream(FileB.c_str(), io_mode); - if (!FileBStream) { - if (Error) *Error = "Couldn't open file '" + FileB + "'"; - return true; - } - - // Compare the two files... - int C1, C2; - do { - C1 = FileAStream.get(); - C2 = FileBStream.get(); - if (C1 != C2) return true; - } while (C1 != EOF); - - return false; -} - -/// MoveFileOverIfUpdated - If the file specified by New is different than Old, -/// or if Old does not exist, move the New file over the Old file. Otherwise, -/// remove the New file. -/// -void llvm::MoveFileOverIfUpdated(const std::string &New, - const std::string &Old) { - if (DiffFiles(New, Old)) { - if (std::rename(New.c_str(), Old.c_str())) - std::cerr << "Error renaming '" << New << "' to '" << Old << "'!\n"; - } else { - std::remove(New.c_str()); - } -} - static bool isNumberChar(char C) { switch (C) { case '0': case '1': case '2': case '3': case '4': @@ -162,14 +113,14 @@ /// error occurs, allowing the caller to distinguish between a failed diff and a /// file system error. /// -int llvm::DiffFilesWithTolerance(const std::string &FileA, - const std::string &FileB, +int llvm::DiffFilesWithTolerance(const sys::Path &FileA, + const sys::Path &FileB, double AbsTol, double RelTol, std::string *Error) { try { // Map in the files into memory. - sys::MappedFile F1((sys::Path(FileA))); - sys::MappedFile F2((sys::Path(FileB))); + sys::MappedFile F1(FileA); + sys::MappedFile F2(FileB); F1.map(); F2.map(); @@ -188,6 +139,9 @@ // Common case: identifical files. if (F1P == File1End && F2P == File2End) return 0; + if (AbsTol == 0 && RelTol == 0) + return 1; // Files different! + char *OrigFile1Start = File1Start; char *OrigFile2Start = File2Start; @@ -239,9 +193,9 @@ } if (OrigFile1Start != File1Start) - delete[] File1Start-1; // Back up past null byte + delete[] (File1Start-1); // Back up past null byte if (OrigFile2Start != File2Start) - delete[] File2Start-1; // Back up past null byte + delete[] (File2Start-1); // Back up past null byte return CompareFailed; } catch (const std::string &Msg) { if (Error) *Error = Msg; From lattner at cs.uiuc.edu Sat Jan 22 21:31:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:31:52 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExecutionDriver.cpp Message-ID: <200501230331.j0N3Vqvu029230@apoc.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExecutionDriver.cpp updated: 1.51 -> 1.52 --- Log message: Adjust to changed interface. --- Diffs of the changes: (+2 -1) ExecutionDriver.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.51 llvm/tools/bugpoint/ExecutionDriver.cpp:1.52 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.51 Wed Dec 22 16:33:33 2004 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Sat Jan 22 21:31:39 2005 @@ -303,7 +303,8 @@ std::string Error; bool FilesDifferent = false; - if (DiffFiles(ReferenceOutputFile, Output.toString(), &Error)) { + if (DiffFilesWithTolerance(ReferenceOutputFile, Output.toString(), 0, 0, + &Error)) { if (!Error.empty()) { std::cerr << "While diffing output: " << Error << '\n'; exit(1); From lattner at cs.uiuc.edu Sat Jan 22 21:32:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:32:29 -0600 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/fpcmp.cpp Message-ID: <200501230332.j0N3WT4M029397@apoc.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: fpcmp.cpp updated: 1.13 -> 1.14 --- Log message: This method takes sys::Path objects now. --- Diffs of the changes: (+2 -2) fpcmp.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/utils/fpcmp/fpcmp.cpp diff -u llvm/utils/fpcmp/fpcmp.cpp:1.13 llvm/utils/fpcmp/fpcmp.cpp:1.14 --- llvm/utils/fpcmp/fpcmp.cpp:1.13 Sat Jan 22 21:16:56 2005 +++ llvm/utils/fpcmp/fpcmp.cpp Sat Jan 22 21:32:16 2005 @@ -33,8 +33,8 @@ cl::ParseCommandLineOptions(argc, argv); std::string ErrorMsg; - int DF = DiffFilesWithTolerance(File1, File2, AbsTolerance, RelTolerance, - &ErrorMsg); + int DF = DiffFilesWithTolerance(sys::Path(File1), sys::Path(File2), + AbsTolerance, RelTolerance, &ErrorMsg); if (!ErrorMsg.empty()) std::cerr << argv[0] << ": " << ErrorMsg << "\n"; return DF; From lattner at cs.uiuc.edu Sat Jan 22 21:45:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 21:45:41 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExecutionDriver.cpp Message-ID: <200501230345.j0N3jfpL029627@apoc.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExecutionDriver.cpp updated: 1.52 -> 1.53 --- Log message: Add support for fp tolerances --- Diffs of the changes: (+11 -3) ExecutionDriver.cpp | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.52 llvm/tools/bugpoint/ExecutionDriver.cpp:1.53 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.52 Sat Jan 22 21:31:39 2005 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Sat Jan 22 21:45:26 2005 @@ -29,6 +29,13 @@ AutoPick, RunLLI, RunJIT, RunLLC, RunCBE }; + cl::opt + AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"), + cl::init(0.0)); + cl::opt + RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"), + cl::init(0.0)); + cl::opt InterpreterSel(cl::desc("Specify how LLVM code should be executed:"), cl::values(clEnumValN(AutoPick, "auto", "Use best guess"), @@ -303,9 +310,10 @@ std::string Error; bool FilesDifferent = false; - if (DiffFilesWithTolerance(ReferenceOutputFile, Output.toString(), 0, 0, - &Error)) { - if (!Error.empty()) { + if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile), + sys::Path(Output.toString()), + AbsTolerance, RelTolerance, &Error)) { + if (Diff == 2) { std::cerr << "While diffing output: " << Error << '\n'; exit(1); } From reid at x10sys.com Sat Jan 22 21:52:24 2005 From: reid at x10sys.com (Reid Spencer) Date: Sat, 22 Jan 2005 21:52:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200501230352.VAA32163@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.131 -> 1.132 --- Log message: Support Cygwin assembly generation. The cygwin version of Gnu ASsembler doesn't support certain directives and symbols on cygwin are prefixed with an underscore. This patch makes the necessary adjustments to the output. --- Diffs of the changes: (+37 -11) X86AsmPrinter.cpp | 48 +++++++++++++++++++++++++++++++++++++----------- 1 files changed, 37 insertions(+), 11 deletions(-) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.131 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.132 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.131 Tue Jan 11 22:07:11 2005 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Sat Jan 22 21:52:14 2005 @@ -43,10 +43,12 @@ struct X86SharedAsmPrinter : public AsmPrinter { X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM) { } + : AsmPrinter(O, TM), forCygwin(false) { } + bool doInitialization(Module &M); void printConstantPool(MachineConstantPool *MCP); bool doFinalization(Module &M); + bool forCygwin; }; } @@ -77,6 +79,24 @@ } } +/// doInitialization - determine +bool X86SharedAsmPrinter::doInitialization(Module& M) { + forCygwin = false; + const std::string& TT = M.getTargetTriple(); + if (TT.length() > 5) + forCygwin = TT.find("cygwin") != std::string::npos; + else if (TT.empty()) { +#ifdef __CYGWIN__ + forCygwin = true; +#else + forCygwin = false; +#endif + } + if (forCygwin) + GlobalPrefix = "_"; + return AsmPrinter::doInitialization(M); +} + /// printConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by @@ -114,11 +134,12 @@ (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || I->hasWeakLinkage() /* FIXME: Verify correct */)) { SwitchSection(O, CurSection, ".data"); - if (I->hasInternalLinkage()) + if (!forCygwin && I->hasInternalLinkage()) O << "\t.local " << name << "\n"; - O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) - << "," << (1 << Align); + O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()); + if (!forCygwin) + O << "," << (1 << Align); O << "\t\t# "; WriteAsOperand(O, I, true, true, &M); O << "\n"; @@ -150,8 +171,10 @@ } emitAlignment(Align); - O << "\t.type " << name << ", at object\n"; - O << "\t.size " << name << "," << Size << "\n"; + if (!forCygwin) { + O << "\t.type " << name << ", at object\n"; + O << "\t.size " << name << "," << Size << "\n"; + } O << name << ":\t\t\t\t# "; WriteAsOperand(O, I, true, true, &M); O << " = "; @@ -239,7 +262,8 @@ O << "\t.text\n"; emitAlignment(4); O << "\t.globl\t" << CurrentFnName << "\n"; - O << "\t.type\t" << CurrentFnName << ", @function\n"; + if (!forCygwin) + O << "\t.type\t" << CurrentFnName << ", @function\n"; O << CurrentFnName << ":\n"; // Print out code for the function. @@ -306,7 +330,7 @@ return; } case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); + O << GlobalPrefix << MO.getSymbolName(); return; default: O << ""; return; @@ -462,7 +486,8 @@ O << "\t.text\n"; emitAlignment(4); O << "\t.globl\t" << CurrentFnName << "\n"; - O << "\t.type\t" << CurrentFnName << ", @function\n"; + if (!forCygwin) + O << "\t.type\t" << CurrentFnName << ", @function\n"; O << CurrentFnName << ":\n"; // Print out code for the function. @@ -523,7 +548,7 @@ } case MachineOperand::MO_ExternalSymbol: if (!isCallOp) O << '$'; - O << MO.getSymbolName(); + O << GlobalPrefix << MO.getSymbolName(); return; default: O << ""; return; @@ -600,7 +625,8 @@ /// FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ switch (AsmWriterFlavor) { - default: assert(0 && "Unknown asm flavor!"); + default: + assert(0 && "Unknown asm flavor!"); case intel: return new X86IntelAsmPrinter(o, tm); case att: From reid at x10sys.com Sat Jan 22 22:32:58 2005 From: reid at x10sys.com (Reid Spencer) Date: Sat, 22 Jan 2005 22:32:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200501230432.WAA32386@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.218 -> 1.219 --- Log message: Fix alloca support for Cygwin. On cygwin its __alloca not __builtin_alloca --- Diffs of the changes: (+4 -1) Writer.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.218 llvm/lib/Target/CBackend/Writer.cpp:1.219 --- llvm/lib/Target/CBackend/Writer.cpp:1.218 Wed Jan 5 22:21:49 2005 +++ llvm/lib/Target/CBackend/Writer.cpp Sat Jan 22 22:32:47 2005 @@ -723,7 +723,10 @@ static void generateCompilerSpecificCode(std::ostream& Out) { // Alloca is hard to get, and we don't want to include stdlib.h here... Out << "/* get a declaration for alloca */\n" - << "#if defined(__CYGWIN__) || defined(__APPLE__)\n" + << "#if defined(__CYGWIN__)\n" + << "extern void *_alloca(unsigned long);\n" + << "#define alloca(x) _alloca(x)\n" + << "#elif defined(__APPLE__)\n" << "extern void *__builtin_alloca(unsigned long);\n" << "#define alloca(x) __builtin_alloca(x)\n" << "#elif defined(__sun__)\n" From lattner at cs.uiuc.edu Sat Jan 22 22:35:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 22:35:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Makefile Message-ID: <200501230435.j0N4Z1gI001230@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Makefile updated: 1.21 -> 1.22 --- Log message: Build Alpha by default. --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Makefile diff -u llvm/lib/Target/Makefile:1.21 llvm/lib/Target/Makefile:1.22 --- llvm/lib/Target/Makefile:1.21 Thu Dec 9 22:54:21 2004 +++ llvm/lib/Target/Makefile Sat Jan 22 22:34:46 2005 @@ -7,7 +7,7 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../.. -PARALLEL_DIRS = CBackend X86 SparcV8 SparcV9 PowerPC Skeleton +PARALLEL_DIRS = CBackend X86 SparcV8 SparcV9 PowerPC Alpha Skeleton LIBRARYNAME = LLVMTarget BUILD_ARCHIVE = 1 From lattner at cs.uiuc.edu Sat Jan 22 22:36:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 22:36:19 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200501230436.j0N4aJmI001252@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.17 -> 1.18 --- Log message: Give SelectionDAG a TargetLowering instance instead of TM instance. --- Diffs of the changes: (+5 -4) SelectionDAG.h | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.17 llvm/include/llvm/CodeGen/SelectionDAG.h:1.18 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.17 Wed Jan 19 14:19:58 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Sat Jan 22 22:36:06 2005 @@ -36,7 +36,7 @@ /// linear form. /// class SelectionDAG { - const TargetMachine &TM; + TargetLowering &TLI; MachineFunction &MF; // Root - The root of the entire DAG. EntryNode - The starting token. @@ -45,13 +45,14 @@ // AllNodes - All of the nodes in the DAG std::vector AllNodes; public: - SelectionDAG(const TargetMachine &tm, MachineFunction &mf) : TM(tm), MF(mf) { + SelectionDAG(TargetLowering &tli, MachineFunction &mf) : TLI(tli), MF(mf) { EntryNode = Root = getNode(ISD::EntryToken, MVT::Other); } ~SelectionDAG(); MachineFunction &getMachineFunction() const { return MF; } - const TargetMachine &getTarget() { return TM; } + const TargetMachine &getTarget() const; + TargetLowering &getTargetLoweringInfo() const { return TLI; } /// viewGraph - Pop up a ghostview window with the DAG rendered using 'dot'. /// @@ -80,7 +81,7 @@ /// /// Note that this is an involved process that may invalidate pointers into /// the graph. - void Legalize(TargetLowering &TLI); + void Legalize(); /// RemoveDeadNodes - This method deletes all unreachable nodes in the /// SelectionDAG, including nodes (like loads) that have uses of their token From lattner at cs.uiuc.edu Sat Jan 22 22:36:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 22:36:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200501230436.j0N4ad7s001268@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.29 -> 1.30 --- Log message: Adjust to changes in SelectionDAG interface. --- Diffs of the changes: (+2 -2) SelectionDAGISel.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.29 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.30 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.29 Sat Jan 22 17:04:37 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Jan 22 22:36:26 2005 @@ -1018,7 +1018,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, FunctionLoweringInfo &FuncInfo) { - SelectionDAG DAG(TLI.getTargetMachine(), MF); + SelectionDAG DAG(TLI, MF); CurDAG = &DAG; std::vector > PHINodesToUpdate; @@ -1031,7 +1031,7 @@ // Second step, hack on the DAG until it only uses operations and types that // the target supports. - DAG.Legalize(TLI); + DAG.Legalize(); DEBUG(std::cerr << "Legalized selection DAG:\n"); DEBUG(DAG.dump()); From lattner at cs.uiuc.edu Sat Jan 22 22:39:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 22:39:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200501230439.j0N4duNf001317@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.49 -> 1.50 --- Log message: Remove the 3 HACK HACK HACKs I put in before, fixing them properly with the new TLI that is available. Implement support for handling out of range shifts. This allows us to compile this code (a 64-bit rotate): unsigned long long f3(unsigned long long x) { return (x << 32) | (x >> (64-32)); } into this: f3: mov %EDX, DWORD PTR [%ESP + 4] mov %EAX, DWORD PTR [%ESP + 8] ret GCC produces this: $ gcc t.c -masm=intel -O3 -S -o - -fomit-frame-pointer .. f3: push %ebx mov %ebx, DWORD PTR [%esp+12] mov %ecx, DWORD PTR [%esp+8] mov %eax, %ebx mov %edx, %ecx pop %ebx ret The Simple ISEL produces (eww gross): f3: sub %ESP, 4 mov DWORD PTR [%ESP], %ESI mov %EDX, DWORD PTR [%ESP + 8] mov %ECX, DWORD PTR [%ESP + 12] mov %EAX, 0 mov %ESI, 0 or %EAX, %ECX or %EDX, %ESI mov %ESI, DWORD PTR [%ESP] add %ESP, 4 ret --- Diffs of the changes: (+27 -14) SelectionDAG.cpp | 41 +++++++++++++++++++++++++++-------------- 1 files changed, 27 insertions(+), 14 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.49 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.50 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.49 Fri Jan 21 18:33:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Jan 22 22:39:44 2005 @@ -16,6 +16,7 @@ #include "llvm/GlobalValue.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Target/TargetLowering.h" #include #include #include @@ -141,6 +142,11 @@ return ISD::CondCode(Op1 & Op2); } +const TargetMachine &SelectionDAG::getTarget() const { + return TLI.getTargetMachine(); +} + + /// RemoveDeadNodes - This method deletes all unreachable nodes in the /// SelectionDAG, including nodes (like loads) that have uses of their token /// chain but no other uses and no side effect. If a node is passed in as an @@ -434,6 +440,8 @@ return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); } } + + // FIXME: move this stuff to the DAG Combiner when it exists! // Simplify (X+Z) == X --> Z == 0 if (N1.getOperand(0) == N2) @@ -446,10 +454,9 @@ else { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 - if (N2.getValueType() != MVT::i64) // FIXME: HACK HACK HACK! return getSetCC(Cond, VT, N1.getOperand(0), getNode(ISD::SHL, N2.getValueType(), - N2, getConstant(1, MVT::i8))); + N2, getConstant(1, TLI.getShiftAmountTy()))); } } } @@ -652,29 +659,35 @@ if (N2C->isAllOnesValue()) // mul X, -1 -> 0-X return getNode(ISD::SUB, VT, getConstant(0, VT), N1); - // FIXME: This should only be done if the target supports shift - // operations. + // FIXME: Move this to the DAG combiner when it exists. if ((C2 & C2-1) == 0) { - if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! - SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); - return getNode(ISD::SHL, VT, N1, ShAmt); - } + SDOperand ShAmt = getConstant(ExactLog2(C2), TLI.getShiftAmountTy()); + return getNode(ISD::SHL, VT, N1, ShAmt); } break; case ISD::UDIV: - // FIXME: This should only be done if the target supports shift - // operations. + // FIXME: Move this to the DAG combiner when it exists. if ((C2 & C2-1) == 0 && C2) { - if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! - SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); - return getNode(ISD::SRL, VT, N1, ShAmt); - } + SDOperand ShAmt = getConstant(ExactLog2(C2), TLI.getShiftAmountTy()); + return getNode(ISD::SRL, VT, N1, ShAmt); } break; case ISD::SHL: case ISD::SRL: + // If the shift amount is bigger than the size of the data, simplify. + if (C2 >= MVT::getSizeInBits(N1.getValueType())) { + if (TLI.getShiftAmountFlavor() == TargetLowering::Mask) { + unsigned NewAmt = + C2 & ((1 << MVT::getSizeInBits(N1.getValueType()))-1); + return getNode(Opcode, VT, N1, getConstant(NewAmt,N2.getValueType())); + } else if (TLI.getShiftAmountFlavor() == TargetLowering::Extend) { + // Shifting all of the bits out? + return getConstant(0, N1.getValueType()); + } + } + // FALL THROUGH. case ISD::SRA: if (C2 == 0) return N1; break; From lattner at cs.uiuc.edu Sat Jan 22 22:43:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 22 Jan 2005 22:43:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501230443.j0N4h2FS001455@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.51 -> 1.52 --- Log message: Adjust to changes in SelectionDAG interfaces The first half of correct chain insertion for libcalls. This is not enough to fix Fhourstones yet though. --- Diffs of the changes: (+119 -9) LegalizeDAG.cpp | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 119 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.51 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.52 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.51 Fri Jan 21 18:31:52 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Jan 22 22:42:50 2005 @@ -85,7 +85,7 @@ public: - SelectionDAGLegalize(TargetLowering &TLI, SelectionDAG &DAG); + SelectionDAGLegalize(SelectionDAG &DAG); /// Run - While there is still lowering to do, perform a pass over the DAG. /// Most regularization can be done in a single pass, but targets that require @@ -135,9 +135,9 @@ } -SelectionDAGLegalize::SelectionDAGLegalize(TargetLowering &tli, - SelectionDAG &dag) - : TLI(tli), DAG(dag), ValueTypeActions(TLI.getValueTypeActions()) { +SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) + : TLI(dag.getTargetLoweringInfo()), DAG(dag), + ValueTypeActions(TLI.getValueTypeActions()) { assert(MVT::LAST_VALUETYPE <= 16 && "Too many value types for ValueTypeActions to hold!"); } @@ -1302,12 +1302,117 @@ return true; } +/// FindLatestAdjCallStackDown - Scan up the dag to find the latest (highest +/// NodeDepth) node that is an AdjCallStackDown operation and occurs later than +/// Found. +static void FindLatestAdjCallStackDown(SDNode *Node, SDNode *&Found) { + if (Node->getNodeDepth() <= Found->getNodeDepth()) return; + + // If we found an ADJCALLSTACKDOWN, we already know this node occurs later + // than the Found node. Just remember this node and return. + if (Node->getOpcode() == ISD::ADJCALLSTACKDOWN) { + Found = Node; + return; + } + + // Otherwise, scan the operands of Node to see if any of them is a call. + assert(Node->getNumOperands() != 0 && + "All leaves should have depth equal to the entry node!"); + for (unsigned i = 0, e = Node->getNumOperands()-1; i != e; ++i) + FindLatestAdjCallStackDown(Node->getOperand(i).Val, Found); + + // Tail recurse for the last iteration. + FindLatestAdjCallStackDown(Node->getOperand(Node->getNumOperands()-1).Val, + Found); +} + + +/// FindEarliestAdjCallStackUp - Scan down the dag to find the earliest (lowest +/// NodeDepth) node that is an AdjCallStackUp operation and occurs more recent +/// than Found. +static void FindEarliestAdjCallStackUp(SDNode *Node, SDNode *&Found) { + if (Found && Node->getNodeDepth() >= Found->getNodeDepth()) return; + + // If we found an ADJCALLSTACKUP, we already know this node occurs earlier + // than the Found node. Just remember this node and return. + if (Node->getOpcode() == ISD::ADJCALLSTACKUP) { + Found = Node; + return; + } + + // Otherwise, scan the operands of Node to see if any of them is a call. + SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); + if (UI == E) return; + for (--E; UI != E; ++UI) + FindEarliestAdjCallStackUp(*UI, Found); + + // Tail recurse for the last iteration. + FindEarliestAdjCallStackUp(*UI, Found); +} + +/// FindAdjCallStackUp - Given a chained node that is part of a call sequence, +/// find the ADJCALLSTACKUP node that terminates the call sequence. +static SDNode *FindAdjCallStackUp(SDNode *Node) { + if (Node->getOpcode() == ISD::ADJCALLSTACKUP) + return Node; + assert(!Node->use_empty() && "Could not find ADJCALLSTACKUP!"); + + if (Node->hasOneUse()) // Simple case, only has one user to check. + return FindAdjCallStackUp(*Node->use_begin()); + + SDOperand TheChain(Node, Node->getNumValues()-1); + assert(TheChain.getValueType() == MVT::Other && "Is not a token chain!"); + + for (SDNode::use_iterator UI = Node->use_begin(), + E = Node->use_end(); ; ++UI) { + assert(UI != E && "Didn't find a user of the tokchain, no ADJCALLSTACKUP!"); + + // Make sure to only follow users of our token chain. + SDNode *User = *UI; + for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) + if (User->getOperand(i) == TheChain) + return FindAdjCallStackUp(User); + } + assert(0 && "Unreachable"); + abort(); +} + +/// FindInputOutputChains - If we are replacing an operation with a call we need +/// to find the call that occurs before and the call that occurs after it to +/// properly serialize the calls in the block. +static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain, + SDOperand Entry) { + SDNode *LatestAdjCallStackDown = Entry.Val; + FindLatestAdjCallStackDown(OpNode, LatestAdjCallStackDown); + //std::cerr << "Found node: "; LatestAdjCallStackDown->dump(); std::cerr <<"\n"; + + SDNode *LatestAdjCallStackUp = FindAdjCallStackUp(LatestAdjCallStackDown); + + + SDNode *EarliestAdjCallStackUp = 0; + FindEarliestAdjCallStackUp(OpNode, EarliestAdjCallStackUp); + + if (EarliestAdjCallStackUp) { + //std::cerr << "Found node: "; + //EarliestAdjCallStackUp->dump(); std::cerr <<"\n"; + } + + return SDOperand(LatestAdjCallStackUp, 0); +} + + + // ExpandLibCall - Expand a node into a call to a libcall. If the result value // does not fit into a register, return the lo part and set the hi part to the // by-reg argument. If it does fit into a single register, return the result // and leave the Hi part unset. SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node, SDOperand &Hi) { + SDNode *OutChain; + SDOperand InChain = FindInputOutputChains(Node, OutChain, + DAG.getEntryNode()); + // TODO. Link in chains. + TargetLowering::ArgListTy Args; for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { MVT::ValueType ArgVT = Node->getOperand(i).getValueType(); @@ -1320,7 +1425,7 @@ // node as our input and ignore the output chain. This allows us to place // calls wherever we need them to satisfy data dependences. const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0)); - SDOperand Result = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, Callee, + SDOperand Result = TLI.LowerCallTo(InChain, RetTy, Callee, Args, DAG).first; switch (getTypeAction(Result.getValueType())) { default: assert(0 && "Unknown thing"); @@ -1335,6 +1440,7 @@ } } + /// ExpandIntToFP - Expand a [US]INT_TO_FP operation, assuming that the /// destination type is legal. SDOperand SelectionDAGLegalize:: @@ -1344,6 +1450,10 @@ "This is not an expansion!"); assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); + SDNode *OutChain; + SDOperand InChain = FindInputOutputChains(Source.Val, OutChain, + DAG.getEntryNode()); + const char *FnName; if (isSigned) { if (DestTy == MVT::f32) @@ -1369,8 +1479,8 @@ // node as our input and ignore the output chain. This allows us to place // calls wherever we need them to satisfy data dependences. const Type *RetTy = MVT::getTypeForValueType(DestTy); - return TLI.LowerCallTo(DAG.getEntryNode(), RetTy, Callee, - Args, DAG).first; + return TLI.LowerCallTo(InChain, RetTy, Callee, Args, DAG).first; + } @@ -1592,9 +1702,9 @@ // SelectionDAG::Legalize - This is the entry point for the file. // -void SelectionDAG::Legalize(TargetLowering &TLI) { +void SelectionDAG::Legalize() { /// run - This is the main entry point to this class. /// - SelectionDAGLegalize(TLI, *this).Run(); + SelectionDAGLegalize(*this).Run(); } From lattner at cs.uiuc.edu Sun Jan 23 00:02:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 00:02:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200501230602.j0N62rUD003044@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.38 -> 1.39 --- Log message: Fix crash comparing empty file against nonempty file. --- Diffs of the changes: (+2 -1) FileUtilities.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.38 llvm/lib/Support/FileUtilities.cpp:1.39 --- llvm/lib/Support/FileUtilities.cpp:1.38 Sat Jan 22 21:31:02 2005 +++ llvm/lib/Support/FileUtilities.cpp Sun Jan 23 00:02:40 2005 @@ -93,7 +93,8 @@ // with a number. Because of this, if needed, we pad the file so that it starts // and ends with a null character. static void PadFileIfNeeded(char *&FileStart, char *&FileEnd, char *&FP) { - if (isNumberChar(FileStart[0]) || isNumberChar(FileEnd[-1])) { + if (FileStart-FileEnd < 2 || + isNumberChar(FileStart[0]) || isNumberChar(FileEnd[-1])) { unsigned FileLen = FileEnd-FileStart; char *NewFile = new char[FileLen+2]; NewFile[0] = 0; // Add null padding From alkis at cs.uiuc.edu Sun Jan 23 08:40:36 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 23 Jan 2005 08:40:36 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200501231440.IAA15196@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.188 -> 1.189 --- Log message: Eliminate some unneeded casts now that the operand stack implecitly adds thems. --- Diffs of the changes: (+10 -28) Compiler.cpp | 38 ++++++++++---------------------------- 1 files changed, 10 insertions(+), 28 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.188 llvm-java/lib/Compiler/Compiler.cpp:1.189 --- llvm-java/lib/Compiler/Compiler.cpp:1.188 Fri Jan 21 21:28:12 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sun Jan 23 08:40:25 2005 @@ -1539,9 +1539,7 @@ void do_aload_common(Type* arrayTy) { Value* index = pop(Type::IntTy); - Value* arrayRef = new CastInst(pop(ObjectBaseRefTy), - PointerType::get(arrayTy), - "cast-to-array", currentBB_); + Value* arrayRef = pop(PointerType::get(arrayTy)); std::vector indices; indices.reserve(3); @@ -1578,9 +1576,7 @@ Value* value = pop(elementTy); Value* index = pop(Type::IntTy); const Type* arrayRefTy = PointerType::get(getArrayInfo(elementTy).type); - Value* arrayRef = new CastInst(pop(ObjectBaseRefTy), - arrayRefTy, - "cast-to-array", currentBB_); + Value* arrayRef = pop(arrayRefTy); std::vector indices; indices.reserve(3); @@ -1830,8 +1826,6 @@ unsigned t, unsigned f) { Value* v2 = pop(type); Value* v1 = pop(type); - if (v1->getType() != v2->getType()) - v1 = new CastInst(v1, v2->getType(), TMP, currentBB_); Value* c = new SetCondInst(cc, v1, v2, TMP, currentBB_); new BranchInst(bbBuilder_->getBasicBlock(t), bbBuilder_->getBasicBlock(f), @@ -2179,8 +2173,7 @@ } void do_newarray(JType type) { - Value* count = pop(Type::IntTy); - count = new CastInst(count, Type::UIntTy, TMP, currentBB_); + Value* count = pop(Type::UIntTy); const ClassInfo& ci = getPrimitiveArrayInfo(type); const VTableInfo& vi = getPrimitiveArrayVTableInfo(type); @@ -2189,8 +2182,7 @@ } void do_anewarray(unsigned index) { - Value* count = pop(Type::IntTy); - count = new CastInst(count, Type::UIntTy, TMP, currentBB_); + Value* count = pop(Type::UIntTy); ConstantClass* classRef = cf_->getConstantClass(index); ClassFile* cf = ClassFile::get(classRef->getName()->str()); @@ -2241,19 +2233,15 @@ } void do_arraylength() { - Value* arrayRef = pop(ObjectBaseRefTy); const ClassInfo& ci = getObjectArrayInfo(); - arrayRef = - new CastInst(arrayRef, PointerType::get(ci.type), TMP, currentBB_); + Value* arrayRef = pop(PointerType::get(ci.type)); Value* lengthPtr = getArrayLengthPtr(arrayRef); Value* length = new LoadInst(lengthPtr, TMP, currentBB_); - length = new CastInst(length, Type::IntTy, TMP, currentBB_); push(length); } void do_athrow() { Value* objRef = pop(ObjectBaseRefTy); - objRef = new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_THROW, Type::IntTy, ObjectBaseRefTy, NULL); @@ -2269,23 +2257,19 @@ tie(ci, vi) = getInfo(classRef->getName()->str()); Value* objRef = pop(ObjectBaseRefTy); - Value* objBase = - new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_ISINSTANCEOF, Type::IntTy, - objBase->getType(), PointerType::get(VTableInfo::VTableBaseTy), NULL); + ObjectBaseRefTy, PointerType::get(VTableInfo::VTableBaseTy), NULL); Value* vtable = new CastInst(vi->vtable, PointerType::get(VTableInfo::VTableBaseTy), TMP, currentBB_); - Value* r = new CallInst(f, objBase, vtable, TMP, currentBB_); + Value* r = new CallInst(f, objRef, vtable, TMP, currentBB_); Value* b = new SetCondInst(Instruction::SetEQ, r, ConstantSInt::get(Type::IntTy, 1), TMP, currentBB_); // FIXME: if b is false we must throw a ClassCast exception - Value* objCast = - new CastInst(objRef, PointerType::get(ci->type), TMP, currentBB_); - push(objCast); + push(objRef); } void do_instanceof(unsigned index) { @@ -2296,15 +2280,13 @@ tie(ci, vi) = getInfo(classRef->getName()->str()); Value* objRef = pop(ObjectBaseRefTy); - Value* objBase = - new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); Function* f = module_.getOrInsertFunction( LLVM_JAVA_ISINSTANCEOF, Type::IntTy, - objBase->getType(), PointerType::get(VTableInfo::VTableBaseTy), NULL); + ObjectBaseRefTy, PointerType::get(VTableInfo::VTableBaseTy), NULL); Value* vtable = new CastInst(vi->vtable, PointerType::get(VTableInfo::VTableBaseTy), TMP, currentBB_); - Value* r = new CallInst(f, objBase, vtable, TMP, currentBB_); + Value* r = new CallInst(f, objRef, vtable, TMP, currentBB_); push(r); } From alkis at cs.uiuc.edu Sun Jan 23 08:56:45 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 23 Jan 2005 08:56:45 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java Message-ID: <200501231456.IAA15322@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Lists3.java updated: 1.1 -> 1.2 --- Log message: Make this test pass. --- Diffs of the changes: (+3 -2) Lists3.java | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java diff -u llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java:1.1 llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java:1.2 --- llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java:1.1 Mon Jan 17 20:30:49 2005 +++ llvm-java/test/Programs/SingleSource/UnitTests/Lists3.java Sun Jan 23 08:56:35 2005 @@ -18,7 +18,8 @@ Test.println(((Integer)llist.removeLast()).intValue()); Test.println(llist.size()); - for (Iterator i = llist.iterator(); i.hasNext(); ) - Test.println(((Integer)i.next()).intValue()); + for (int i = 0; i < llist.size(); ++i) { + Test.println(((Integer)llist.get(i)).intValue()); + } } } From alkis at cs.uiuc.edu Sun Jan 23 09:06:44 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 23 Jan 2005 09:06:44 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/Lists5.java Message-ID: <200501231506.JAA15455@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: Lists5.java added (r1.1) --- Log message: Add test case distilled from Lists3.java. --- Diffs of the changes: (+10 -0) Lists5.java | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm-java/test/Programs/SingleSource/UnitTests/Lists5.java diff -c /dev/null llvm-java/test/Programs/SingleSource/UnitTests/Lists5.java:1.1 *** /dev/null Sun Jan 23 09:06:43 2005 --- llvm-java/test/Programs/SingleSource/UnitTests/Lists5.java Sun Jan 23 09:06:33 2005 *************** *** 0 **** --- 1,10 ---- + import java.util.*; + + public class Lists5 + { + public static void main(String[] args) { + LinkedList llist = new LinkedList(); + Iterator i = llist.iterator(); + Test.println(i.hasNext()); + } + } From lattner at cs.uiuc.edu Sun Jan 23 14:27:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 14:27:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200501232027.j0NKRBkp003563@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.309 -> 1.310 --- Log message: Get rid of a several dozen more and instructions in specint. --- Diffs of the changes: (+36 -5) InstructionCombining.cpp | 41 ++++++++++++++++++++++++++++++++++++----- 1 files changed, 36 insertions(+), 5 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.309 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.310 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.309 Fri Jan 21 17:06:49 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 23 14:26:55 2005 @@ -1298,6 +1298,14 @@ if (ConstantExpr::getAnd(CI, Mask)->isNullValue()) return true; break; + case Instruction::Or: + // If the LHS and the RHS are MaskedValueIsZero, the result is also zero. + return MaskedValueIsZero(I->getOperand(1), Mask) && + MaskedValueIsZero(I->getOperand(0), Mask); + case Instruction::Select: + // If the T and F values are MaskedValueIsZero, the result is also zero. + return MaskedValueIsZero(I->getOperand(2), Mask) && + MaskedValueIsZero(I->getOperand(1), Mask); case Instruction::Cast: { const Type *SrcTy = I->getOperand(0)->getType(); if (SrcTy->isIntegral()) { @@ -1535,9 +1543,9 @@ if (Op0 == Op1) return ReplaceInstUsesWith(I, Op1); - // and X, -1 == X if (ConstantIntegral *AndRHS = dyn_cast(Op1)) { - if (AndRHS->isAllOnesValue()) // and X, -1 == X + // and X, -1 == X + if (AndRHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); if (MaskedValueIsZero(Op0, AndRHS)) // LHS & RHS == 0 @@ -1545,9 +1553,10 @@ // If the mask is not masking out any bits, there is no reason to do the // and in the first place. - if (MaskedValueIsZero(Op0, - cast(ConstantExpr::getNot(AndRHS)))) - return ReplaceInstUsesWith(I, Op0); + ConstantIntegral *NotAndRHS = + cast(ConstantExpr::getNot(AndRHS)); + if (MaskedValueIsZero(Op0, NotAndRHS)) + return ReplaceInstUsesWith(I, Op0); // Optimize a variety of ((val OP C1) & C2) combinations... if (isa(Op0) || isa(Op0)) { @@ -1563,6 +1572,28 @@ return BinaryOperator::createAnd(Op0RHS, AndRHS); if (MaskedValueIsZero(Op0RHS, AndRHS)) return BinaryOperator::createAnd(Op0LHS, AndRHS); + + // If the mask is only needed on one incoming arm, push it up. + if (Op0I->hasOneUse()) { + if (MaskedValueIsZero(Op0LHS, NotAndRHS)) { + // Not masking anything out for the LHS, move to RHS. + Instruction *NewRHS = BinaryOperator::createAnd(Op0RHS, AndRHS, + Op0RHS->getName()+".masked"); + InsertNewInstBefore(NewRHS, I); + return BinaryOperator::create( + cast(Op0I)->getOpcode(), Op0LHS, NewRHS); + } + if (!isa(NotAndRHS) && + MaskedValueIsZero(Op0RHS, NotAndRHS)) { + // Not masking anything out for the RHS, move to LHS. + Instruction *NewLHS = BinaryOperator::createAnd(Op0LHS, AndRHS, + Op0LHS->getName()+".masked"); + InsertNewInstBefore(NewLHS, I); + return BinaryOperator::create( + cast(Op0I)->getOpcode(), NewLHS, Op0RHS); + } + } + break; case Instruction::And: // (X & V) & C2 --> 0 iff (V & C2) == 0 From lattner at cs.uiuc.edu Sun Jan 23 15:45:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 15:45:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200501232145.j0NLjHJI011854@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.39 -> 1.40 --- Log message: Speed this up a bit by making ModifiedRegs a vector not vector --- Diffs of the changes: (+5 -6) PrologEpilogInserter.cpp | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.39 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.40 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.39 Fri Jan 21 18:49:16 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Sun Jan 23 15:45:01 2005 @@ -112,7 +112,7 @@ return; // This bitset contains an entry for each physical register for the target... - std::vector ModifiedRegs(RegInfo->getNumRegs()); + std::vector ModifiedRegs(RegInfo->getNumRegs()); unsigned MaxCallFrameSize = 0; bool HasCalls = false; @@ -209,7 +209,7 @@ const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); // Now that we have a stack slot for each register to be saved, insert spill - // code into the entry block... + // code into the entry block. MachineBasicBlock *MBB = Fn.begin(); MachineBasicBlock::iterator I = MBB->begin(); for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { @@ -219,8 +219,8 @@ // Add code to restore the callee-save registers in each exiting block. const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); - for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) { - // If last instruction is a return instruction, add an epilogue + for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) + // If last instruction is a return instruction, add an epilogue. if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { MBB = FI; I = MBB->end(); --I; @@ -232,12 +232,11 @@ --I; // Insert in reverse order } } - } } /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the -/// abstract stack objects... +/// abstract stack objects. /// void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); From lattner at cs.uiuc.edu Sun Jan 23 16:13:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 16:13:51 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFunction.h Message-ID: <200501232213.j0NMDpIv012406@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFunction.h updated: 1.45 -> 1.46 --- Log message: Expose more information from register allocation to passes that run after it. --- Diffs of the changes: (+26 -0) MachineFunction.h | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+) Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.45 llvm/include/llvm/CodeGen/MachineFunction.h:1.46 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.45 Wed Oct 27 11:14:51 2004 +++ llvm/include/llvm/CodeGen/MachineFunction.h Sun Jan 23 16:13:36 2005 @@ -97,6 +97,13 @@ // numbered and this vector keeps track of the mapping from ID's to MBB's. std::vector MBBNumbering; + /// UsedPhysRegs - This is a new[]'d array of bools that is computed and set + /// by the register allocator, and must be kept up to date by passes that run + /// after register allocation (though most don't modify this). This is used + /// so that the code generator knows which callee save registers to save and + /// for other target specific uses. + bool *UsedPhysRegs; + public: MachineFunction(const Function *Fn, const TargetMachine &TM); ~MachineFunction(); @@ -138,6 +145,25 @@ return static_cast(MFInfo); } + /// setUsedPhysRegs - The register allocator should call this to initialized + /// the UsedPhysRegs set. This should be passed a new[]'d array with entries + /// for all of the physical registers that the target supports. Each array + /// entry should be set to true iff the physical register is used within the + /// function. + void setUsedPhysRegs(bool *UPR) { UsedPhysRegs = UPR; } + + /// getUsedPhysregs - This returns the UsedPhysRegs array. This returns null + /// before register allocation. + const bool *getUsedPhysregs() { return UsedPhysRegs; } + + /// isPhysRegUsed - Return true if the specified register is used in this + /// function. This only works after register allocation. + bool isPhysRegUsed(unsigned Reg) { return UsedPhysRegs[Reg]; } + + /// changePhyRegUsed - This method allows code that runs after register + /// allocation to keep the PhysRegsUsed array up-to-date. + void changePhyRegUsed(unsigned Reg, bool State) { UsedPhysRegs[Reg] = State; } + /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they /// are inserted into the machine function. The block number for a machine /// basic block can be found by using the MBB::getBlockNumber method, this From lattner at cs.uiuc.edu Sun Jan 23 16:14:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 16:14:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineFunction.cpp Message-ID: <200501232214.j0NMEBjB012417@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineFunction.cpp updated: 1.74 -> 1.75 --- Log message: Add support for the PhysRegsUsed array. --- Diffs of the changes: (+3 -2) MachineFunction.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.74 llvm/lib/CodeGen/MachineFunction.cpp:1.75 --- llvm/lib/CodeGen/MachineFunction.cpp:1.74 Sat Jan 8 13:55:00 2005 +++ llvm/lib/CodeGen/MachineFunction.cpp Sun Jan 23 16:13:58 2005 @@ -61,7 +61,7 @@ /// stream is std::cerr; the default banner is empty. /// FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS, - const std::string &Banner) { + const std::string &Banner){ return new Printer(OS, Banner); } @@ -108,7 +108,7 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM) - : Annotation(MF_AID), Fn(F), Target(TM) { + : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) { SSARegMapping = new SSARegMap(); MFInfo = 0; FrameInfo = new MachineFrameInfo(); @@ -122,6 +122,7 @@ delete MFInfo; delete FrameInfo; delete ConstantPool; + delete[] UsedPhysRegs; } void MachineFunction::dump() const { print(std::cerr); } From alkis at cs.uiuc.edu Sun Jan 23 16:35:26 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 23 Jan 2005 16:35:26 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/MultipleInterfaces.java Message-ID: <200501232235.QAA19294@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: MultipleInterfaces.java updated: 1.5 -> 1.6 --- Log message: Change return types to make the test a bit more interesting. --- Diffs of the changes: (+4 -4) MultipleInterfaces.java | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm-java/test/Programs/SingleSource/UnitTests/MultipleInterfaces.java diff -u llvm-java/test/Programs/SingleSource/UnitTests/MultipleInterfaces.java:1.5 llvm-java/test/Programs/SingleSource/UnitTests/MultipleInterfaces.java:1.6 --- llvm-java/test/Programs/SingleSource/UnitTests/MultipleInterfaces.java:1.5 Mon Dec 13 21:00:03 2004 +++ llvm-java/test/Programs/SingleSource/UnitTests/MultipleInterfaces.java Sun Jan 23 16:35:15 2005 @@ -2,7 +2,7 @@ { interface I1 { - public int i1(); + public boolean i1(); } interface I2 @@ -12,14 +12,14 @@ interface I3 extends I1, I2 { - public int i3(); + public float i3(); } private static class C1 implements I3 { - public int i1() { return 1; } + public boolean i1() { return true; } public int i2() { return 2; } - public int i3() { return 3; } + public float i3() { return 3.0F; } } public static void main(String[] args) { From lattner at cs.uiuc.edu Sun Jan 23 16:45:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 16:45:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocIterativeScan.cpp RegAllocLinearScan.cpp VirtRegMap.cpp Message-ID: <200501232245.j0NMjSJj013418@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocIterativeScan.cpp updated: 1.20 -> 1.21 RegAllocLinearScan.cpp updated: 1.106 -> 1.107 VirtRegMap.cpp updated: 1.34 -> 1.35 --- Log message: Update these register allocators to set the PhysRegUsed info in MachineFunction. --- Diffs of the changes: (+35 -11) RegAllocIterativeScan.cpp | 10 +++++++++- RegAllocLinearScan.cpp | 11 +++++++++-- VirtRegMap.cpp | 25 +++++++++++++++++-------- 3 files changed, 35 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/RegAllocIterativeScan.cpp diff -u llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.20 llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.21 --- llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.20 Sat Jan 8 13:53:50 2005 +++ llvm/lib/CodeGen/RegAllocIterativeScan.cpp Sun Jan 23 16:45:12 2005 @@ -51,6 +51,7 @@ const TargetMachine* tm_; const MRegisterInfo* mri_; LiveIntervals* li_; + bool *PhysRegsUsed; typedef std::vector IntervalPtrs; IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_; @@ -145,6 +146,11 @@ tm_ = &fn.getTarget(); mri_ = tm_->getRegisterInfo(); li_ = &getAnalysis(); + + PhysRegsUsed = new bool[mri_->getNumRegs()]; + std::fill(PhysRegsUsed, PhysRegsUsed+mri_->getNumRegs(), false); + fn.setUsedPhysRegs(PhysRegsUsed); + if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_)); vrm_.reset(new VirtRegMap(*mf_)); if (!spiller_.get()) spiller_.reset(createSpiller()); @@ -256,8 +262,10 @@ for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){ unhandled_.push_back(&i->second); - if (MRegisterInfo::isPhysicalRegister(i->second.reg)) + if (MRegisterInfo::isPhysicalRegister(i->second.reg)) { + PhysRegsUsed[i->second.reg] = true; fixed_.push_back(&i->second); + } } } Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.106 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.107 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.106 Sat Jan 8 13:53:50 2005 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Sun Jan 23 16:45:12 2005 @@ -48,6 +48,7 @@ const TargetMachine* tm_; const MRegisterInfo* mri_; LiveIntervals* li_; + bool *PhysRegsUsed; /// handled_ - Intervals are added to the handled_ set in the order of their /// start value. This is uses for backtracking. @@ -139,6 +140,10 @@ mri_ = tm_->getRegisterInfo(); li_ = &getAnalysis(); + PhysRegsUsed = new bool[mri_->getNumRegs()]; + std::fill(PhysRegsUsed, PhysRegsUsed+mri_->getNumRegs(), false); + fn.setUsedPhysRegs(PhysRegsUsed); + if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_)); vrm_.reset(new VirtRegMap(*mf_)); if (!spiller_.get()) spiller_.reset(createSpiller()); @@ -147,6 +152,7 @@ linearScan(); + // Rewrite spill code and update the PhysRegsUsed set. spiller_->runOnMachineFunction(*mf_, *vrm_); vrm_.reset(); // Free the VirtRegMap @@ -170,9 +176,10 @@ "interval sets should be empty on initialization"); for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) { - if (MRegisterInfo::isPhysicalRegister(i->second.reg)) + if (MRegisterInfo::isPhysicalRegister(i->second.reg)) { + PhysRegsUsed[i->second.reg] = true; fixed_.push_back(std::make_pair(&i->second, i->second.begin())); - else + } else unhandled_.push(&i->second); } } Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.34 llvm/lib/CodeGen/VirtRegMap.cpp:1.35 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.34 Fri Jan 14 09:54:24 2005 +++ llvm/lib/CodeGen/VirtRegMap.cpp Sun Jan 23 16:45:13 2005 @@ -133,13 +133,14 @@ }; } -bool SimpleSpiller::runOnMachineFunction(MachineFunction& MF, - const VirtRegMap& VRM) { +bool SimpleSpiller::runOnMachineFunction(MachineFunction &MF, + const VirtRegMap &VRM) { DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n"); DEBUG(std::cerr << "********** Function: " << MF.getFunction()->getName() << '\n'); - const TargetMachine& TM = MF.getTarget(); - const MRegisterInfo& MRI = *TM.getRegisterInfo(); + const TargetMachine &TM = MF.getTarget(); + const MRegisterInfo &MRI = *TM.getRegisterInfo(); + bool *PhysRegsUsed = MF.getUsedPhysregs(); // LoadedRegs - Keep track of which vregs are loaded, so that we only load // each vreg once (in the case where a spilled vreg is used by multiple @@ -177,6 +178,7 @@ ++NumStores; } } + PhysRegsUsed[PhysReg] = true; MI.SetMachineOperandReg(i, PhysReg); } } @@ -296,6 +298,8 @@ // same stack slot, the original store is deleted. std::map MaybeDeadStores; + bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs(); + for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); MII != E; ) { MachineInstr &MI = *MII; @@ -313,7 +317,9 @@ if (!VRM.hasStackSlot(VirtReg)) { // This virtual register was assigned a physreg! - MI.SetMachineOperandReg(i, VRM.getPhys(VirtReg)); + unsigned Phys = VRM.getPhys(VirtReg); + PhysRegsUsed[Phys] = true; + MI.SetMachineOperandReg(i, Phys); } else { // Is this virtual register a spilled value? if (MO.isUse()) { @@ -397,7 +403,7 @@ } } ContinueReload: - + PhysRegsUsed[PhysReg] = true; MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); // This invalidates PhysReg. ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); @@ -429,9 +435,11 @@ // Loop over all of the implicit defs, clearing them from our available // sets. - const TargetInstrDescriptor &InstrDesc = TII->get(MI.getOpcode()); - for (const unsigned* ImpDef = InstrDesc.ImplicitDefs; *ImpDef; ++ImpDef) + for (const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode()); + *ImpDef; ++ImpDef) { + PhysRegsUsed[*ImpDef] = true; ClobberPhysReg(*ImpDef, SpillSlotsAvailable, PhysRegsAvailable); + } DEBUG(std::cerr << '\t' << MI); @@ -516,6 +524,7 @@ else PhysReg = MO.getReg(); + PhysRegsUsed[PhysReg] = true; MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot); DEBUG(std::cerr << "Store:\t" << *next(MII)); MI.SetMachineOperandReg(i, PhysReg); From lattner at cs.uiuc.edu Sun Jan 23 16:52:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 16:52:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200501232252.j0NMqBwF013564@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.70 -> 1.71 --- Log message: Update this pass to set PhysRegsUsed info in MachineFunction. --- Diffs of the changes: (+13 -1) RegAllocLocal.cpp | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.70 llvm/lib/CodeGen/RegAllocLocal.cpp:1.71 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.70 Tue Oct 26 10:35:58 2004 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Sun Jan 23 16:51:56 2005 @@ -38,6 +38,7 @@ MachineFunction *MF; const MRegisterInfo *RegInfo; LiveVariables *LV; + bool *PhysRegsEverUsed; // StackSlotForVirtReg - Maps virtual regs to the frame index where these // values are spilled. @@ -478,6 +479,7 @@ RegInfo->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex); ++NumLoads; // Update statistics + PhysRegsEverUsed[PhysReg] = true; MI->SetMachineOperandReg(OpNum, PhysReg); // Assign the input register return MI; } @@ -547,6 +549,7 @@ if (MO.isDef() && MO.isRegister() && MO.getReg() && MRegisterInfo::isPhysicalRegister(MO.getReg())) { unsigned Reg = MO.getReg(); + PhysRegsEverUsed[Reg] = true; spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in the reg PhysRegsUsed[Reg] = 0; // It is free and reserved now PhysRegsUseOrder.push_back(Reg); @@ -554,6 +557,7 @@ *AliasSet; ++AliasSet) { PhysRegsUseOrder.push_back(*AliasSet); PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now + PhysRegsEverUsed[*AliasSet] = true; } } } @@ -565,16 +569,19 @@ spillPhysReg(MBB, MI, Reg, true); PhysRegsUseOrder.push_back(Reg); PhysRegsUsed[Reg] = 0; // It is free and reserved now + PhysRegsEverUsed[Reg] = true; + for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); *AliasSet; ++AliasSet) { PhysRegsUseOrder.push_back(*AliasSet); PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now + PhysRegsEverUsed[*AliasSet] = true; } } // Okay, we have allocated all of the source operands and spilled any values // that would be destroyed by defs of this instruction. Loop over the - // implicit defs and assign them to a register, spilling incoming values if + // explicit defs and assign them to a register, spilling incoming values if // we need to scavenge a register. // for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -587,6 +594,7 @@ // If DestVirtReg already has a value, use it. if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg))) DestPhysReg = getReg(MBB, MI, DestVirtReg); + PhysRegsEverUsed[DestPhysReg] = true; markVirtRegModified(DestVirtReg); MI->SetMachineOperandReg(i, DestPhysReg); // Assign the output register } @@ -652,6 +660,10 @@ RegInfo = TM->getRegisterInfo(); LV = &getAnalysis(); + PhysRegsEverUsed = new bool[RegInfo->getNumRegs()]; + std::fill(PhysRegsEverUsed, PhysRegsEverUsed+RegInfo->getNumRegs(), false); + Fn.setUsedPhysRegs(PhysRegsEverUsed); + PhysRegsUsed.assign(RegInfo->getNumRegs(), -1); // initialize the virtual->physical register map to have a 'null' From lattner at cs.uiuc.edu Sun Jan 23 16:56:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 16:56:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp Message-ID: <200501232256.j0NMu0vd013679@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocSimple.cpp updated: 1.61 -> 1.62 --- Log message: Update physregsused info. --- Diffs of the changes: (+18 -10) RegAllocSimple.cpp | 28 ++++++++++++++++++---------- 1 files changed, 18 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.61 llvm/lib/CodeGen/RegAllocSimple.cpp:1.62 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.61 Wed Sep 1 17:55:35 2004 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Sun Jan 23 16:55:45 2005 @@ -35,6 +35,7 @@ MachineFunction *MF; const TargetMachine *TM; const MRegisterInfo *RegInfo; + bool *PhysRegsEverUsed; // StackSlotForVirtReg - Maps SSA Regs => frame index on the stack where // these values are spilled @@ -118,8 +119,10 @@ assert(RI+regIdx != RE && "Not enough registers!"); unsigned PhysReg = *(RI+regIdx); - if (!RegsUsed[PhysReg]) + if (!RegsUsed[PhysReg]) { + PhysRegsEverUsed[PhysReg] = true; return PhysReg; + } } } @@ -156,19 +159,20 @@ RegsUsed.resize(RegInfo->getNumRegs()); - // a preliminary pass that will invalidate any registers that - // are used by the instruction (including implicit uses) + // This is a preliminary pass that will invalidate any registers that are + // used by the instruction (including implicit uses). unsigned Opcode = MI->getOpcode(); const TargetInstrDescriptor &Desc = TM->getInstrInfo()->get(Opcode); - const unsigned *Regs = Desc.ImplicitUses; - while (*Regs) - RegsUsed[*Regs++] = true; + const unsigned *Regs; + for (Regs = Desc.ImplicitUses; *Regs; ++Regs) + RegsUsed[*Regs] = true; - Regs = Desc.ImplicitDefs; - while (*Regs) - RegsUsed[*Regs++] = true; + for (Regs = Desc.ImplicitDefs; *Regs; ++Regs) { + RegsUsed[*Regs] = true; + PhysRegsEverUsed[*Regs] = true; + } - // Loop over uses, move from memory into registers + // Loop over uses, move from memory into registers. for (int i = MI->getNumOperands() - 1; i >= 0; --i) { MachineOperand &op = MI->getOperand(i); @@ -225,6 +229,10 @@ TM = &MF->getTarget(); RegInfo = TM->getRegisterInfo(); + PhysRegsEverUsed = new bool[RegInfo->getNumRegs()]; + std::fill(PhysRegsEverUsed, PhysRegsEverUsed+RegInfo->getNumRegs(), false); + Fn.setUsedPhysRegs(PhysRegsEverUsed); + // Loop over all of the basic blocks, eliminating virtual register references for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) From lattner at cs.uiuc.edu Sun Jan 23 16:57:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 16:57:42 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFunction.h Message-ID: <200501232257.j0NMvgsU013707@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFunction.h updated: 1.46 -> 1.47 --- Log message: Add an accessor. --- Diffs of the changes: (+2 -1) MachineFunction.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.46 llvm/include/llvm/CodeGen/MachineFunction.h:1.47 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.46 Sun Jan 23 16:13:36 2005 +++ llvm/include/llvm/CodeGen/MachineFunction.h Sun Jan 23 16:57:27 2005 @@ -154,7 +154,8 @@ /// getUsedPhysregs - This returns the UsedPhysRegs array. This returns null /// before register allocation. - const bool *getUsedPhysregs() { return UsedPhysRegs; } + bool *getUsedPhysregs() { return UsedPhysRegs; } + const bool *getUsedPhysregs() const { return UsedPhysRegs; } /// isPhysRegUsed - Return true if the specified register is used in this /// function. This only works after register allocation. From lattner at cs.uiuc.edu Sun Jan 23 17:13:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 17:13:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200501232313.j0NNDRwF016805@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.40 -> 1.41 --- Log message: Simplify/speedup the PEI by not having to scan for uses of the callee saved registers. This information is computed directly by the register allocator now. --- Diffs of the changes: (+5 -19) PrologEpilogInserter.cpp | 24 +++++------------------- 1 files changed, 5 insertions(+), 19 deletions(-) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.40 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.41 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.40 Sun Jan 23 15:45:01 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Sun Jan 23 17:13:12 2005 @@ -111,8 +111,6 @@ FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) return; - // This bitset contains an entry for each physical register for the target... - std::vector ModifiedRegs(RegInfo->getNumRegs()); unsigned MaxCallFrameSize = 0; bool HasCalls = false; @@ -127,19 +125,6 @@ HasCalls = true; RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); } else { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - MachineOperand &MO = I->getOperand(i); - if (MO.isRegister() && MO.isDef()) { - assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Register allocation must be performed!"); - ModifiedRegs[MO.getReg()] = true; // Register is modified - } - - // Mark any implicitly defined registers as being modified. - for (const unsigned *ImpDefs = TII.getImplicitDefs(I->getOpcode()); - *ImpDefs; ++ImpDefs) - ModifiedRegs[*ImpDefs] = true; - } ++I; } @@ -150,14 +135,15 @@ // Now figure out which *callee saved* registers are modified by the current // function, thus needing to be saved and restored in the prolog/epilog. // + const bool *PhysRegsUsed = Fn.getUsedPhysregs(); for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; - if (ModifiedRegs[Reg]) { - RegsToSave.push_back(Reg); // If modified register... + if (PhysRegsUsed[Reg]) { + RegsToSave.push_back(Reg); // If the reg is modified, save it! } else { for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); - *AliasSet; ++AliasSet) { // Check alias registers too... - if (ModifiedRegs[*AliasSet]) { + *AliasSet; ++AliasSet) { // Check alias registers too. + if (PhysRegsUsed[*AliasSet]) { RegsToSave.push_back(Reg); break; } From lattner at cs.uiuc.edu Sun Jan 23 17:14:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 17:14:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86FloatingPoint.cpp Message-ID: <200501232314.j0NNECD7016818@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86FloatingPoint.cpp updated: 1.40 -> 1.41 --- Log message: Allow the FP stackifier to completely ignore functions that do not use FP at all. This should speed up the X86 backend fairly significantly on integer codes. Now if only we didn't have to compute livevar still... ;-) --- Diffs of the changes: (+15 -0) X86FloatingPoint.cpp | 15 +++++++++++++++ 1 files changed, 15 insertions(+) Index: llvm/lib/Target/X86/X86FloatingPoint.cpp diff -u llvm/lib/Target/X86/X86FloatingPoint.cpp:1.40 llvm/lib/Target/X86/X86FloatingPoint.cpp:1.41 --- llvm/lib/Target/X86/X86FloatingPoint.cpp:1.40 Wed Sep 1 17:55:36 2004 +++ llvm/lib/Target/X86/X86FloatingPoint.cpp Sun Jan 23 17:13:59 2005 @@ -157,6 +157,21 @@ /// register references into FP stack references. /// bool FPS::runOnMachineFunction(MachineFunction &MF) { + // We only need to run this pass if there are any FP registers used in this + // function. If it is all integer, there is nothing for us to do! + const bool *PhysRegsUsed = MF.getUsedPhysregs(); + bool FPIsUsed = false; + + assert(X86::FP6 == X86::FP0+6 && "Register enums aren't sorted right!"); + for (unsigned i = 0; i <= 6; ++i) + if (PhysRegsUsed[X86::FP0+i]) { + FPIsUsed = true; + break; + } + + // Early exit. + if (!FPIsUsed) return false; + LV = &getAnalysis(); StackTop = 0; From lattner at cs.uiuc.edu Sun Jan 23 17:19:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 17:19:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200501232319.j0NNJxgG018182@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.52 -> 1.53 --- Log message: Silence optimized warnings. --- Diffs of the changes: (+1 -1) LegalizeDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.52 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.53 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.52 Sat Jan 22 22:42:50 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Jan 23 17:19:44 2005 @@ -1454,7 +1454,7 @@ SDOperand InChain = FindInputOutputChains(Source.Val, OutChain, DAG.getEntryNode()); - const char *FnName; + const char *FnName = 0; if (isSigned) { if (DestTy == MVT::f32) FnName = "__floatdisf"; From lattner at cs.uiuc.edu Sun Jan 23 17:20:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 17:20:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200501232320.j0NNKLXf018300@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.86 -> 1.87 --- Log message: Silence a warning. --- Diffs of the changes: (+1 -1) X86ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.86 llvm/lib/Target/X86/X86ISelPattern.cpp:1.87 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.86 Fri Jan 21 15:43:02 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sun Jan 23 17:20:06 2005 @@ -2587,7 +2587,7 @@ // Handle: [mem] op= CST SDOperand Op0 = StVal.getOperand(0); SDOperand Op1 = StVal.getOperand(1); - unsigned Opc; + unsigned Opc = 0; if (ConstantSDNode *CN = dyn_cast(Op1)) { switch (Op0.getValueType()) { // Use Op0's type because of shifts. default: break; From lattner at cs.uiuc.edu Sun Jan 23 19:40:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 19:40:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Message-ID: <200501240140.j0O1eXXb025603@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9BurgISel.cpp updated: 1.14 -> 1.15 --- Log message: Fix a spurious warning. --- Diffs of the changes: (+1 -1) SparcV9BurgISel.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp diff -u llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.14 llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.15 --- llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.14 Mon Jan 17 00:47:26 2005 +++ llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Sun Jan 23 19:40:18 2005 @@ -627,7 +627,7 @@ bool smallNegValue =isSigned && sC < 0 && sC != -sC && -sC < (int32_t)MAXSIMM; //Create TmpInstruction for intermediate values - TmpInstruction *tmpReg; + TmpInstruction *tmpReg = 0; // Set the high 22 bits in dest if non-zero and simm13 field of OR not enough if (!smallNegValue && (C & ~MAXLO) && C > MAXSIMM) { From lattner at cs.uiuc.edu Sun Jan 23 20:08:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 20:08:50 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Type.h Message-ID: <200501240208.j0O28oFf005731@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Type.h updated: 1.68 -> 1.69 --- Log message: This giant patch speeds up Type::isSized(). Before, this would have to search large nested types over and over again to determine if they are sized or not. Now, isSized() is able to make snap decisions about all concrete types, which are a common occurance (and includes all primitives). On 177.mesa, this speeds up DSE from 39.5s -> 21.3s and GCSE from 13.2s -> 11.3s, reducing gccas time from 80s -> 61s (this is a debug build). DSE and GCSE are still too slow on this testcase, but this is a simple improvement. --- Diffs of the changes: (+1 -2) Type.h | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/include/llvm/Type.h diff -u llvm/include/llvm/Type.h:1.68 llvm/include/llvm/Type.h:1.69 --- llvm/include/llvm/Type.h:1.68 Mon Dec 13 10:28:53 2004 +++ llvm/include/llvm/Type.h Sun Jan 23 20:08:34 2005 @@ -201,8 +201,7 @@ /// TargetData subsystem to do this. /// bool isSized() const { - return (ID >= BoolTyID && ID <= DoubleTyID) || ID == PointerTyID || - isSizedDerivedType(); + return !isAbstract() || ID == PointerTyID || isSizedDerivedType(); } /// getPrimitiveSize - Return the basic size of this type if it is a primitive From lattner at cs.uiuc.edu Sun Jan 23 22:04:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 22:04:57 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.f2c Message-ID: <200501240404.j0O44vXX024934@apoc.cs.uiuc.edu> Changes in directory llvm-test: Makefile.f2c updated: 1.4 -> 1.5 --- Log message: Successfully internalize the f2c tests. --- Diffs of the changes: (+5 -1) Makefile.f2c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm-test/Makefile.f2c diff -u llvm-test/Makefile.f2c:1.4 llvm-test/Makefile.f2c:1.5 --- llvm-test/Makefile.f2c:1.4 Mon Oct 25 15:21:35 2004 +++ llvm-test/Makefile.f2c Sun Jan 23 22:04:42 2005 @@ -29,7 +29,11 @@ %.c: %.f $(F2C) $< > /dev/null 2>&1 - + CPPFLAGS = -I$(F2C_INC) LDFLAGS += -L$(F2C_LIB) -lf2c + +# 'main' is defined in the f2c runtime library. The function exported from the +# program is named MAIN__ +EXTRA_LINKTIME_OPT_FLAGS += -internalize-public-api-list=MAIN__ \ No newline at end of file From lattner at cs.uiuc.edu Sun Jan 23 22:05:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 23 Jan 2005 22:05:08 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200501240405.j0O458MO024941@apoc.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.146 -> 1.147 --- Log message: Allow extra options to be specified for gccld. --- 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.146 llvm-test/Makefile.programs:1.147 --- llvm-test/Makefile.programs:1.146 Sun Jan 16 20:03:01 2005 +++ llvm-test/Makefile.programs Sun Jan 23 22:04:25 2005 @@ -207,7 +207,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.llvm.bc): \ Output/%.llvm.bc: Output/%.linked.bc $(LGCCLDPROG) - -$(LGCCLD) $(STATS) $< -lc $(LIBS) -lcrtend -o Output/$*.llvm + -$(LGCCLD) $(STATS) $(EXTRA_LINKTIME_OPT_FLAGS) $< -lc $(LIBS) -lcrtend -o Output/$*.llvm ifneq ($(OPTPASSES),) -$(LOPT) -q $(OPTPASSES) < $@ > $@.tmp $(MV) -f $@.tmp $@