From lattner at persephone.cs.uiuc.edu Mon Aug 29 08:14:50 2005 From: lattner at persephone.cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 08:14:50 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/lib/Support/ToolRunner.cpp Message-ID: <20050829131450.1581B14AC3DA@persephone.cs.uiuc.edu> Changes in directory llvm/lib/Support: ToolRunner.cpp updated: 1.45 -> 1.46 --- Log message: Allow bugpoint+PPC codegen to use fsqrt --- Diffs of the changes: (+3 -0) ToolRunner.cpp | 3 +++ 1 files changed, 3 insertions Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.45 llvm/lib/Support/ToolRunner.cpp:1.46 --- llvm/lib/Support/ToolRunner.cpp:1.45 Thu Jul 7 22:08:58 2005 +++ llvm/lib/Support/ToolRunner.cpp Mon Aug 29 08:14:24 2005 @@ -385,6 +385,9 @@ GCCArgs.push_back("-fno-strict-aliasing"); } else { GCCArgs.push_back("assembler"); +#ifdef __APPLE__ + GCCArgs.push_back("-force_cpusubtype_ALL"); +#endif } GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename... GCCArgs.push_back("-o"); From lattner at cs.uiuc.edu Mon Aug 29 12:30:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 12:30:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200508291730.MAA07382@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.175 -> 1.176 --- Log message: Fix an infinite loop on x86 --- 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.175 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.176 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.175 Fri Aug 26 17:50:40 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Aug 29 12:30:00 2005 @@ -1838,7 +1838,7 @@ if (Tmp.Val) { AddLegalizedOperand(Op, Tmp); NeedsAnotherIteration = true; - return Result; + return Tmp; } else { // The target thinks this is legal afterall. break; From alenhar2 at cs.uiuc.edu Mon Aug 29 15:47:02 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 29 Aug 2005 15:47:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200508292047.PAA04700@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.176 -> 1.177 --- Log message: Some of us cared about the the promote path --- Diffs of the changes: (+4 -0) LegalizeDAG.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.176 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.177 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.176 Mon Aug 29 12:30:00 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Aug 29 15:46:51 2005 @@ -1266,6 +1266,10 @@ default: assert(0 && "Cannot handle this action for SETCC yet!"); break; + case TargetLowering::Promote: + Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2, + Node->getOperand(2)); + break; case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2, From lattner at cs.uiuc.edu Mon Aug 29 16:59:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 16:59:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508292159.QAA05417@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.173 -> 1.174 --- Log message: Add a new API for Nate --- Diffs of the changes: (+27 -0) SelectionDAG.cpp | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.173 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.174 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.173 Sun Aug 28 18:59:36 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Aug 29 16:59:31 2005 @@ -228,6 +228,33 @@ delete N; } +void SelectionDAG::DeleteNode(SDNode *N) { + assert(N->use_empty() && "Cannot delete a node that is not dead!"); + + // First take this out of the appropriate CSE map. + RemoveNodeFromCSEMaps(N); + + // Remove it from the AllNodes list. + for (std::vector::iterator I = AllNodes.begin(); ; ++I) { + assert(I != AllNodes.end() && "Node not in AllNodes list??"); + if (*I == N) { + // Erase from the vector, which is not ordered. + std::swap(*I, AllNodes.back()); + AllNodes.pop_back(); + break; + } + } + + // Drop all of the operands and decrement used nodes use counts. + while (!N->Operands.empty()) { + SDNode *O = N->Operands.back().Val; + N->Operands.pop_back(); + O->removeUser(N); + } + + delete N; +} + /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that /// correspond to it. This is useful when we're about to delete or repurpose /// the node. We don't want future request for structurally identical nodes From lattner at cs.uiuc.edu Mon Aug 29 17:00:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 17:00:11 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200508292200.RAA05505@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.55 -> 1.56 --- Log message: Add a new API for nate --- Diffs of the changes: (+5 -0) SelectionDAG.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.55 llvm/include/llvm/CodeGen/SelectionDAG.h:1.56 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.55 Fri Aug 26 13:35:58 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Mon Aug 29 17:00:00 2005 @@ -287,6 +287,11 @@ void ReplaceAllUsesWith(SDNode *From, SDNode *To); void ReplaceAllUsesWith(SDNode *From, const std::vector &To); + + /// DeleteNode - Remove the specified node from the system. This node must + /// have no referrers. + void DeleteNode(SDNode *N); + void dump() const; private: From lattner at cs.uiuc.edu Mon Aug 29 17:23:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 17:23:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508292223.RAA05698@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.51 -> 1.52 --- Log message: Fix a dumb bug of mine where we were mishandling the PPC ABI (undef handling). This fixes voronoi and bh in Olden, allowing all of olden to pass! --- Diffs of the changes: (+16 -15) PPC32ISelDAGToDAG.cpp | 31 ++++++++++++++++--------------- 1 files changed, 16 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.51 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.52 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.51 Sun Aug 28 20:07:02 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Mon Aug 29 17:22:57 2005 @@ -1479,27 +1479,28 @@ PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 }; - for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) + for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { + unsigned DestReg = 0; + MVT::ValueType RegTy; + if (N->getOperand(i).getValueType() == MVT::i32) { + assert(GPR_idx < 8 && "Too many int args"); + DestReg = GPR[GPR_idx++]; + RegTy = MVT::i32; + } else { + assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && + "Unpromoted integer arg?"); + assert(FPR_idx < 13 && "Too many fp args"); + DestReg = FPR[FPR_idx++]; + RegTy = MVT::f64; // Even if this is really f32! + } + if (N->getOperand(i).getOpcode() != ISD::UNDEF) { - unsigned DestReg = 0; - MVT::ValueType RegTy; - if (N->getOperand(i).getValueType() == MVT::i32) { - assert(GPR_idx < 8 && "Too many int args"); - DestReg = GPR[GPR_idx++]; - RegTy = MVT::i32; - } else { - assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && - "Unpromoted integer arg?"); - assert(FPR_idx < 13 && "Too many fp args"); - DestReg = FPR[FPR_idx++]; - RegTy = MVT::f64; // Even if this is really f32! - } - SDOperand Reg = CurDAG->getRegister(DestReg, RegTy); Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, Reg, Select(N->getOperand(i))); CallOperands.push_back(Reg); } + } // Finally, once everything is in registers to pass to the call, emit the // call itself. From lattner at cs.uiuc.edu Mon Aug 29 17:48:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 17:48:43 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200508292248.RAA05851@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.64 -> 1.65 --- Log message: improve comment --- Diffs of the changes: (+3 -1) SelectionDAGNodes.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.64 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.65 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.64 Sat Aug 27 14:06:05 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Mon Aug 29 17:48:32 2005 @@ -220,7 +220,9 @@ // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned // to a specified boundary. The first operand is the token chain, the // second is the number of bytes to allocate, and the third is the alignment - // boundary. + // boundary. The size is guaranteed to be a multiple of the stack + // alignment, and the alignment is guaranteed to be bigger than the stack + // alignment (if required) or 0 to get standard stack alignment. DYNAMIC_STACKALLOC, // Control flow instructions. These all have token chains. From lattner at cs.uiuc.edu Mon Aug 29 18:21:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 18:21:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200508292321.SAA06085@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.17 -> 1.18 --- Log message: Add a hack to avoid some horrible code in some cases by always emitting token chains first. For this C function: int test() { int i; for (i = 0; i < 100000; ++i) foo(); } Instead of emitting this (condition before call) .LBB_test_1: ; no_exit addi r30, r30, 1 lis r2, 1 ori r2, r2, 34464 cmpw cr2, r30, r2 bl L_foo$stub bne cr2, .LBB_test_1 ; no_exit Emit this: .LBB_test_1: ; no_exit bl L_foo$stub addi r30, r30, 1 lis r2, 1 ori r2, r2, 34464 cmpw cr0, r30, r2 bne cr0, .LBB_test_1 ; no_exit Which makes it so we don't have to save/restore cr2 in the prolog/epilog of the function. This also makes the code much more similar to what the pattern isel produces. --- Diffs of the changes: (+31 -12) ScheduleDAG.cpp | 43 +++++++++++++++++++++++++++++++------------ 1 files changed, 31 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.17 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.18 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.17 Fri Aug 26 19:58:02 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Aug 29 18:21:29 2005 @@ -97,6 +97,7 @@ while (NodeOperands && Op.getOperand(NodeOperands-1).getValueType() == MVT::Flag) --NodeOperands; + if (NodeOperands && // Ignore chain if it exists. Op.getOperand(NodeOperands-1).getValueType() == MVT::Other) --NodeOperands; @@ -125,18 +126,24 @@ } } - // Emit all of the operands of this instruction, adding them to the + // If there is a token chain operand, emit it first, as a hack to get avoid + // really bad cases. + if (Op.getNumOperands() > NodeOperands && + Op.getOperand(NodeOperands).getValueType() == MVT::Other) + Emit(Op.getOperand(NodeOperands)); + + // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. - for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) { + for (unsigned i = 0; i != NodeOperands; ++i) { if (Op.getOperand(i).isTargetOpcode()) { // Note that this case is redundant with the final else block, but we // include it because it is the most common and it makes the logic // simpler here. - unsigned R = Emit(Op.getOperand(i)); - // Add an operand, unless this corresponds to a chain or flag node. - MVT::ValueType VT = Op.getOperand(i).getValueType(); - if (VT != MVT::Other && VT != MVT::Flag) - MI->addRegOperand(R, MachineOperand::Use); + assert(Op.getOperand(i).getValueType() != MVT::Other && + Op.getOperand(i).getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + + MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use); } else if (ConstantSDNode *C = dyn_cast(Op.getOperand(i))) { MI->addZeroExtImm64Operand(C->getValue()); @@ -159,14 +166,26 @@ dyn_cast(Op.getOperand(i))) { MI->addExternalSymbolOperand(ES->getSymbol(), false); } else { - unsigned R = Emit(Op.getOperand(i)); - // Add an operand, unless this corresponds to a chain or flag node. - MVT::ValueType VT = Op.getOperand(i).getValueType(); - if (VT != MVT::Other && VT != MVT::Flag) - MI->addRegOperand(R, MachineOperand::Use); + assert(Op.getOperand(i).getValueType() != MVT::Other && + Op.getOperand(i).getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use); } } + // Finally, if this node has any flag operands, we *must* emit them last, to + // avoid emitting operations that might clobber the flags. + if (Op.getNumOperands() > NodeOperands) { + unsigned i = NodeOperands; + if (Op.getOperand(i).getValueType() == MVT::Other) + ++i; // the chain is already selected. + for (; i != Op.getNumOperands(); ++i) { + assert(Op.getOperand(i).getValueType() == MVT::Flag && + "Must be flag operands!"); + Emit(Op.getOperand(i)); + } + } + // Now that we have emitted all operands, emit this instruction itself. if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { BB->insert(BB->end(), MI); From lattner at cs.uiuc.edu Mon Aug 29 18:30:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 18:30:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508292330.SAA06169@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.52 -> 1.53 --- Log message: Implement DYNAMIC_STACKALLOC, wrap some long lines --- Diffs of the changes: (+35 -2) PPC32ISelDAGToDAG.cpp | 37 +++++++++++++++++++++++++++++++++++-- 1 files changed, 35 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.52 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.53 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.52 Mon Aug 29 17:22:57 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Mon Aug 29 18:30:11 2005 @@ -738,6 +738,37 @@ CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA); break; } + case ISD::DYNAMIC_STACKALLOC: { + // FIXME: We are currently ignoring the requested alignment for handling + // greater than the stack alignment. This will need to be revisited at some + // point. Align = N.getOperand(2); + if (!isa(N->getOperand(2)) || + cast(N->getOperand(2))->getValue() != 0) { + std::cerr << "Cannot allocate stack object with greater alignment than" + << " the stack alignment yet!"; + abort(); + } + SDOperand Chain = Select(N->getOperand(0)); + SDOperand Amt = Select(N->getOperand(1)); + + SDOperand R1Reg = CurDAG->getRegister(PPC::R1, MVT::i32); + + // Subtract the amount (guaranteed to be a multiple of the stack alignment) + // from the stack pointer, giving us the result pointer. + SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Reg); + + // Copy this result back into R1. + Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R1Reg, Result); + + // Copy this result back out of R1 to make sure we're not using the stack + // space without decrementing the stack pointer. + Result = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); + + // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg. + CurDAG->ReplaceAllUsesWith(N, Result.Val); + N = Result.Val; + break; + } case ISD::SIGN_EXTEND_INREG: switch(cast(N->getOperand(1))->getVT()) { default: assert(0 && "Illegal type in SIGN_EXTEND_INREG"); break; @@ -1101,8 +1132,10 @@ int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); SDOperand FI = CurDAG->getTargetFrameIndex(FrameIdx, MVT::f64); - SDOperand ST = CurDAG->getTargetNode(PPC::STFD, MVT::Other, In, getI32Imm(0), FI); - CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, MVT::Other, getI32Imm(4), FI, ST); + SDOperand ST = CurDAG->getTargetNode(PPC::STFD, MVT::Other, In, + getI32Imm(0), FI); + CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, MVT::Other, + getI32Imm(4), FI, ST); break; } case ISD::FNEG: { From lattner at cs.uiuc.edu Mon Aug 29 18:49:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 18:49:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508292349.SAA06355@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.53 -> 1.54 --- Log message: fix a crash in cfrac --- Diffs of the changes: (+2 -2) PPC32ISelDAGToDAG.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.53 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.54 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.53 Mon Aug 29 18:30:11 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Mon Aug 29 18:49:25 2005 @@ -1373,8 +1373,8 @@ break; case ISD::SETNE: { Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op); - SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, Op, - getI32Imm(~0U)); + SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, + Op, getI32Imm(~0U)); CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); break; } From lattner at cs.uiuc.edu Mon Aug 29 19:19:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 19:19:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200508300019.TAA06641@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.11 -> 1.12 --- Log message: Fix some really strange indentation that xcode likes to use. no xcode, this is not right: if (!foo) break; X; --- Diffs of the changes: (+158 -157) PPC32ISelLowering.cpp | 315 +++++++++++++++++++++++++------------------------- 1 files changed, 158 insertions(+), 157 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.11 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.12 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.11 Fri Aug 26 16:23:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Mon Aug 29 19:19:00 2005 @@ -199,63 +199,63 @@ MVT::ValueType ObjectVT = getValueType(I->getType()); switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - ObjSize = 4; - if (!ArgLive) break; - if (GPR_remaining > 0) { - MF.addLiveIn(GPR[GPR_idx]); - argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), - GPR[GPR_idx], MVT::i32); - if (ObjectVT != MVT::i32) - argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); - } else { - needsLoad = true; - } - break; - case MVT::i64: ObjSize = 8; - if (!ArgLive) break; - if (GPR_remaining > 0) { - SDOperand argHi, argLo; - MF.addLiveIn(GPR[GPR_idx]); - argHi = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32); - // If we have two or more remaining argument registers, then both halves - // of the i64 can be sourced from there. Otherwise, the lower half will - // have to come off the stack. This can happen when an i64 is preceded - // by 28 bytes of arguments. - if (GPR_remaining > 1) { - MF.addLiveIn(GPR[GPR_idx+1]); - argLo = DAG.getCopyFromReg(argHi, GPR[GPR_idx+1], MVT::i32); - } else { - int FI = MFI->CreateFixedObject(4, ArgOffset+4); - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - } - // Build the outgoing arg thingy - argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); - newroot = argLo; - } else { - needsLoad = true; - } - break; - case MVT::f32: - case MVT::f64: - ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; - if (!ArgLive) break; - if (FPR_remaining > 0) { - MF.addLiveIn(FPR[FPR_idx]); - argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), - FPR[FPR_idx], ObjectVT); - --FPR_remaining; - ++FPR_idx; - } else { - needsLoad = true; - } - break; + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + ObjSize = 4; + if (!ArgLive) break; + if (GPR_remaining > 0) { + MF.addLiveIn(GPR[GPR_idx]); + argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), + GPR[GPR_idx], MVT::i32); + if (ObjectVT != MVT::i32) + argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); + } else { + needsLoad = true; + } + break; + case MVT::i64: ObjSize = 8; + if (!ArgLive) break; + if (GPR_remaining > 0) { + SDOperand argHi, argLo; + MF.addLiveIn(GPR[GPR_idx]); + argHi = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32); + // If we have two or more remaining argument registers, then both halves + // of the i64 can be sourced from there. Otherwise, the lower half will + // have to come off the stack. This can happen when an i64 is preceded + // by 28 bytes of arguments. + if (GPR_remaining > 1) { + MF.addLiveIn(GPR[GPR_idx+1]); + argLo = DAG.getCopyFromReg(argHi, GPR[GPR_idx+1], MVT::i32); + } else { + int FI = MFI->CreateFixedObject(4, ArgOffset+4); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + } + // Build the outgoing arg thingy + argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); + newroot = argLo; + } else { + needsLoad = true; + } + break; + case MVT::f32: + case MVT::f64: + ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; + if (!ArgLive) break; + if (FPR_remaining > 0) { + MF.addLiveIn(FPR[FPR_idx]); + argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), + FPR[FPR_idx], ObjectVT); + --FPR_remaining; + ++FPR_idx; + } else { + needsLoad = true; + } + break; } // We need to load the argument to a virtual register if we determined above @@ -349,26 +349,27 @@ Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); } else { - for (unsigned i = 0, e = Args.size(); i != e; ++i) + for (unsigned i = 0, e = Args.size(); i != e; ++i) { switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - case MVT::f64: - NumBytes += 8; - break; + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + case MVT::f64: + NumBytes += 8; + break; } + } - // Just to be safe, we'll always reserve the full 24 bytes of linkage area - // plus 32 bytes of argument space in case any called code gets funky on us. - // (Required by ABI to support var arg) - if (NumBytes < 56) NumBytes = 56; + // Just to be safe, we'll always reserve the full 24 bytes of linkage area + // plus 32 bytes of argument space in case any called code gets funky on us. + // (Required by ABI to support var arg) + if (NumBytes < 56) NumBytes = 56; // Adjust the stack pointer for the new arguments... // These operations are automatically eliminated by the prolog/epilog pass @@ -398,102 +399,102 @@ MVT::ValueType ArgVT = getValueType(Args[i].second); switch (ArgVT) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - // Promote the integer to 32 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::i32, Args[i].first); - else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); - // FALL THROUGH - case MVT::i32: + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + // Promote the integer to 32 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::i32, Args[i].first); + else + Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + // FALL THROUGH + case MVT::i32: + if (GPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + --GPR_remaining; + } else { + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + } + ArgOffset += 4; + break; + case MVT::i64: + // If we have one free GPR left, we can place the upper half of the i64 + // in it, and store the other half to the stack. If we have two or more + // free GPRs, then we can pass both halves of the i64 in registers. + if (GPR_remaining > 0) { + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(0, MVT::i32)); + args_to_use.push_back(Hi); + --GPR_remaining; if (GPR_remaining > 0) { - args_to_use.push_back(Args[i].first); + args_to_use.push_back(Lo); --GPR_remaining; } else { + SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); + Lo, PtrOff, DAG.getSrcValue(NULL))); } - ArgOffset += 4; - break; - case MVT::i64: - // If we have one free GPR left, we can place the upper half of the i64 - // in it, and store the other half to the stack. If we have two or more - // free GPRs, then we can pass both halves of the i64 in registers. - if (GPR_remaining > 0) { - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - args_to_use.push_back(Hi); - --GPR_remaining; + } else { + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + } + ArgOffset += 8; + break; + case MVT::f32: + case MVT::f64: + if (FPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + --FPR_remaining; + if (isVarArg) { + SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL)); + MemOps.push_back(Store); + // Float varargs are always shadowed in available integer registers if (GPR_remaining > 0) { - args_to_use.push_back(Lo); + SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, + DAG.getSrcValue(NULL)); + MemOps.push_back(Load); + args_to_use.push_back(Load); --GPR_remaining; - } else { + } + if (GPR_remaining > 0 && MVT::f64 == ArgVT) { SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Lo, PtrOff, DAG.getSrcValue(NULL))); + SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, + DAG.getSrcValue(NULL)); + MemOps.push_back(Load); + args_to_use.push_back(Load); + --GPR_remaining; } } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - } - ArgOffset += 8; - break; - case MVT::f32: - case MVT::f64: - if (FPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --FPR_remaining; - if (isVarArg) { - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Store); - // Float varargs are always shadowed in available integer registers - if (GPR_remaining > 0) { - SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Load); - args_to_use.push_back(Load); - --GPR_remaining; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Load); - args_to_use.push_back(Load); - --GPR_remaining; - } - } else { - // If we have any FPRs remaining, we may also have GPRs remaining. - // Args passed in FPRs consume either 1 (f32) or 2 (f64) available - // GPRs. - if (GPR_remaining > 0) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); - --GPR_remaining; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); - --GPR_remaining; - } + // If we have any FPRs remaining, we may also have GPRs remaining. + // Args passed in FPRs consume either 1 (f32) or 2 (f64) available + // GPRs. + if (GPR_remaining > 0) { + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + --GPR_remaining; + } + if (GPR_remaining > 0 && MVT::f64 == ArgVT) { + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + --GPR_remaining; } - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); } - ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; - break; + } else { + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + } + ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; + break; } } if (!MemOps.empty()) From lattner at cs.uiuc.edu Mon Aug 29 19:30:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 19:30:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508300030.TAA06840@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.54 -> 1.55 --- Log message: emit FMR instructions to convert f64<->f32 instructions, so things like STOREs, know the right type to store. --- Diffs of the changes: (+15 -8) PPC32ISelDAGToDAG.cpp | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.54 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.55 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.54 Mon Aug 29 18:49:25 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Mon Aug 29 19:30:43 2005 @@ -1113,14 +1113,13 @@ CurDAG->SelectNodeTo(N, PPC::FABS, N->getValueType(0), Select(N->getOperand(0))); break; - case ISD::FP_EXTEND: { + case ISD::FP_EXTEND: assert(MVT::f64 == N->getValueType(0) && MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND"); - std::vector Tmp; - Tmp.push_back(Select(N->getOperand(0))); - CurDAG->ReplaceAllUsesWith(N, Tmp); // Just use the operand as the result. - return Tmp[0]; - } + // We need to emit an FMR to make sure that the result has the right value + // type. + CurDAG->SelectNodeTo(N, PPC::FMR, MVT::f64, Select(N->getOperand(0))); + break; case ISD::FP_ROUND: assert(MVT::f32 == N->getValueType(0) && MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND"); @@ -1560,7 +1559,12 @@ case MVT::f32: case MVT::f64: Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, MVT::f64).getValue(1); - CallResults.push_back(Chain.getValue(0)); + if (N->getValueType(0) == MVT::f64) + CallResults.push_back(Chain.getValue(0)); + else + // Insert an FMR to convert the result to f32 from f64. + CallResults.push_back(CurDAG->getTargetNode(PPC::FMR, MVT::f32, + Chain.getValue(0))); break; } @@ -1575,8 +1579,11 @@ SDOperand Val = Select(N->getOperand(1)); switch (N->getOperand(1).getValueType()) { default: assert(0 && "Unknown return type!"); - case MVT::f64: case MVT::f32: + // Insert a copy to get the type right. + Val = CurDAG->getTargetNode(PPC::FMR, MVT::f64, Val); + // FALL THROUGH + case MVT::f64: Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); break; case MVT::i32: From lattner at cs.uiuc.edu Mon Aug 29 19:45:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 19:45:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200508300045.TAA06978@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.12 -> 1.13 --- Log message: Fix a bug in my patch for legalizing to fsel. It cannot handle seteq/setne, which I failed to include when I moved the code over. This fixes MallocBench/gs. --- Diffs of the changes: (+4 -0) PPC32ISelLowering.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.12 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.13 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.12 Mon Aug 29 19:19:00 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Mon Aug 29 19:45:18 2005 @@ -111,6 +111,10 @@ if (MVT::isFloatingPoint(Op.getOperand(0).getValueType()) && MVT::isFloatingPoint(Op.getOperand(2).getValueType())) { ISD::CondCode CC = cast(Op.getOperand(4))->get(); + + // Cannot handle SETEQ/SETNE. + if (CC == ISD::SETEQ || CC == ISD::SETNE) break; + MVT::ValueType ResVT = Op.getValueType(); MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); From lattner at cs.uiuc.edu Mon Aug 29 19:59:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 19:59:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508300059.TAA07074@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.55 -> 1.56 --- Log message: The first operand to AND does not always have more than two operands. This fixes MediaBench/toast with the dag selector --- Diffs of the changes: (+2 -1) PPC32ISelDAGToDAG.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.55 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.56 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.55 Mon Aug 29 19:30:43 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Mon Aug 29 19:59:16 2005 @@ -167,7 +167,8 @@ unsigned Shift = 32; unsigned Indeterminant = ~0; // bit mask marking indeterminant results unsigned Opcode = N->getOpcode(); - if (!isIntImmediate(N->getOperand(1).Val, Shift) || (Shift > 31)) + if (N->getNumOperands() != 2 || + !isIntImmediate(N->getOperand(1).Val, Shift) || (Shift > 31)) return false; if (Opcode == ISD::SHL) { From lattner at cs.uiuc.edu Mon Aug 29 20:56:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 20:56:24 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200508300156.UAA07592@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.56 -> 1.57 --- Log message: add some method variants --- Diffs of the changes: (+39 -0) SelectionDAG.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.56 llvm/include/llvm/CodeGen/SelectionDAG.h:1.57 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.56 Mon Aug 29 17:00:00 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Mon Aug 29 20:56:13 2005 @@ -112,6 +112,22 @@ getRegister(Reg, N.getValueType()), N); } + // This version of the getCopyToReg method takes an extra operand, which + // indicates that there is potentially an incoming flag value (if Flag is not + // null) and that there should be a flag result. + SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N, + SDOperand Flag) { + std::vector VTs; + VTs.push_back(MVT::Other); + VTs.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(getRegister(Reg, N.getValueType())); + Ops.push_back(N); + if (Flag.Val) Ops.push_back(Flag); + return getNode(ISD::CopyToReg, VTs, Ops); + } + SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) { std::vector ResultTys; ResultTys.push_back(VT); @@ -121,6 +137,22 @@ Ops.push_back(getRegister(Reg, VT)); return getNode(ISD::CopyFromReg, ResultTys, Ops); } + + // This version of the getCopyFromReg method takes an extra operand, which + // indicates that there is potentially an incoming flag value (if Flag is not + // null) and that there should be a flag result. + SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT, + SDOperand Flag) { + std::vector ResultTys; + ResultTys.push_back(VT); + ResultTys.push_back(MVT::Other); + ResultTys.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(getRegister(Reg, VT)); + if (Flag.Val) Ops.push_back(Flag); + return getNode(ISD::CopyFromReg, ResultTys, Ops); + } SDOperand getImplicitDef(SDOperand Chain, unsigned Reg, MVT::ValueType VT) { return getNode(ISD::ImplicitDef, MVT::Other, Chain, getRegister(Reg, VT)); @@ -277,6 +309,13 @@ std::vector &Ops) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Ops); } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, std::vector &Ops) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. /// This can cause recursive merging of nodes in the DAG. Use the first From lattner at cs.uiuc.edu Mon Aug 29 20:57:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 20:57:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508300157.UAA07654@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.56 -> 1.57 --- Log message: Make sure the selector emits register register copies with flag operands linking them to calls when appropriate, this prevents the scheduler from pulling these copies away from the call. This fixes Ptrdist/yacr2 --- Diffs of the changes: (+20 -10) PPC32ISelDAGToDAG.cpp | 30 ++++++++++++++++++++---------- 1 files changed, 20 insertions(+), 10 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.56 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.57 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.56 Mon Aug 29 19:59:16 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Mon Aug 29 20:57:02 2005 @@ -1512,6 +1512,8 @@ PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 }; + SDOperand InFlag; // Null incoming flag value. + for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { unsigned DestReg = 0; MVT::ValueType RegTy; @@ -1528,17 +1530,21 @@ } if (N->getOperand(i).getOpcode() != ISD::UNDEF) { - SDOperand Reg = CurDAG->getRegister(DestReg, RegTy); - Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, Reg, - Select(N->getOperand(i))); - CallOperands.push_back(Reg); + Chain = CurDAG->getCopyToReg(Chain, DestReg, + Select(N->getOperand(i)), InFlag); + InFlag = Chain.getValue(1); + CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); } } // Finally, once everything is in registers to pass to the call, emit the // call itself. - CallOperands.push_back(Chain); - Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, CallOperands); + if (InFlag.Val) + CallOperands.push_back(InFlag); // Strong dep on register copies. + else + CallOperands.push_back(Chain); // Weak dep on whatever occurs before + Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, + CallOperands); std::vector CallResults; @@ -1548,18 +1554,22 @@ case MVT::Other: break; case MVT::i32: if (N->getValueType(1) == MVT::i32) { - Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32).getValue(1); + Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, + Chain.getValue(1)).getValue(1); CallResults.push_back(Chain.getValue(0)); - Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32).getValue(1); + Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(1)).getValue(1); CallResults.push_back(Chain.getValue(0)); } else { - Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32).getValue(1); + Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(1)).getValue(1); CallResults.push_back(Chain.getValue(0)); } break; case MVT::f32: case MVT::f64: - Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, MVT::f64).getValue(1); + Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, MVT::f64, + Chain.getValue(1)).getValue(1); if (N->getValueType(0) == MVT::f64) CallResults.push_back(Chain.getValue(0)); else From lattner at cs.uiuc.edu Mon Aug 29 20:57:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 20:57:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200508300157.UAA07687@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.18 -> 1.19 --- Log message: Handle CopyToReg nodes with flag operands correctly --- Diffs of the changes: (+6 -1) ScheduleDAG.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.18 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.19 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.18 Mon Aug 29 18:21:29 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Aug 29 20:57:23 2005 @@ -205,8 +205,13 @@ Emit(Op.getOperand(i)); break; case ISD::CopyToReg: { - Emit(Op.getOperand(0)); // Emit the chain. + SDOperand ChainOp; + if (Op.getNumOperands() == 4) + ChainOp = Op.getOperand(3); + if (Op.getOperand(0).Val != ChainOp.Val) + Emit(Op.getOperand(0)); // Emit the chain. unsigned Val = Emit(Op.getOperand(2)); + if (ChainOp.Val) Emit(ChainOp); MRI.copyRegToReg(*BB, BB->end(), cast(Op.getOperand(1))->getReg(), Val, RegMap->getRegClass(Val)); From lattner at cs.uiuc.edu Mon Aug 29 20:59:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 29 Aug 2005 20:59:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200508300159.UAA07746@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.19 -> 1.20 --- Log message: Name this variable to be what it really is! --- Diffs of the changes: (+4 -4) ScheduleDAG.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.19 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.20 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.19 Mon Aug 29 20:57:23 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Aug 29 20:58:51 2005 @@ -205,13 +205,13 @@ Emit(Op.getOperand(i)); break; case ISD::CopyToReg: { - SDOperand ChainOp; + SDOperand FlagOp; if (Op.getNumOperands() == 4) - ChainOp = Op.getOperand(3); - if (Op.getOperand(0).Val != ChainOp.Val) + FlagOp = Op.getOperand(3); + if (Op.getOperand(0).Val != FlagOp.Val) Emit(Op.getOperand(0)); // Emit the chain. unsigned Val = Emit(Op.getOperand(2)); - if (ChainOp.Val) Emit(ChainOp); + if (FlagOp.Val) Emit(FlagOp); MRI.copyRegToReg(*BB, BB->end(), cast(Op.getOperand(1))->getReg(), Val, RegMap->getRegClass(Val)); From natebegeman at mac.com Mon Aug 29 21:39:43 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 29 Aug 2005 21:39:43 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200508300239.VAA08075@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.65 -> 1.66 --- Log message: Add AssertSext, AssertZext nodes for targets that pass arguments in registers, and the incoming values have already been zero or sign extended from the appopriate type to the register width. --- Diffs of the changes: (+7 -0) SelectionDAGNodes.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.65 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.66 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.65 Mon Aug 29 17:48:32 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Mon Aug 29 21:39:32 2005 @@ -52,6 +52,13 @@ // single token result. This is used to represent the fact that the operand // operators are independent of each other. TokenFactor, + + // AssertSext, AssertZext - These nodes record if a register contains a + // value that has already been zero or sign extended from a narrower type. + // These nodes take two operands. The first is the node that has already + // been extended, and the second is a value type node indicating the width + // of the extension + AssertSext, AssertZext, // Various leaf nodes. Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool, From natebegeman at mac.com Mon Aug 29 21:44:11 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 29 Aug 2005 21:44:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200508300244.VAA08152@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.177 -> 1.178 SelectionDAG.cpp updated: 1.174 -> 1.175 --- Log message: Add support for AssertSext and AssertZext, folding other extensions with them. This allows for elminination of redundant extends in the entry blocks of functions on PowerPC. Add support for i32 x i32 -> i64 multiplies, by recognizing when the inputs to ISD::MUL in ExpandOp are actually just extended i32 values and not real i64 values. this allows us to codegen int mulhs(int a, int b) { return ((long long)a * b) >> 32; } as: _mulhs: mulhw r3, r4, r3 blr instead of: _mulhs: mulhwu r2, r4, r3 srawi r5, r3, 31 mullw r5, r4, r5 add r2, r2, r5 srawi r4, r4, 31 mullw r3, r4, r3 add r3, r2, r3 blr with a similar improvement on x86. --- Diffs of the changes: (+43 -9) LegalizeDAG.cpp | 29 ++++++++++++++++++++++++----- SelectionDAG.cpp | 23 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.177 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.178 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.177 Mon Aug 29 15:46:51 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Aug 29 21:44:00 2005 @@ -456,6 +456,8 @@ assert(0 && "Do not know how to legalize this operator!"); abort(); case ISD::EntryToken: + case ISD::AssertSext: + case ISD::AssertZext: case ISD::FrameIndex: case ISD::GlobalAddress: case ISD::ExternalSymbol: @@ -3158,11 +3160,28 @@ SDOperand LL, LH, RL, RH; ExpandOp(Node->getOperand(0), LL, LH); ExpandOp(Node->getOperand(1), RL, RH); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + unsigned SH = MVT::getSizeInBits(RH.getValueType())-1; + // MULHS implicitly sign extends its inputs. Check to see if ExpandOp + // extended the sign bit of the low half through the upper half, and if so + // emit a MULHS instead of the alternate sequence that is valid for any + // i64 x i64 multiply. + if (TLI.isOperationLegal(ISD::MULHS, NVT) && + // is RH an extension of the sign bit of RL? + RH.getOpcode() == ISD::SRA && RH.getOperand(0) == RL && + RH.getOperand(1).getOpcode() == ISD::Constant && + cast(RH.getOperand(1))->getValue() == SH && + // is LH an extension of the sign bit of LL? + LH.getOpcode() == ISD::SRA && LH.getOperand(0) == LL && + LH.getOperand(1).getOpcode() == ISD::Constant && + cast(LH.getOperand(1))->getValue() == SH) { + Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); + } else { + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + } Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); } else { Lo = ExpandLibCall("__muldi3" , Node, Hi); break; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.174 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.175 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.174 Mon Aug 29 16:59:31 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Aug 29 21:44:00 2005 @@ -631,7 +631,8 @@ unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy); MVT::ValueType ExtDstTy = N1.getValueType(); unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy); - + + if (Cond == ISD::SETEQ || Cond == ISD::SETNE) { // If the extended part has any inconsistent bits, it cannot ever // compare equal. In other words, they have to be all ones or all // zeros. @@ -644,6 +645,7 @@ return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy), getConstant(C2 & (~0ULL >> 64-ExtSrcTyBits), ExtDstTy), Cond); + } } uint64_t MinVal, MaxVal; @@ -1192,6 +1194,8 @@ assert(EVT <= VT && "Not rounding down!"); break; } + case ISD::AssertSext: + case ISD::AssertZext: case ISD::SIGN_EXTEND_INREG: { MVT::ValueType EVT = cast(N2)->getVT(); assert(VT == N1.getValueType() && "Not an inreg extend!"); @@ -1394,6 +1398,14 @@ // we know the result of the AND will be the AND mask itself. return N2; } + } else if (N1.getOpcode() == ISD::AssertZext) { + // If we are masking out the part of our input that was already masked + // out, just return the input directly. + unsigned ExtendBits = + MVT::getSizeInBits(cast(N1.getOperand(1))->getVT()); + uint64_t ExtendMask = (1ULL << ExtendBits) - 1; + if (ExtendMask == C2) + return N1.getOperand(0); } break; case ISD::OR: @@ -1579,14 +1591,15 @@ if (EVT == VT) return N1; // Not actually extending // If we are sign extending an extension, use the original source. - if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) + if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG || + N1.getOpcode() == ISD::AssertSext) if (cast(N1.getOperand(1))->getVT() <= EVT) return N1; // If we are sign extending a sextload, return just the load. if (N1.getOpcode() == ISD::SEXTLOAD) if (cast(N1.getOperand(3))->getVT() <= EVT) - return N1; + return N1; // If we are extending the result of a setcc, and we already know the // contents of the top bits, eliminate the extension. @@ -1594,7 +1607,7 @@ TLI.getSetCCResultContents() == TargetLowering::ZeroOrNegativeOneSetCCResult) return N1; - + // If we are sign extending the result of an (and X, C) operation, and we // know the extended bits are zeros already, don't do the extend. if (N1.getOpcode() == ISD::AND) @@ -2195,6 +2208,8 @@ case ISD::VALUETYPE: return "ValueType"; case ISD::EntryToken: return "EntryToken"; case ISD::TokenFactor: return "TokenFactor"; + case ISD::AssertSext: return "AssertSext"; + case ISD::AssertZext: return "AssertZext"; case ISD::Constant: return "Constant"; case ISD::TargetConstant: return "TargetConstant"; case ISD::ConstantFP: return "ConstantFP"; From natebegeman at mac.com Mon Aug 29 21:54:40 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 29 Aug 2005 21:54:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508300254.VAA08200@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.175 -> 1.176 --- Log message: Remove a bogus piece of my AssertSext/AssertZext patch. oops. --- Diffs of the changes: (+0 -2) SelectionDAG.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.175 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.176 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.175 Mon Aug 29 21:44:00 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Aug 29 21:54:28 2005 @@ -632,7 +632,6 @@ MVT::ValueType ExtDstTy = N1.getValueType(); unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy); - if (Cond == ISD::SETEQ || Cond == ISD::SETNE) { // If the extended part has any inconsistent bits, it cannot ever // compare equal. In other words, they have to be all ones or all // zeros. @@ -645,7 +644,6 @@ return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy), getConstant(C2 & (~0ULL >> 64-ExtSrcTyBits), ExtDstTy), Cond); - } } uint64_t MinVal, MaxVal; From lattner at cs.uiuc.edu Tue Aug 30 11:56:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 11:56:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200508301656.LAA16231@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.178 -> 1.179 --- Log message: Fix a miscompile of PtrDist/bc. Sign extending bools is not the right thing, at least tends to expose problems elsewhere. --- Diffs of the changes: (+4 -1) LegalizeDAG.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.178 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.179 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.178 Mon Aug 29 21:44:00 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Aug 30 11:56:19 2005 @@ -2011,7 +2011,10 @@ Result = DAG.getNode(ISD::UNDEF, NVT); break; case ISD::Constant: - Result = DAG.getNode(ISD::SIGN_EXTEND, NVT, Op); + if (VT != MVT::i1) + Result = DAG.getNode(ISD::SIGN_EXTEND, NVT, Op); + else + Result = DAG.getNode(ISD::ZERO_EXTEND, NVT, Op); assert(isa(Result) && "Didn't constant fold zext?"); break; case ISD::ConstantFP: From lattner at cs.uiuc.edu Tue Aug 30 12:14:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 12:14:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508301714.MAA16506@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.57 -> 1.58 --- Log message: add operands in the right order, fixing McCat/18-imp with the dag isel --- Diffs of the changes: (+3 -3) PPC32ISelDAGToDAG.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.57 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.58 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.57 Mon Aug 29 20:57:02 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 12:13:58 2005 @@ -906,12 +906,12 @@ break; } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { SDOperand Op = - CurDAG->getTargetNode(PPC::SRAWI, MVT::Flag, MVT::i32, + CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag, Select(N->getOperand(0)), getI32Imm(Log2_32(-Imm))); SDOperand PT = - CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(1), - Op.getValue(0)); + CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(0), + Op.getValue(1)); CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); break; } else if (Imm) { From lattner at cs.uiuc.edu Tue Aug 30 12:21:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 12:21:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200508301721.MAA16621@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.179 -> 1.180 --- Log message: Fix FreeBench/fourinarow with the dag isel, by not adding a bogus result to SHIFT_PARTS nodes --- Diffs of the changes: (+1 -4) LegalizeDAG.cpp | 5 +---- 1 files changed, 1 insertion(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.179 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.180 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.179 Tue Aug 30 11:56:19 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Aug 30 12:21:17 2005 @@ -2388,10 +2388,7 @@ Ops.push_back(LHSL); Ops.push_back(LHSH); Ops.push_back(Amt); - std::vector VTs; - VTs.push_back(LHSL.getValueType()); - VTs.push_back(LHSH.getValueType()); - VTs.push_back(Amt.getValueType()); + std::vector VTs(2, LHSL.getValueType()); Lo = DAG.getNode(NodeOp, VTs, Ops); Hi = Lo.getValue(1); } From lattner at cs.uiuc.edu Tue Aug 30 12:40:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 12:40:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508301740.MAA16833@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.58 -> 1.59 --- Log message: codegen ADD_PARTS correctly: put the results in the right registers! This fixes fhourstones --- Diffs of the changes: (+1 -1) PPC32ISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.58 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.59 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.58 Tue Aug 30 12:13:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 12:40:13 2005 @@ -1208,8 +1208,8 @@ else ResultHi = CurDAG->getTargetNode(PPC::ADDE, MVT::i32, LHSH, Select(N->getOperand(3)), CarryFromLo); - Result.push_back(ResultHi); Result.push_back(CarryFromLo.getValue(0)); + Result.push_back(ResultHi); CurDAG->ReplaceAllUsesWith(N, Result); return Result[Op.ResNo]; } From lattner at cs.uiuc.edu Tue Aug 30 12:43:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 12:43:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508301743.MAA16895@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.59 -> 1.60 --- Log message: Fix a problem Nate found where we swapped the operands of SHL/SHR_PARTS. This fixes fourinarow --- Diffs of the changes: (+4 -4) PPC32ISelDAGToDAG.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.59 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.60 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.59 Tue Aug 30 12:40:13 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 12:42:59 2005 @@ -1228,8 +1228,8 @@ return Result[Op.ResNo]; } case ISD::SHL_PARTS: { - SDOperand HI = Select(N->getOperand(0)); - SDOperand LO = Select(N->getOperand(1)); + SDOperand LO = Select(N->getOperand(0)); + SDOperand HI = Select(N->getOperand(1)); SDOperand SH = Select(N->getOperand(2)); SDOperand SH_LO_R = CurDAG->getTargetNode(PPC::SUBFIC, MVT::i32, MVT::Flag, SH, getI32Imm(32)); @@ -1247,8 +1247,8 @@ return Result[Op.ResNo]; } case ISD::SRL_PARTS: { - SDOperand HI = Select(N->getOperand(0)); - SDOperand LO = Select(N->getOperand(1)); + SDOperand LO = Select(N->getOperand(0)); + SDOperand HI = Select(N->getOperand(1)); SDOperand SH = Select(N->getOperand(2)); SDOperand SH_HI_L = CurDAG->getTargetNode(PPC::SUBFIC, MVT::i32, MVT::Flag, SH, getI32Imm(32)); From lattner at cs.uiuc.edu Tue Aug 30 12:49:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 12:49:30 -0500 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Misc/richards_benchmark.c Message-ID: <200508301749.MAA16941@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/Misc: richards_benchmark.c updated: 1.2 -> 1.3 --- Log message: Rename the wait function to Wait to prevent it from conflicting with the unix wait function, allowing it to build on darwin --- Diffs of the changes: (+4 -4) richards_benchmark.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm-test/SingleSource/Benchmarks/Misc/richards_benchmark.c diff -u llvm-test/SingleSource/Benchmarks/Misc/richards_benchmark.c:1.2 llvm-test/SingleSource/Benchmarks/Misc/richards_benchmark.c:1.3 --- llvm-test/SingleSource/Benchmarks/Misc/richards_benchmark.c:1.2 Sun Feb 29 21:39:02 2004 +++ llvm-test/SingleSource/Benchmarks/Misc/richards_benchmark.c Tue Aug 30 12:49:18 2005 @@ -182,7 +182,7 @@ } } -struct task *wait(void) +struct task *Wait(void) { tcb->t_state |= WAITBIT; return (tcb); @@ -264,7 +264,7 @@ struct task *workfn(struct packet *pkt) { - if ( pkt==0 ) return ( wait() ); + if ( pkt==0 ) return ( Wait() ); else { int i; @@ -311,14 +311,14 @@ return( qpkt(devpkt) ); } } - return ( wait() ); + return ( Wait() ); } struct task *devfn(struct packet *pkt) { if ( pkt==0 ) { - if ( v1==0 ) return ( wait() ); + if ( v1==0 ) return ( Wait() ); pkt = (struct packet *)v1; v1 = 0; return ( qpkt(pkt) ); From lattner at cs.uiuc.edu Tue Aug 30 13:37:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 13:37:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508301837.NAA17371@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.60 -> 1.61 --- Log message: Fix some indentation (first hunks). Remove code (last hunk) that miscompiled immediate and's, such as and uint %tmp.30, 4294958079 into andi. r8, r8, 56319 andis. r8, r8, 65535 instead of: li r9, -9217 and r8, r8, r9 The first always generates zero. This fixes espresso. --- Diffs of the changes: (+20 -30) PPC32ISelDAGToDAG.cpp | 50 ++++++++++++++++++++------------------------------ 1 files changed, 20 insertions(+), 30 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.60 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.61 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.60 Tue Aug 30 12:42:59 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 13:37:48 2005 @@ -257,34 +257,33 @@ // Generate Mask value for Target if (isIntImmediate(Op0.getOperand(1), Value)) { switch(Op0Opc) { - case ISD::SHL: TgtMask <<= Value; break; - case ISD::SRL: TgtMask >>= Value; break; - case ISD::AND: TgtMask &= Value; break; + case ISD::SHL: TgtMask <<= Value; break; + case ISD::SRL: TgtMask >>= Value; break; + case ISD::AND: TgtMask &= Value; break; } } else { return 0; } // Generate Mask value for Insert - if (isIntImmediate(Op1.getOperand(1), Value)) { - switch(Op1Opc) { - case ISD::SHL: - SH = Value; - InsMask <<= SH; - if (Op0Opc == ISD::SRL) IsRotate = true; - break; - case ISD::SRL: - SH = Value; - InsMask >>= SH; - SH = 32-SH; - if (Op0Opc == ISD::SHL) IsRotate = true; - break; - case ISD::AND: - InsMask &= Value; - break; - } - } else { + if (!isIntImmediate(Op1.getOperand(1), Value)) return 0; + + switch(Op1Opc) { + case ISD::SHL: + SH = Value; + InsMask <<= SH; + if (Op0Opc == ISD::SRL) IsRotate = true; + break; + case ISD::SRL: + SH = Value; + InsMask >>= SH; + SH = 32-SH; + if (Op0Opc == ISD::SHL) IsRotate = true; + break; + case ISD::AND: + InsMask &= Value; + break; } // If both of the inputs are ANDs and one of them has a logical shift by @@ -979,15 +978,6 @@ getI32Imm(MB), getI32Imm(ME)); break; } - // If this is an and with an immediate that isn't a mask, then codegen it as - // high and low 16 bit immediate ands. - if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), - N->getOperand(1), - PPC::ANDISo, PPC::ANDIo)) { - CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); - N = I; - break; - } // Finally, check for the case where we are being asked to select // and (not(a), b) or and (a, not(b)) which can be selected as andc. if (isOprNot(N->getOperand(0).Val)) From lattner at cs.uiuc.edu Tue Aug 30 13:44:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 13:44:21 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/and-imm.ll Message-ID: <200508301844.NAA17444@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: and-imm.ll added (r1.1) --- Log message: The dag isel misses both of these, the pattern isel just misses the second one. TODO :) --- Diffs of the changes: (+13 -0) and-imm.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/and-imm.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/and-imm.ll:1.1 *** /dev/null Tue Aug 30 13:44:19 2005 --- llvm/test/Regression/CodeGen/PowerPC/and-imm.ll Tue Aug 30 13:44:09 2005 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep 'ori\|lis' + ; XFAIL: * + + int %test(int %X) { + %Y = and int %X, 32769 ; andi. r3, r3, 32769 + ret int %Y + } + + int %test2(int %X) { + %Y = and int %X, -2147418112 ; andis. r3, r3, 32769 + ret int %Y + } + From lattner at cs.uiuc.edu Tue Aug 30 16:03:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 16:03:03 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2005-08-30-RegAllocAliasProblem.ll Message-ID: <200508302103.QAA18672@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2005-08-30-RegAllocAliasProblem.ll added (r1.1) --- Log message: new testcase corresponding to PR621: http://llvm.cs.uiuc.edu/PR621 --- Diffs of the changes: (+17 -0) 2005-08-30-RegAllocAliasProblem.ll | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2005-08-30-RegAllocAliasProblem.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2005-08-30-RegAllocAliasProblem.ll:1.1 *** /dev/null Tue Aug 30 16:03:01 2005 --- llvm/test/Regression/CodeGen/X86/2005-08-30-RegAllocAliasProblem.ll Tue Aug 30 16:02:51 2005 *************** *** 0 **** --- 1,17 ---- + ; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel | not grep 'test.*%AL' || \ + ; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel | not grep 'cmove.*%EAX' + + ; This testcase was compiling to: + ; + ; _pypy_simple5: + ; movl $13, %ecx + ; movl $12, %eax + ; movb 4(%esp), %al + ; testb %al, %al ;; clobber EAX! + ; cmove %ecx, %eax + ; ret + + int %pypy_simple5(bool %b_4787) { + %retval = select bool %b_4787, int 12, int 13 ; [#uses=1] + ret int %retval + } From lattner at cs.uiuc.edu Tue Aug 30 16:03:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 16:03:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200508302103.QAA18767@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.112 -> 1.113 --- Log message: When checking the fixed intervals, don't forget to check for register aliases. This fixes PR621: http://llvm.cs.uiuc.edu/PR621 and Regression/CodeGen/X86/2005-08-30-RegAllocAliasProblem.ll --- Diffs of the changes: (+11 -5) RegAllocLinearScan.cpp | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.112 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.113 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.112 Tue Aug 23 17:27:31 2005 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Tue Aug 30 16:03:36 2005 @@ -444,10 +444,16 @@ unsigned physReg = getFreePhysReg(cur); if (physReg) { // We got a register. However, if it's in the fixed_ list, we might - // conflict with it. Check to see if we conflict with it. + // conflict with it. Check to see if we conflict with it or any of its + // aliases. + std::set RegAliases; + for (const unsigned *AS = mri_->getAliasSet(physReg); *AS; ++AS) + RegAliases.insert(*AS); + bool ConflictsWithFixed = false; for (unsigned i = 0, e = fixed_.size(); i != e; ++i) { - if (physReg == fixed_[i].first->reg) { + if (physReg == fixed_[i].first->reg || + RegAliases.count(fixed_[i].first->reg)) { // Okay, this reg is on the fixed list. Check to see if we actually // conflict. IntervalPtr &IP = fixed_[i]; @@ -457,11 +463,11 @@ IP.second = II; if (II != I->begin() && II->start > StartPosition) --II; - if (cur->overlapsFrom(*I, II)) + if (cur->overlapsFrom(*I, II)) { ConflictsWithFixed = true; + break; + } } - - break; } } From lattner at cs.uiuc.edu Tue Aug 30 16:28:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 16:28:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508302128.QAA18990@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.61 -> 1.62 --- Log message: Fix type mismatches when passing f32 values to calls --- Diffs of the changes: (+7 -2) PPC32ISelDAGToDAG.cpp | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.61 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.62 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.61 Tue Aug 30 13:37:48 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 16:28:19 2005 @@ -1520,8 +1520,13 @@ } if (N->getOperand(i).getOpcode() != ISD::UNDEF) { - Chain = CurDAG->getCopyToReg(Chain, DestReg, - Select(N->getOperand(i)), InFlag); + SDOperand Val = Select(N->getOperand(i)); + if (Val.getValueType() != RegTy) { + // Use a register-register copy to handle f32 values in f64 registers. + assert(Val.getValueType() == MVT::f32 && RegTy == MVT::f64); + Val = CurDAG->getTargetNode(PPC::FMR, MVT::f64, Val); + } + Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); InFlag = Chain.getValue(1); CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); } From lattner at cs.uiuc.edu Tue Aug 30 17:38:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 17:38:16 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200508302238.RAA19374@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.57 -> 1.58 --- Log message: Allow physregs to occur in the dag with multiple types. Though I don't like this, it is a requirement on PPC, which can have an f32 value in r3 at one point in a function and a f64 value in r3 at another point. :( --- Diffs of the changes: (+1 -1) SelectionDAG.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.57 llvm/include/llvm/CodeGen/SelectionDAG.h:1.58 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.57 Mon Aug 29 20:56:13 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Tue Aug 30 17:38:05 2005 @@ -355,7 +355,7 @@ std::map >, SDNode *> BinaryOps; - std::vector RegNodes; + std::map, RegisterSDNode*> RegNodes; std::vector CondCodeNodes; std::map >, From lattner at cs.uiuc.edu Tue Aug 30 17:38:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 17:38:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508302238.RAA19431@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.176 -> 1.177 --- Log message: Allow physregs to occur in the dag with multiple types. Though I don't likethis, it is a requirement on PPC, which can have an f32 value in r3 at onepoint in a function and a f64 value in r3 at another point. :( This fixes compilation of mesa --- Diffs of the changes: (+8 -12) SelectionDAG.cpp | 20 ++++++++------------ 1 files changed, 8 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.176 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.177 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.176 Mon Aug 29 21:54:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Aug 30 17:38:38 2005 @@ -307,7 +307,8 @@ ValueTypeNodes[cast(N)->getVT()] = 0; break; case ISD::Register: - RegNodes[cast(N)->getReg()] = 0; + RegNodes.erase(std::make_pair(cast(N)->getReg(), + N->getValueType(0))); break; case ISD::SRCVALUE: { SrcValueSDNode *SVN = cast(N); @@ -533,18 +534,13 @@ return SDOperand(CondCodeNodes[Cond], 0); } -SDOperand SelectionDAG::getRegister(unsigned Reg, MVT::ValueType VT) { - if (Reg >= RegNodes.size()) - RegNodes.resize(Reg+1); - RegisterSDNode *&Result = RegNodes[Reg]; - if (Result) { - assert(Result->getValueType(0) == VT && - "Inconsistent value types for machine registers"); - } else { - Result = new RegisterSDNode(Reg, VT); - AllNodes.push_back(Result); +SDOperand SelectionDAG::getRegister(unsigned RegNo, MVT::ValueType VT) { + RegisterSDNode *&Reg = RegNodes[std::make_pair(RegNo, VT)]; + if (!Reg) { + Reg = new RegisterSDNode(RegNo, VT); + AllNodes.push_back(Reg); } - return SDOperand(Result, 0); + return SDOperand(Reg, 0); } SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, From lattner at cs.uiuc.edu Tue Aug 30 18:00:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 18:00:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508302300.SAA19546@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.62 -> 1.63 --- Log message: now that physregs can exist in the same dag with multiple types, remove some ugly hacks --- Diffs of the changes: (+8 -27) PPC32ISelDAGToDAG.cpp | 35 ++++++++--------------------------- 1 files changed, 8 insertions(+), 27 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.62 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.63 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.62 Tue Aug 30 16:28:19 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 17:59:48 2005 @@ -1506,26 +1506,19 @@ for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { unsigned DestReg = 0; - MVT::ValueType RegTy; - if (N->getOperand(i).getValueType() == MVT::i32) { + MVT::ValueType RegTy = N->getOperand(i).getValueType(); + if (RegTy == MVT::i32) { assert(GPR_idx < 8 && "Too many int args"); DestReg = GPR[GPR_idx++]; - RegTy = MVT::i32; } else { assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && "Unpromoted integer arg?"); assert(FPR_idx < 13 && "Too many fp args"); DestReg = FPR[FPR_idx++]; - RegTy = MVT::f64; // Even if this is really f32! } if (N->getOperand(i).getOpcode() != ISD::UNDEF) { SDOperand Val = Select(N->getOperand(i)); - if (Val.getValueType() != RegTy) { - // Use a register-register copy to handle f32 values in f64 registers. - assert(Val.getValueType() == MVT::f32 && RegTy == MVT::f64); - Val = CurDAG->getTargetNode(PPC::FMR, MVT::f64, Val); - } Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); InFlag = Chain.getValue(1); CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); @@ -1563,14 +1556,9 @@ break; case MVT::f32: case MVT::f64: - Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, MVT::f64, + Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), Chain.getValue(1)).getValue(1); - if (N->getValueType(0) == MVT::f64) - CallResults.push_back(Chain.getValue(0)); - else - // Insert an FMR to convert the result to f32 from f64. - CallResults.push_back(CurDAG->getTargetNode(PPC::FMR, MVT::f32, - Chain.getValue(0))); + CallResults.push_back(Chain.getValue(0)); break; } @@ -1583,18 +1571,11 @@ if (N->getNumOperands() > 1) { SDOperand Val = Select(N->getOperand(1)); - switch (N->getOperand(1).getValueType()) { - default: assert(0 && "Unknown return type!"); - case MVT::f32: - // Insert a copy to get the type right. - Val = CurDAG->getTargetNode(PPC::FMR, MVT::f64, Val); - // FALL THROUGH - case MVT::f64: - Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); - break; - case MVT::i32: + if (N->getOperand(1).getValueType() == MVT::i32) { Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val); - break; + } else { + assert(MVT::isFloatingPoint(N->getOperand(1).getValueType())); + Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); } if (N->getNumOperands() > 2) { From natebegeman at mac.com Tue Aug 30 19:25:13 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 30 Aug 2005 19:25:13 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/MathExtras.h Message-ID: <200508310025.TAA19903@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: MathExtras.h updated: 1.25 -> 1.26 --- Log message: Add support for count trailing zeroes, and population count. These are needed for folding constants in the upcoming dag combiner. --- Diffs of the changes: (+37 -5) MathExtras.h | 42 +++++++++++++++++++++++++++++++++++++----- 1 files changed, 37 insertions(+), 5 deletions(-) Index: llvm/include/llvm/Support/MathExtras.h diff -u llvm/include/llvm/Support/MathExtras.h:1.25 llvm/include/llvm/Support/MathExtras.h:1.26 --- llvm/include/llvm/Support/MathExtras.h:1.25 Wed Aug 17 18:54:12 2005 +++ llvm/include/llvm/Support/MathExtras.h Tue Aug 30 19:25:01 2005 @@ -83,10 +83,6 @@ // counting the number of zeros from the most significant bit to the first one // bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. // Returns 32 if the word is zero. -// CountLeadingZeros_32 - this function performs the platform optimal form -// of counting the number of zeros from the most significant bit to the first -// one bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. -// Returns 32 if the word is zero. inline unsigned CountLeadingZeros_32(unsigned Value) { unsigned Count; // result #if __GNUC__ >= 4 @@ -155,12 +151,48 @@ return Count; } +// CountTrailingZeros_32 - this function performs the platform optimal form of +// counting the number of zeros from the least significant bit to the first one +// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8. +// Returns 32 if the word is zero. +inline unsigned CountTrailingZeros_32(unsigned Value) { + return 32 - CountLeadingZeros_32(~Value & (Value - 1)); +} + +// CountTrailingZeros_64 - This function performs the platform optimal form +// of counting the number of zeros from the least significant bit to the first +// one bit (64 bit edition.) +// Returns 64 if the word is zero. +inline unsigned CountTrailingZeros_64(uint64_t Value) { + return 64 - CountLeadingZeros_64(~Value & (Value - 1)); +} + +// CountPopulation_32 - this function counts the number of set bits in a value. +// Ex. CountPopulation(0xF000F000) = 8 +// Returns 0 if the word is zero. +inline unsigned CountPopulation_32(unsigned Value) { + unsigned x, t; + x = Value - ((Value >> 1) & 0x55555555); + t = ((x >> 2) & 0x33333333); + x = (x & 0x33333333) + t; + x = (x + (x >> 4)) & 0x0F0F0F0F; + x = x + (x << 8); + x = x + (x << 16); + return x >> 24; +} + +// CountPopulation_64 - this function counts the number of set bits in a value, +// (64 bit edition.) +inline unsigned CountPopulation_64(uint64_t Value) { + return CountPopulation_32(Value >> 32) + CountPopulation_32(Value); +} + // Log2_32 - This function returns the floor log base 2 of the specified value, // -1 if the value is zero. (32 bit edition.) // Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1 inline unsigned Log2_32(unsigned Value) { return 31 - CountLeadingZeros_32(Value); - } +} // Log2_64 - This function returns the floor log base 2 of the specified value, // -1 if the value is zero. (64 bit edition.) From natebegeman at mac.com Tue Aug 30 19:28:05 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 30 Aug 2005 19:28:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508310028.TAA19915@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.177 -> 1.178 --- Log message: Remove some unnecessary casts, and add the AssertZext case to MaskedValueIsZero. --- Diffs of the changes: (+3 -2) SelectionDAG.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.177 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.178 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.177 Tue Aug 30 17:38:38 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Aug 30 19:27:53 2005 @@ -1095,6 +1095,7 @@ SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. case ISD::ZERO_EXTEND: + case ISD::AssertZext: SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); @@ -1228,8 +1229,8 @@ case ISD::AND : return getConstant(C1 & C2, VT); case ISD::OR : return getConstant(C1 | C2, VT); case ISD::XOR : return getConstant(C1 ^ C2, VT); - case ISD::SHL : return getConstant(C1 << (int)C2, VT); - case ISD::SRL : return getConstant(C1 >> (unsigned)C2, VT); + case ISD::SHL : return getConstant(C1 << C2, VT); + case ISD::SRL : return getConstant(C1 >> C2, VT); case ISD::SRA : return getConstant(N1C->getSignExtended() >>(int)C2, VT); default: break; } From natebegeman at mac.com Tue Aug 30 19:43:20 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 30 Aug 2005 19:43:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508310043.TAA20005@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.178 -> 1.179 --- Log message: Fix a mistake in my previous patch pointed out by sabre; the AssertZext case in MaskedValueIsZero was wrong. --- Diffs of the changes: (+3 -2) SelectionDAG.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.178 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.179 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.178 Tue Aug 30 19:27:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Aug 30 19:43:08 2005 @@ -1095,10 +1095,11 @@ SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. case ISD::ZERO_EXTEND: - case ISD::AssertZext: SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); - + case ISD::AssertZext: + SrcBits = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); + return (Mask & ((1ULL << SrcBits)-1) == 0; // Returning only the zext bits. case ISD::AND: // (X & C1) & C2 == 0 iff C1 & C2 == 0. if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) From natebegeman at mac.com Tue Aug 30 19:44:01 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 30 Aug 2005 19:44:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508310044.TAA20017@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.179 -> 1.180 --- Log message: Sigh, not my day. Fix typo. --- Diffs of the changes: (+1 -1) SelectionDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.179 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.180 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.179 Tue Aug 30 19:43:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Aug 30 19:43:49 2005 @@ -1099,7 +1099,7 @@ return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); case ISD::AssertZext: SrcBits = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); - return (Mask & ((1ULL << SrcBits)-1) == 0; // Returning only the zext bits. + return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. case ISD::AND: // (X & C1) & C2 == 0 iff C1 & C2 == 0. if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) From lattner at cs.uiuc.edu Tue Aug 30 20:34:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 30 Aug 2005 20:34:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508310134.UAA20346@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.63 -> 1.64 --- Log message: Fix 'ret long' to return the high and lo parts in the right registers. This fixes crafty and probably others. --- Diffs of the changes: (+7 -9) PPC32ISelDAGToDAG.cpp | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.63 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.64 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.63 Tue Aug 30 17:59:48 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Tue Aug 30 20:34:29 2005 @@ -1569,7 +1569,7 @@ case ISD::RET: { SDOperand Chain = Select(N->getOperand(0)); // Token chain. - if (N->getNumOperands() > 1) { + if (N->getNumOperands() == 2) { SDOperand Val = Select(N->getOperand(1)); if (N->getOperand(1).getValueType() == MVT::i32) { Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val); @@ -1577,14 +1577,12 @@ assert(MVT::isFloatingPoint(N->getOperand(1).getValueType())); Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); } - - if (N->getNumOperands() > 2) { - assert(N->getOperand(1).getValueType() == MVT::i32 && - N->getOperand(2).getValueType() == MVT::i32 && - N->getNumOperands() == 3 && "Unknown two-register ret value!"); - Val = Select(N->getOperand(2)); - Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val); - } + } else if (N->getNumOperands() > 1) { + assert(N->getOperand(1).getValueType() == MVT::i32 && + N->getOperand(2).getValueType() == MVT::i32 && + N->getNumOperands() == 3 && "Unknown two-register ret value!"); + Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Select(N->getOperand(1))); + Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Select(N->getOperand(2))); } // Finally, select this to a blr (return) instruction. From natebegeman at mac.com Tue Aug 30 20:58:50 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 30 Aug 2005 20:58:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200508310158.UAA20412@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.13 -> 1.14 --- Log message: Enable generation of AssertSext and AssertZext in the PPC backend. --- Diffs of the changes: (+7 -2) PPC32ISelLowering.cpp | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.13 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.14 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.13 Mon Aug 29 19:45:18 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Tue Aug 30 20:58:39 2005 @@ -214,8 +214,13 @@ MF.addLiveIn(GPR[GPR_idx]); argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32); - if (ObjectVT != MVT::i32) - argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); + if (ObjectVT != MVT::i32) { + unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext + : ISD::AssertZext; + argt = DAG.getNode(AssertOp, MVT::i32, argt, + DAG.getValueType(ObjectVT)); + argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, argt); + } } else { needsLoad = true; } From jeffc at jolt-lang.org Tue Aug 30 21:47:17 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Tue, 30 Aug 2005 21:47:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200508310247.VAA20646@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.180 -> 1.181 --- Log message: Fix VC++ precedence warnings --- 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.180 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.181 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.180 Tue Aug 30 19:43:49 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Aug 30 21:47:06 2005 @@ -632,13 +632,13 @@ // compare equal. In other words, they have to be all ones or all // zeros. uint64_t ExtBits = - (~0ULL >> 64-ExtSrcTyBits) & (~0ULL << (ExtDstTyBits-1)); + (~0ULL >> (64-ExtSrcTyBits)) & (~0ULL << (ExtDstTyBits-1)); if ((C2 & ExtBits) != 0 && (C2 & ExtBits) != ExtBits) return getConstant(Cond == ISD::SETNE, VT); // Otherwise, make this a use of a zext. return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy), - getConstant(C2 & (~0ULL >> 64-ExtSrcTyBits), ExtDstTy), + getConstant(C2 & (~0ULL>>(64-ExtSrcTyBits)), ExtDstTy), Cond); } From lattner at cs.uiuc.edu Wed Aug 31 12:48:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 12:48:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200508311748.MAA24801@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.172 -> 1.173 --- Log message: Handle AssertSext/AssertZext nodes, fixing the regressions last night. --- Diffs of the changes: (+4 -0) PPC32ISelPattern.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.172 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.173 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.172 Fri Aug 26 15:25:03 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Aug 31 12:48:04 2005 @@ -781,6 +781,10 @@ Reg = Result = (N.getValueType() != MVT::Other) ? MakeReg(N.getValueType()) : 1; break; + case ISD::AssertSext: + case ISD::AssertZext: + // Don't allocate a vreg for these nodes. + return Reg = SelectExpr(N.getOperand(0)); case ISD::TAILCALL: case ISD::CALL: // If this is a call instruction, make sure to prepare ALL of the result From lattner at cs.uiuc.edu Wed Aug 31 13:08:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 13:08:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200508311808.NAA25697@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.64 -> 1.65 --- Log message: add assert zext/sext to the dag isel --- Diffs of the changes: (+3 -0) PPC32ISelDAGToDAG.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.64 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.65 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.64 Tue Aug 30 20:34:29 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Aug 31 13:08:46 2005 @@ -642,6 +642,9 @@ abort(); case ISD::EntryToken: // These leaves remain the same. return Op; + case ISD::AssertSext: + case ISD::AssertZext: + return Select(N->getOperand(0)); case ISD::TokenFactor: { SDOperand New; if (N->getNumOperands() == 2) { From lattner at cs.uiuc.edu Wed Aug 31 13:20:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 13:20:03 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Message-ID: <200508311820.NAA25878@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: small-arguments.ll added (r1.1) --- Log message: Add a testcase for nate's patch --- Diffs of the changes: (+12 -0) small-arguments.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.1 *** /dev/null Wed Aug 31 13:20:00 2005 --- llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Wed Aug 31 13:19:50 2005 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep 'extsh\|rlwinm r3, r3' + + int %test1(short %X) { + %Y = cast short %X to int ;; dead + ret int %Y + } + + int %test2(ushort %X) { + %Y = cast ushort %X to int + %Z = and int %Y, 65535 ;; dead + ret int %Z + } From lattner at cs.uiuc.edu Wed Aug 31 14:02:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 14:02:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200508311902.OAA26086@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.180 -> 1.181 --- Log message: Allow targets to custom expand shifts that are too large for their registers --- Diffs of the changes: (+39 -0) LegalizeDAG.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.180 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.181 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.180 Tue Aug 30 12:21:17 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Aug 31 14:01:53 2005 @@ -3101,6 +3101,19 @@ break; case ISD::SHL: + // If the target wants custom lowering, do so. + if (TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Custom) { + SDOperand Op = DAG.getNode(ISD::SHL, VT, Node->getOperand(0), + LegalizeOp(Node->getOperand(1))); + Op = TLI.LowerOperation(Op, DAG); + if (Op.Val) { + // Now that the custom expander is done, expand the result, which is + // still VT. + ExpandOp(Op, Lo, Hi); + break; + } + } + // If we can emit an efficient shift operation, do so now. if (ExpandShift(ISD::SHL, Node->getOperand(0), Node->getOperand(1), Lo, Hi)) break; @@ -3117,6 +3130,19 @@ break; case ISD::SRA: + // If the target wants custom lowering, do so. + if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Custom) { + SDOperand Op = DAG.getNode(ISD::SRA, VT, Node->getOperand(0), + LegalizeOp(Node->getOperand(1))); + Op = TLI.LowerOperation(Op, DAG); + if (Op.Val) { + // Now that the custom expander is done, expand the result, which is + // still VT. + ExpandOp(Op, Lo, Hi); + break; + } + } + // If we can emit an efficient shift operation, do so now. if (ExpandShift(ISD::SRA, Node->getOperand(0), Node->getOperand(1), Lo, Hi)) break; @@ -3132,6 +3158,19 @@ Lo = ExpandLibCall("__ashrdi3", Node, Hi); break; case ISD::SRL: + // If the target wants custom lowering, do so. + if (TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Custom) { + SDOperand Op = DAG.getNode(ISD::SRL, VT, Node->getOperand(0), + LegalizeOp(Node->getOperand(1))); + Op = TLI.LowerOperation(Op, DAG); + if (Op.Val) { + // Now that the custom expander is done, expand the result, which is + // still VT. + ExpandOp(Op, Lo, Hi); + break; + } + } + // If we can emit an efficient shift operation, do so now. if (ExpandShift(ISD::SRL, Node->getOperand(0), Node->getOperand(1), Lo, Hi)) break; From lattner at cs.uiuc.edu Wed Aug 31 14:07:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 14:07:50 -0500 Subject: [llvm-commits] CVS: llvm-test/SingleSource/UnitTests/2005-07-15-Bitfield-ABI.c Message-ID: <200508311907.OAA26200@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/UnitTests: 2005-07-15-Bitfield-ABI.c added (r1.1) --- Log message: check in a testcase for PR594: http://llvm.cs.uiuc.edu/PR594 that I forgot to commit earlier --- Diffs of the changes: (+21 -0) 2005-07-15-Bitfield-ABI.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm-test/SingleSource/UnitTests/2005-07-15-Bitfield-ABI.c diff -c /dev/null llvm-test/SingleSource/UnitTests/2005-07-15-Bitfield-ABI.c:1.1 *** /dev/null Wed Aug 31 14:07:48 2005 --- llvm-test/SingleSource/UnitTests/2005-07-15-Bitfield-ABI.c Wed Aug 31 14:07:38 2005 *************** *** 0 **** --- 1,21 ---- + // PR594 + + struct X { + int Q :6; + int A : 4; + int Z : 22; + }; + + void test(struct X *P, int A) { + P->A = A; + } + + int main() { + union { + int Y; + struct X Z; + } U; + U.Y = ~0; + test(&U.Z, 0); + printf("%x\n", U.Y); + } From lattner at cs.uiuc.edu Wed Aug 31 14:08:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 14:08:11 -0500 Subject: [llvm-commits] CVS: llvm-test/SingleSource/UnitTests/2003-05-31-LongShifts.c Message-ID: <200508311908.OAA26233@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/UnitTests: 2003-05-31-LongShifts.c updated: 1.1 -> 1.2 --- Log message: Make this test not get constant folded away. --- Diffs of the changes: (+16 -9) 2003-05-31-LongShifts.c | 25 ++++++++++++++++--------- 1 files changed, 16 insertions(+), 9 deletions(-) Index: llvm-test/SingleSource/UnitTests/2003-05-31-LongShifts.c diff -u llvm-test/SingleSource/UnitTests/2003-05-31-LongShifts.c:1.1 llvm-test/SingleSource/UnitTests/2003-05-31-LongShifts.c:1.2 --- llvm-test/SingleSource/UnitTests/2003-05-31-LongShifts.c:1.1 Sat May 31 20:57:25 2003 +++ llvm-test/SingleSource/UnitTests/2003-05-31-LongShifts.c Wed Aug 31 14:07:59 2005 @@ -5,14 +5,21 @@ (unsigned long long)Val >> Amt, Val << Amt); } -int main() { - Test(123, 4); - Test(123, 34); - Test(-4, 4); - Test(-5, 34); - Test(-6000000000LL, 4); - Test(-6000000000LL, 34); - Test( 6000000000LL, 4); - Test( 6000000000LL, 34); +volatile struct { + long long A; int V; +} Vals[] = { + { 123, 4}, + { 123, 34}, + {-4, 4}, + {-5, 34}, + { -6000000000LL, 4}, + { -6000000000LL, 34}, + { 6000000000LL, 4}, + { 6000000000LL, 34} +}; + +int main(int argc, char**argv) { + for (argc--; argc < sizeof(Vals)/sizeof(Vals[0]); ++argc) + Test(Vals[argc].A, Vals[argc].V); return 0; } From lattner at cs.uiuc.edu Wed Aug 31 14:10:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 14:10:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200508311910.OAA26296@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.14 -> 1.15 --- Log message: lower sra_parts on the dag, implementing it for the dag isel, and exposing the ops to dag optimization. --- Diffs of the changes: (+28 -0) PPC32ISelLowering.cpp | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.14 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.15 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.14 Tue Aug 30 20:58:39 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Wed Aug 31 14:09:57 2005 @@ -71,6 +71,9 @@ // PowerPC wants to turn select_cc of FP into fsel when possible. setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); + + // PowerPC wants to expand SRA_PARTS into SELECT_CC and stuff. + setOperationAction(ISD::SRA, MVT::i64, Custom); // PowerPC does not have BRCOND* which requires SetCC setOperationAction(ISD::BRCOND, MVT::Other, Expand); @@ -161,6 +164,31 @@ } } break; + case ISD::SRA: + assert(Op.getValueType() == MVT::i64 && + Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!"); + // The generic code does a fine job expanding shift by a constant. + if (isa(Op.getOperand(1))) break; + + // Otherwise, expand into a bunch of logical ops, followed by a select_cc. + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), + DAG.getConstant(0, MVT::i32)); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), + DAG.getConstant(1, MVT::i32)); + SDOperand Amt = Op.getOperand(1); + + SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, + DAG.getConstant(32, MVT::i32), Amt); + SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); + SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); + SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); + SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, + DAG.getConstant(-32U, MVT::i32)); + SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5); + SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt); + SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32), + Tmp4, Tmp6, ISD::SETLE); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } return SDOperand(); } From lattner at cs.uiuc.edu Wed Aug 31 14:11:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 14:11:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200508311911.OAA26353@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.173 -> 1.174 --- Log message: Remove code that is now dead from the pattern isel. --- Diffs of the changes: (+2 -28) PPC32ISelPattern.cpp | 30 ++---------------------------- 1 files changed, 2 insertions(+), 28 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.173 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.174 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.173 Wed Aug 31 12:48:04 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Aug 31 14:11:36 2005 @@ -803,7 +803,6 @@ case ISD::SUB_PARTS: case ISD::SHL_PARTS: case ISD::SRL_PARTS: - case ISD::SRA_PARTS: Result = MakeReg(Node->getValueType(0)); ExprMap[N.getValue(0)] = Result; for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i) @@ -1440,7 +1439,6 @@ } case ISD::SHL_PARTS: - case ISD::SRA_PARTS: case ISD::SRL_PARTS: { assert(N.getNumOperands() == 3 && N.getValueType() == MVT::i32 && "Not an i64 shift!"); @@ -1462,7 +1460,8 @@ BuildMI(BB, PPC::SLW, 2, Tmp6).addReg(ShiftOpLo).addReg(Tmp5); BuildMI(BB, PPC::OR, 2, Result+1).addReg(Tmp4).addReg(Tmp6); BuildMI(BB, PPC::SLW, 2, Result).addReg(ShiftOpLo).addReg(SHReg); - } else if (ISD::SRL_PARTS == opcode) { + } else { + assert (opcode == ISD::SRL_PARTS); BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg); BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1); BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3); @@ -1470,31 +1469,6 @@ BuildMI(BB, PPC::SRW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5); BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp4).addReg(Tmp6); BuildMI(BB, PPC::SRW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg); - } else { - MachineBasicBlock *TmpMBB = new MachineBasicBlock(BB->getBasicBlock()); - MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock()); - MachineBasicBlock *OldMBB = BB; - MachineFunction *F = BB->getParent(); - ilist::iterator It = BB; ++It; - F->getBasicBlockList().insert(It, TmpMBB); - F->getBasicBlockList().insert(It, PhiMBB); - BB->addSuccessor(TmpMBB); - BB->addSuccessor(PhiMBB); - BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg); - BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1); - BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3); - BuildMI(BB, PPC::ADDICo, 2, Tmp5).addReg(SHReg).addSImm(-32); - BuildMI(BB, PPC::SRAW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5); - BuildMI(BB, PPC::SRAW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg); - BuildMI(BB, PPC::BLE, 2).addReg(PPC::CR0).addMBB(PhiMBB); - // Select correct least significant half if the shift amount > 32 - BB = TmpMBB; - unsigned Tmp7 = MakeIntReg(); - BuildMI(BB, PPC::OR, 2, Tmp7).addReg(Tmp6).addReg(Tmp6); - TmpMBB->addSuccessor(PhiMBB); - BB = PhiMBB; - BuildMI(BB, PPC::PHI, 4, Result).addReg(Tmp4).addMBB(OldMBB) - .addReg(Tmp7).addMBB(TmpMBB); } return Result+N.ResNo; } From lattner at cs.uiuc.edu Wed Aug 31 15:24:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 15:24:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200508312024.PAA26861@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.15 -> 1.16 --- Log message: Move SHL,SHR i64 -> legalizer --- Diffs of the changes: (+57 -2) PPC32ISelLowering.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 57 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.15 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.16 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.15 Wed Aug 31 14:09:57 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Wed Aug 31 15:23:54 2005 @@ -72,7 +72,9 @@ setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); - // PowerPC wants to expand SRA_PARTS into SELECT_CC and stuff. + // PowerPC wants to expand i64 shifts itself. + setOperationAction(ISD::SHL, MVT::i64, Custom); + setOperationAction(ISD::SRL, MVT::i64, Custom); setOperationAction(ISD::SRA, MVT::i64, Custom); // PowerPC does not have BRCOND* which requires SetCC @@ -164,7 +166,59 @@ } } break; - case ISD::SRA: + case ISD::SHL: { + assert(Op.getValueType() == MVT::i64 && + Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); + // The generic code does a fine job expanding shift by a constant. + if (isa(Op.getOperand(1))) break; + + // Otherwise, expand into a bunch of logical ops. Note that these ops + // depend on the PPC behavior for oversized shift amounts. + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), + DAG.getConstant(0, MVT::i32)); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), + DAG.getConstant(1, MVT::i32)); + SDOperand Amt = Op.getOperand(1); + + SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, + DAG.getConstant(32, MVT::i32), Amt); + SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt); + SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1); + SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); + SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, + DAG.getConstant(-32U, MVT::i32)); + SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5); + SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); + SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); + } + case ISD::SRL: { + assert(Op.getValueType() == MVT::i64 && + Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); + // The generic code does a fine job expanding shift by a constant. + if (isa(Op.getOperand(1))) break; + + // Otherwise, expand into a bunch of logical ops. Note that these ops + // depend on the PPC behavior for oversized shift amounts. + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), + DAG.getConstant(0, MVT::i32)); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), + DAG.getConstant(1, MVT::i32)); + SDOperand Amt = Op.getOperand(1); + + SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, + DAG.getConstant(32, MVT::i32), Amt); + SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); + SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); + SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); + SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, + DAG.getConstant(-32U, MVT::i32)); + SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5); + SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); + SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); + } + case ISD::SRA: { assert(Op.getValueType() == MVT::i64 && Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!"); // The generic code does a fine job expanding shift by a constant. @@ -190,6 +244,7 @@ Tmp4, Tmp6, ISD::SETLE); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } + } return SDOperand(); } From lattner at cs.uiuc.edu Wed Aug 31 15:25:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 15:25:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp PPC32ISelPattern.cpp Message-ID: <200508312025.PAA26929@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.65 -> 1.66 PPC32ISelPattern.cpp updated: 1.174 -> 1.175 --- Log message: Remove dead code --- Diffs of the changes: (+0 -75) PPC32ISelDAGToDAG.cpp | 38 -------------------------------------- PPC32ISelPattern.cpp | 37 ------------------------------------- 2 files changed, 75 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.65 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.66 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.65 Wed Aug 31 13:08:46 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Aug 31 15:25:15 2005 @@ -1220,44 +1220,6 @@ CurDAG->ReplaceAllUsesWith(N, Result); return Result[Op.ResNo]; } - case ISD::SHL_PARTS: { - SDOperand LO = Select(N->getOperand(0)); - SDOperand HI = Select(N->getOperand(1)); - SDOperand SH = Select(N->getOperand(2)); - SDOperand SH_LO_R = CurDAG->getTargetNode(PPC::SUBFIC, MVT::i32, MVT::Flag, - SH, getI32Imm(32)); - SDOperand SH_LO_L = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, SH, - getI32Imm((unsigned)-32)); - SDOperand HI_SHL = CurDAG->getTargetNode(PPC::SLW, MVT::i32, HI, SH); - SDOperand HI_LOR = CurDAG->getTargetNode(PPC::SRW, MVT::i32, LO, SH_LO_R); - SDOperand HI_LOL = CurDAG->getTargetNode(PPC::SLW, MVT::i32, LO, SH_LO_L); - SDOperand HI_OR = CurDAG->getTargetNode(PPC::OR, MVT::i32, HI_SHL, HI_LOR); - - std::vector Result; - Result.push_back(CurDAG->getTargetNode(PPC::SLW, MVT::i32, LO, SH)); - Result.push_back(CurDAG->getTargetNode(PPC::OR, MVT::i32, HI_OR, HI_LOL)); - CurDAG->ReplaceAllUsesWith(N, Result); - return Result[Op.ResNo]; - } - case ISD::SRL_PARTS: { - SDOperand LO = Select(N->getOperand(0)); - SDOperand HI = Select(N->getOperand(1)); - SDOperand SH = Select(N->getOperand(2)); - SDOperand SH_HI_L = CurDAG->getTargetNode(PPC::SUBFIC, MVT::i32, MVT::Flag, - SH, getI32Imm(32)); - SDOperand SH_HI_R = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, SH, - getI32Imm((unsigned)-32)); - SDOperand LO_SHR = CurDAG->getTargetNode(PPC::SRW, MVT::i32, LO, SH); - SDOperand LO_HIL = CurDAG->getTargetNode(PPC::SLW, MVT::i32, HI, SH_HI_L); - SDOperand LO_HIR = CurDAG->getTargetNode(PPC::SRW, MVT::i32, HI, SH_HI_R); - SDOperand LO_OR = CurDAG->getTargetNode(PPC::OR, MVT::i32, LO_SHR, LO_HIL); - - std::vector Result; - Result.push_back(CurDAG->getTargetNode(PPC::OR, MVT::i32, LO_OR, LO_HIR)); - Result.push_back(CurDAG->getTargetNode(PPC::SRW, MVT::i32, HI, SH)); - CurDAG->ReplaceAllUsesWith(N, Result); - return Result[Op.ResNo]; - } case ISD::LOAD: case ISD::EXTLOAD: Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.174 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.175 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.174 Wed Aug 31 14:11:36 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Aug 31 15:25:15 2005 @@ -801,8 +801,6 @@ break; case ISD::ADD_PARTS: case ISD::SUB_PARTS: - case ISD::SHL_PARTS: - case ISD::SRL_PARTS: Result = MakeReg(Node->getValueType(0)); ExprMap[N.getValue(0)] = Result; for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i) @@ -1438,41 +1436,6 @@ return Result+N.ResNo; } - case ISD::SHL_PARTS: - case ISD::SRL_PARTS: { - assert(N.getNumOperands() == 3 && N.getValueType() == MVT::i32 && - "Not an i64 shift!"); - unsigned ShiftOpLo = SelectExpr(N.getOperand(0)); - unsigned ShiftOpHi = SelectExpr(N.getOperand(1)); - unsigned SHReg = FoldIfWideZeroExtend(N.getOperand(2)); - Tmp1 = MakeIntReg(); - Tmp2 = MakeIntReg(); - Tmp3 = MakeIntReg(); - unsigned Tmp4 = MakeIntReg(); - unsigned Tmp5 = MakeIntReg(); - unsigned Tmp6 = MakeIntReg(); - BuildMI(BB, PPC::SUBFIC, 2, Tmp1).addReg(SHReg).addSImm(32); - if (ISD::SHL_PARTS == opcode) { - BuildMI(BB, PPC::SLW, 2, Tmp2).addReg(ShiftOpHi).addReg(SHReg); - BuildMI(BB, PPC::SRW, 2, Tmp3).addReg(ShiftOpLo).addReg(Tmp1); - BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3); - BuildMI(BB, PPC::ADDI, 2, Tmp5).addReg(SHReg).addSImm(-32); - BuildMI(BB, PPC::SLW, 2, Tmp6).addReg(ShiftOpLo).addReg(Tmp5); - BuildMI(BB, PPC::OR, 2, Result+1).addReg(Tmp4).addReg(Tmp6); - BuildMI(BB, PPC::SLW, 2, Result).addReg(ShiftOpLo).addReg(SHReg); - } else { - assert (opcode == ISD::SRL_PARTS); - BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg); - BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1); - BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3); - BuildMI(BB, PPC::ADDI, 2, Tmp5).addReg(SHReg).addSImm(-32); - BuildMI(BB, PPC::SRW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5); - BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp4).addReg(Tmp6); - BuildMI(BB, PPC::SRW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg); - } - return Result+N.ResNo; - } - case ISD::FP_TO_SINT: { Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = MakeFPReg(); From lattner at cs.uiuc.edu Wed Aug 31 16:10:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 16:10:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp PPC32ISelLowering.cpp PPC32ISelLowering.h PPC32ISelPattern.cpp Message-ID: <200508312110.QAA27479@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.66 -> 1.67 PPC32ISelLowering.cpp updated: 1.16 -> 1.17 PPC32ISelLowering.h updated: 1.4 -> 1.5 PPC32ISelPattern.cpp updated: 1.175 -> 1.176 --- Log message: Move FCTIWZ handling out of the instruction selectors and into legalization, getting them out of the business of making stack slots. --- Diffs of the changes: (+71 -65) PPC32ISelDAGToDAG.cpp | 17 ++------ PPC32ISelLowering.cpp | 100 +++++++++++++++++++++++++++++--------------------- PPC32ISelLowering.h | 4 ++ PPC32ISelPattern.cpp | 15 ++----- 4 files changed, 71 insertions(+), 65 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.66 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.67 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.66 Wed Aug 31 15:25:15 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Wed Aug 31 16:09:52 2005 @@ -17,7 +17,6 @@ #include "PPC32ISelLowering.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAGISel.h" @@ -793,6 +792,10 @@ Select(N->getOperand(1)), Select(N->getOperand(2))); break; + case PPCISD::FCTIWZ: + CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), + Select(N->getOperand(0))); + break; case ISD::ADD: { MVT::ValueType Ty = N->getValueType(0); if (Ty == MVT::i32) { @@ -1119,18 +1122,6 @@ MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND"); CurDAG->SelectNodeTo(N, PPC::FRSP, MVT::f32, Select(N->getOperand(0))); break; - case ISD::FP_TO_SINT: { - SDOperand In = Select(N->getOperand(0)); - In = CurDAG->getTargetNode(PPC::FCTIWZ, MVT::f64, In); - - int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); - SDOperand FI = CurDAG->getTargetFrameIndex(FrameIdx, MVT::f64); - SDOperand ST = CurDAG->getTargetNode(PPC::STFD, MVT::Other, In, - getI32Imm(0), FI); - CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, MVT::Other, - getI32Imm(4), FI, ST); - break; - } case ISD::FNEG: { SDOperand Val = Select(N->getOperand(0)); MVT::ValueType Ty = N->getValueType(0); Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.16 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.17 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.16 Wed Aug 31 15:23:54 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Wed Aug 31 16:09:52 2005 @@ -84,6 +84,9 @@ // PowerPC does not have FP_TO_UINT setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); + // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + // PowerPC does not have [U|S]INT_TO_FP setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); @@ -111,61 +114,76 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Wasn't expecting to be able to lower this!"); - case ISD::SELECT_CC: + case ISD::FP_TO_SINT: { + assert(Op.getValueType() == MVT::i32 && + MVT::isFloatingPoint(Op.getOperand(0).getValueType())); + Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); + + int FrameIdx = + DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); + SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); + SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op, FI, DAG.getSrcValue(0)); + FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); + return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); + } + case ISD::SELECT_CC: { // Turn FP only select_cc's into fsel instructions. - if (MVT::isFloatingPoint(Op.getOperand(0).getValueType()) && - MVT::isFloatingPoint(Op.getOperand(2).getValueType())) { - ISD::CondCode CC = cast(Op.getOperand(4))->get(); - - // Cannot handle SETEQ/SETNE. - if (CC == ISD::SETEQ || CC == ISD::SETNE) break; - - MVT::ValueType ResVT = Op.getValueType(); - MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); - SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); - SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3); - - // If the RHS of the comparison is a 0.0, we don't need to do the - // subtraction at all. - if (isFloatingPointZero(RHS)) - switch (CC) { - default: assert(0 && "Invalid FSEL condition"); abort(); - case ISD::SETULT: - case ISD::SETLT: - std::swap(TV, FV); // fsel is natively setge, swap operands for setlt - case ISD::SETUGE: - case ISD::SETGE: - return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); - case ISD::SETUGT: - case ISD::SETGT: - std::swap(TV, FV); // fsel is natively setge, swap operands for setlt - case ISD::SETULE: - case ISD::SETLE: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV); - } - + if (!MVT::isFloatingPoint(Op.getOperand(0).getValueType()) || + !MVT::isFloatingPoint(Op.getOperand(2).getValueType())) + break; + + ISD::CondCode CC = cast(Op.getOperand(4))->get(); + + // Cannot handle SETEQ/SETNE. + if (CC == ISD::SETEQ || CC == ISD::SETNE) break; + + MVT::ValueType ResVT = Op.getValueType(); + MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); + SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); + SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3); + + // If the RHS of the comparison is a 0.0, we don't need to do the + // subtraction at all. + if (isFloatingPointZero(RHS)) switch (CC) { default: assert(0 && "Invalid FSEL condition"); abort(); case ISD::SETULT: case ISD::SETLT: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); + std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETUGE: case ISD::SETGE: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); + return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); case ISD::SETUGT: case ISD::SETGT: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); + std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETULE: case ISD::SETLE: return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV); + DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV); } + + switch (CC) { + default: assert(0 && "Invalid FSEL condition"); abort(); + case ISD::SETULT: + case ISD::SETLT: + return DAG.getNode(PPCISD::FSEL, ResVT, + DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); + case ISD::SETUGE: + case ISD::SETGE: + return DAG.getNode(PPCISD::FSEL, ResVT, + DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); + case ISD::SETUGT: + case ISD::SETGT: + return DAG.getNode(PPCISD::FSEL, ResVT, + DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); + case ISD::SETULE: + case ISD::SETLE: + return DAG.getNode(PPCISD::FSEL, ResVT, + DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV); } - break; + break; + } case ISD::SHL: { assert(Op.getValueType() == MVT::i64 && Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.h diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.4 llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.5 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.h:1.4 Fri Aug 26 16:23:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.h Wed Aug 31 16:09:52 2005 @@ -28,6 +28,10 @@ /// FSEL - Traditional three-operand fsel node. /// FSEL, + + /// FCTIWZ - The FCTIWZ instruction, taking an f32 or f64 operand, + /// producing an f64 value. + FCTIWZ, }; } Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.175 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.176 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.175 Wed Aug 31 15:25:15 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Aug 31 16:09:52 2005 @@ -22,7 +22,6 @@ #include "llvm/Function.h" #include "llvm/CodeGen/MachineConstantPool.h" #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" @@ -818,6 +817,10 @@ Tmp3 = SelectExpr(N.getOperand(2)); BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; + case PPCISD::FCTIWZ: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FCTIWZ, 1, Result).addReg(Tmp1); + return Result; case ISD::UNDEF: if (Node->getValueType(0) == MVT::i32) BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result); @@ -1436,16 +1439,6 @@ return Result+N.ResNo; } - case ISD::FP_TO_SINT: { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = MakeFPReg(); - BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1); - int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); - addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx); - addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4); - return Result; - } - case ISD::SETCC: { ISD::CondCode CC = cast(Node->getOperand(2))->get(); if (isIntImmediate(Node->getOperand(1), Tmp3)) { From lattner at cs.uiuc.edu Wed Aug 31 17:35:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 17:35:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineFunction.cpp Message-ID: <200508312235.RAA27991@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineFunction.cpp updated: 1.79 -> 1.80 --- Log message: If a function has live ins/outs, print them --- Diffs of the changes: (+23 -1) MachineFunction.cpp | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.79 llvm/lib/CodeGen/MachineFunction.cpp:1.80 --- llvm/lib/CodeGen/MachineFunction.cpp:1.79 Fri May 13 17:54:44 2005 +++ llvm/lib/CodeGen/MachineFunction.cpp Wed Aug 31 17:34:59 2005 @@ -134,7 +134,29 @@ // Print Constant Pool getConstantPool()->print(OS); - + + const MRegisterInfo *MRI = getTarget().getRegisterInfo(); + + if (livein_begin() != livein_end()) { + OS << "Live Ins:"; + for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) { + if (MRI) + OS << " " << MRI->getName(I->first); + else + OS << " Reg #" << I->first; + } + OS << "\n"; + } + if (liveout_begin() != liveout_end()) { + OS << "Live Outs:"; + for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I) + if (MRI) + OS << " " << MRI->getName(*I); + else + OS << " Reg #" << *I; + OS << "\n"; + } + for (const_iterator BB = begin(); BB != end(); ++BB) BB->print(OS); From lattner at cs.uiuc.edu Wed Aug 31 17:50:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 31 Aug 2005 17:50:03 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFunction.h Message-ID: <200508312250.RAA28083@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFunction.h updated: 1.54 -> 1.55 --- Log message: remove an inappropriate comment --- Diffs of the changes: (+1 -2) MachineFunction.h | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.54 llvm/include/llvm/CodeGen/MachineFunction.h:1.55 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.54 Fri May 13 02:07:52 2005 +++ llvm/include/llvm/CodeGen/MachineFunction.h Wed Aug 31 17:49:51 2005 @@ -143,8 +143,7 @@ MachineConstantPool *getConstantPool() const { return ConstantPool; } /// MachineFunctionInfo - Keep track of various per-function pieces of - /// information for backends that would like to do so. (Currently, - /// SPARC and IA64.) + /// information for backends that would like to do so. /// template Ty *getInfo() { From natebegeman at mac.com Wed Aug 31 19:04:14 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 31 Aug 2005 19:04:14 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/mulhs.ll Message-ID: <200509010004.TAA28579@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: mulhs.ll added (r1.1) --- Log message: Add regression test for efficient codegen of i32 x i32 -> hi32(i64) as mulhs. --- Diffs of the changes: (+17 -0) mulhs.ll | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/mulhs.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/mulhs.ll:1.1 *** /dev/null Wed Aug 31 19:04:13 2005 --- llvm/test/Regression/CodeGen/PowerPC/mulhs.ll Wed Aug 31 19:04:03 2005 *************** *** 0 **** --- 1,17 ---- + ; All of these ands and shifts should be folded into rlwimi's + ; RUN: llvm-as < mulhs.ll | llc -march=ppc32 | not grep mulhwu && + ; RUN: llvm-as < mulhs.ll | llc -march=ppc32 | not grep srawi && + ; RUN: llvm-as < mulhs.ll | llc -march=ppc32 | not grep add && + ; RUN: llvm-as < mulhs.ll | llc -march=ppc32 | grep mulhw | wc -l | grep 1 + + implementation ; Functions: + + int %mulhs(int %a, int %b) { + entry: + %tmp.1 = cast int %a to ulong ; [#uses=1] + %tmp.3 = cast int %b to ulong ; [#uses=1] + %tmp.4 = mul ulong %tmp.3, %tmp.1 ; [#uses=1] + %tmp.6 = shr ulong %tmp.4, ubyte 32 ; [#uses=1] + %tmp.7 = cast ulong %tmp.6 to int ; [#uses=1] + ret int %tmp.7 + } From natebegeman at mac.com Wed Aug 31 19:19:37 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 31 Aug 2005 19:19:37 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200509010019.TAA28673@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.58 -> 1.59 --- Log message: First pass at the DAG Combiner. It isn't used anywhere yet, but it should be mostly functional. It currently has all folds from SelectionDAG.cpp that do not involve a condition code. --- Diffs of the changes: (+6 -0) SelectionDAG.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.58 llvm/include/llvm/CodeGen/SelectionDAG.h:1.59 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.58 Tue Aug 30 17:38:05 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Aug 31 19:19:25 2005 @@ -79,6 +79,12 @@ /// const SDOperand &setRoot(SDOperand N) { return Root = N; } + /// Combine - This iterates over the nodes in the SelectionDAG, folding + /// certain types of nodes together, or eliminating superfluous nodes. When + /// the AfterLegalize argument is set to 'true', Combine takes care not to + /// generate any nodes that will be illegal on the target. + void Combine(bool AfterLegalize); + /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is /// compatible with the target instruction selector, as indicated by the /// TargetLowering object. From natebegeman at mac.com Wed Aug 31 19:19:37 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 31 Aug 2005 19:19:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509010019.TAA28677@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp added (r1.1) --- Log message: First pass at the DAG Combiner. It isn't used anywhere yet, but it should be mostly functional. It currently has all folds from SelectionDAG.cpp that do not involve a condition code. --- Diffs of the changes: (+1056 -0) DAGCombiner.cpp | 1056 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1056 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -c /dev/null llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.1 *** /dev/null Wed Aug 31 19:19:35 2005 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Aug 31 19:19:25 2005 *************** *** 0 **** --- 1,1056 ---- + //===-- DAGCombiner.cpp - Implement a trivial DAG combiner ----------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Nate Begeman and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This pass combines dag nodes to form fewer, simpler DAG nodes. It can be run + // both before and after the DAG is legalized. + // + // FIXME: Missing folds + // sdiv, udiv, srem, urem (X, const) where X is an integer can be expanded into + // a sequence of multiplies, shifts, and adds. This should be controlled by + // some kind of hint from the target that int div is expensive. + // various folds of mulh[s,u] by constants such as -1, powers of 2, etc. + // + // FIXME: Should add a corresponding version of fold AND with + // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which + // we don't have yet. + // + // FIXME: mul (x, const) -> shifts + adds + // + // FIXME: undef values + // + // FIXME: zero extend when top bits are 0 -> drop it ? + // + //===----------------------------------------------------------------------===// + + #define DEBUG_TYPE "dagcombine" + #include "llvm/ADT/Statistic.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/Support/MathExtras.h" + #include "llvm/Target/TargetLowering.h" + #include + using namespace llvm; + + namespace { + Statistic<> NodesCombined ("dagcombiner", "Number of dag nodes combined"); + + class DAGCombiner { + SelectionDAG &DAG; + TargetLowering &TLI; + + // Worklist of all of the nodes that need to be simplified. + std::vector WorkList; + + /// AddUsersToWorkList - When an instruction is simplified, add all users of + /// the instruction to the work lists because they might get more simplified + /// now. + /// + void AddUsersToWorkList(SDNode *N) { + for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); + UI != UE; ++UI) { + SDNode *U = *UI; + for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) + WorkList.push_back(U->getOperand(i).Val); + } + } + + /// removeFromWorkList - remove all instances of N from the worklist. + void removeFromWorkList(SDNode *N) { + WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), N), + WorkList.end()); + } + + /// visit - call the node-specific routine that knows how to fold each + /// particular type of node. + SDNode *visit(SDNode *N); + + // Visitation implementation - Implement dag node combining for different + // node types. The semantics are as follows: + // Return Value: + // null - No change was made + // otherwise - Node N should be replaced by the returned node. + // + SDNode *visitTokenFactor(SDNode *N); + SDNode *visitAdd(SDNode *N); + SDNode *visitSub(SDNode *N); + SDNode *visitMul(SDNode *N); + SDNode *visitSdiv(SDNode *N); + SDNode *visitUdiv(SDNode *N); + SDNode *visitSrem(SDNode *N); + SDNode *visitUrem(SDNode *N); + SDNode *visitMulHiU(SDNode *N); + SDNode *visitMulHiS(SDNode *N); + SDNode *visitAnd(SDNode *N); + SDNode *visitOr(SDNode *N); + SDNode *visitXor(SDNode *N); + SDNode *visitShl(SDNode *N); + SDNode *visitSra(SDNode *N); + SDNode *visitSrl(SDNode *N); + SDNode *visitCtlz(SDNode *N); + SDNode *visitCttz(SDNode *N); + SDNode *visitCtpop(SDNode *N); + // select + // select_cc + // setcc + SDNode *visitSignExtend(SDNode *N); + SDNode *visitZeroExtend(SDNode *N); + SDNode *visitSignExtendInReg(SDNode *N); + SDNode *visitTruncate(SDNode *N); + SDNode *visitSintToFP(SDNode *N); + SDNode *visitUintToFP(SDNode *N); + SDNode *visitFPToSint(SDNode *N); + SDNode *visitFPToUint(SDNode *N); + SDNode *visitFPRound(SDNode *N); + SDNode *visitFPRoundInReg(SDNode *N); + SDNode *visitFPExtend(SDNode *N); + SDNode *visitFneg(SDNode *N); + SDNode *visitFabs(SDNode *N); + SDNode *visitExtLoad(SDNode *N); + SDNode *visitSextLoad(SDNode *N); + SDNode *visitZextLoad(SDNode *N); + SDNode *visitTruncStore(SDNode *N); + // brcond + // brcondtwoway + // br_cc + // brtwoway_cc + public: + DAGCombiner(SelectionDAG &D) + : DAG(D), TLI(D.getTargetLoweringInfo()) { + // Add all the dag nodes to the worklist. + WorkList.insert(WorkList.end(), D.allnodes_begin(), D.allnodes_end()); + } + + /// Run - runs the dag combiner on all nodes in the work list + void Run(bool AfterLegalize); + }; + } + + /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use + /// this predicate to simplify operations downstream. V and Mask are known to + /// be the same type. + static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask, + const TargetLowering &TLI) { + unsigned SrcBits; + if (Mask == 0) return true; + + // If we know the result of a setcc has the top bits zero, use this info. + switch (Op.getOpcode()) { + case ISD::Constant: + return (cast(Op)->getValue() & Mask) == 0; + + case ISD::SETCC: + return ((Mask & 1) == 0) && + TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; + + case ISD::ZEXTLOAD: + SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); + return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. + case ISD::ZERO_EXTEND: + case ISD::AssertZext: + SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); + return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); + + case ISD::AND: + // (X & C1) & C2 == 0 iff C1 & C2 == 0. + if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) + return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI); + + // FALL THROUGH + case ISD::OR: + case ISD::XOR: + return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(1), Mask, TLI); + case ISD::SELECT: + return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(2), Mask, TLI); + case ISD::SELECT_CC: + return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(3), Mask, TLI); + case ISD::SRL: + // (ushr X, C1) & C2 == 0 iff X & (C2 << C1) == 0 + if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { + uint64_t NewVal = Mask << ShAmt->getValue(); + SrcBits = MVT::getSizeInBits(Op.getValueType()); + if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1; + return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); + } + return false; + case ISD::SHL: + // (ushl X, C1) & C2 == 0 iff X & (C2 >> C1) == 0 + if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { + uint64_t NewVal = Mask >> ShAmt->getValue(); + return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); + } + return false; + case ISD::CTTZ: + case ISD::CTLZ: + case ISD::CTPOP: + // Bit counting instructions can not set the high bits of the result + // register. The max number of bits sets depends on the input. + return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0; + + // TODO we could handle some SRA cases here. + default: break; + } + + return false; + } + + // isInvertibleForFree - Return true if there is no cost to emitting the logical + // inverse of this node. + static bool isInvertibleForFree(SDOperand N) { + if (isa(N.Val)) return true; + if (N.Val->getOpcode() == ISD::SETCC && N.Val->hasOneUse()) + return true; + return false; + } + + // isSetCCEquivalent - Return true if this node is a select_cc that selects + // between the values 1 and 0, making it equivalent to a setcc. + static bool isSetCCEquivalent(SDOperand N) { + if (N.getOpcode() == ISD::SELECT_CC && + N.getOperand(2).getOpcode() == ISD::Constant && + N.getOperand(3).getOpcode() == ISD::Constant && + cast(N.getOperand(2))->getValue() == 1 && + cast(N.getOperand(3))->isNullValue()) + return true; + return false; + } + + void DAGCombiner::Run(bool AfterLegalize) { + // while the worklist isn't empty, inspect the node on the end of it and + // try and combine it. + while (!WorkList.empty()) { + SDNode *N = WorkList.back(); + WorkList.pop_back(); + + // If N has no uses, it is dead. Make sure to revisit all N's operands once + // N is deleted from the DAG, since they too may now be dead. + if (N->use_empty()) { + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + WorkList.push_back(N->getOperand(i).Val); + + DAG.DeleteNode(N); + removeFromWorkList(N); + continue; + } + + if (SDNode *Result = visit(N)) { + ++NodesCombined; + assert(Result != N && "Modifying DAG nodes in place is illegal!"); + + std::cerr << "DC: Old = "; N->dump(); + std::cerr << " New = "; Result->dump(); + std::cerr << '\n'; + DAG.ReplaceAllUsesWith(N, Result); + + // Push the new node and any users onto the worklist + WorkList.push_back(Result); + AddUsersToWorkList(Result); + + // Nodes can end up on the worklist more than once. Make sure we do + // not process a node that has been replaced. + removeFromWorkList(N); + } + } + } + + SDNode *DAGCombiner::visit(SDNode *N) { + switch(N->getOpcode()) { + default: break; + case ISD::TokenFactor: + return visitTokenFactor(N); + case ISD::ADD: + return visitAdd(N); + case ISD::SUB: + return visitSub(N); + case ISD::MUL: + return visitMul(N); + case ISD::SDIV: + return visitSdiv(N); + case ISD::UDIV: + return visitUdiv(N); + case ISD::SREM: + return visitSrem(N); + case ISD::UREM: + return visitUrem(N); + case ISD::SIGN_EXTEND: + return visitSignExtend(N); + case ISD::ZERO_EXTEND: + return visitZeroExtend(N); + case ISD::FNEG: + return visitFneg(N); + } + return 0; + } + + SDNode *DAGCombiner::visitTokenFactor(SDNode *N) { + // If the token factor only has one operand, fold TF(x) -> x + if (N->getNumOperands() == 1) + return N->getOperand(0).Val; + + // If the token factor has two operands and one is the entry token, replace + // the token factor with the other operand. + if (N->getNumOperands() == 2) { + if (N->getOperand(0).getOpcode() == ISD::EntryToken) + return N->getOperand(1).Val; + if (N->getOperand(1).getOpcode() == ISD::EntryToken) + return N->getOperand(0).Val; + } + return 0; + } + + SDNode *DAGCombiner::visitAdd(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + + // fold (add c1, c2) -> c1+c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() + N2C->getValue(), + N->getValueType(0)).Val; + // fold (add x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // fold floating point (add c1, c2) -> c1+c2 + if (N1CFP && N2CFP) + return DAG.getConstantFP(N1CFP->getValue() + N2CFP->getValue(), + N->getValueType(0)).Val; + // fold (A + (-B)) -> A-B + if (N1.getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(0)).Val; + // fold ((-A) + B) -> B-A + if (N0.getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(0)).Val; + // fold ((0-A) + B) -> B-A + if (N0.getOpcode() == ISD::SUB && isa(N0.getOperand(0)) && + cast(N0.getOperand(0))->isNullValue()) + return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(1)).Val; + // fold (A + (0-B)) -> A-B + if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && + cast(N1.getOperand(0))->isNullValue()) + return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(1)).Val; + // fold (A+(B-A)) -> B for non-fp types + if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1) && + !MVT::isFloatingPoint(N1.getValueType())) + return N1.getOperand(0).Val; + return 0; + } + + SDNode *DAGCombiner::visitSub(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + + // fold (sub c1, c2) -> c1-c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() - N2C->getValue(), + N->getValueType(0)).Val; + // fold (sub x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // fold floating point (sub c1, c2) -> c1-c2 + if (N1CFP && N2CFP) + return DAG.getConstantFP(N1CFP->getValue() - N2CFP->getValue(), + N->getValueType(0)).Val; + // fold (A+B)-A -> B + if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1 && + !MVT::isFloatingPoint(N1.getValueType())) + return N0.getOperand(1).Val; + // fold (A+B)-B -> A + if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 && + !MVT::isFloatingPoint(N1.getValueType())) + return N0.getOperand(0).Val; + // fold (A-(-B)) -> A+B + if (N1.getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::ADD, N0.getValueType(), N0, N1.getOperand(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitMul(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + + // fold (mul c1, c2) -> c1*c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() * N2C->getValue(), + N->getValueType(0)).Val; + // fold (mul x, 0) -> 0 + if (N2C && N2C->isNullValue()) + return N1.Val; + // fold (mul x, -1) -> 0-x + if (N2C && N2C->isAllOnesValue()) + return DAG.getNode(ISD::SUB, N->getValueType(0), + DAG.getConstant(0, N->getValueType(0)), N0).Val; + // fold (mul x, (1 << c)) -> x << c + if (N2C && isPowerOf2_64(N2C->getValue())) + return DAG.getNode(ISD::SHL, N->getValueType(0), N0, + DAG.getConstant(Log2_64(N2C->getValue()), + TLI.getShiftAmountTy())).Val; + // fold floating point (mul c1, c2) -> c1*c2 + if (N1CFP && N2CFP) + return DAG.getConstantFP(N1CFP->getValue() * N2CFP->getValue(), + N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitSdiv(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + + // fold (sdiv c1, c2) -> c1/c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getSignExtended() / N2C->getSignExtended(), + N->getValueType(0)).Val; + // fold floating point (sdiv c1, c2) -> c1/c2 + if (N1CFP && N2CFP) + return DAG.getConstantFP(N1CFP->getValue() / N2CFP->getValue(), + N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitUdiv(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + + // fold (udiv c1, c2) -> c1/c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() / N2C->getValue(), + N->getValueType(0)).Val; + // fold (udiv x, (1 << c)) -> x >>u c + if (N2C && isPowerOf2_64(N2C->getValue())) + return DAG.getNode(ISD::SRL, N->getValueType(0), N0, + DAG.getConstant(Log2_64(N2C->getValue()), + TLI.getShiftAmountTy())).Val; + return 0; + } + + SDNode *DAGCombiner::visitSrem(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + + // fold (srem c1, c2) -> c1%c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getSignExtended() % N2C->getSignExtended(), + N->getValueType(0)).Val; + // fold floating point (srem c1, c2) -> fmod(c1, c2) + if (N1CFP && N2CFP) + return DAG.getConstantFP(fmod(N1CFP->getValue(),N2CFP->getValue()), + N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitUrem(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + + // fold (urem c1, c2) -> c1%c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() % N2C->getValue(), + N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitMulHiS(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N2C = dyn_cast(N1.Val); + + // fold (mulhs x, 0) -> 0 + if (N2C && N2C->isNullValue()) + return N1.Val; + + // fold (mulhs x, 1) -> (sra x, size(x)-1) + if (N2C && N2C->getValue() == 1) + return DAG.getNode(ISD::SRA, N0.getValueType(), N0, + DAG.getConstant(MVT::getSizeInBits(N0.getValueType())-1, + TLI.getShiftAmountTy())).Val; + return 0; + } + + SDNode *DAGCombiner::visitMulHiU(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N2C = dyn_cast(N1.Val); + + // fold (mulhu x, 0) -> 0 + if (N2C && N2C->isNullValue()) + return N1.Val; + + // fold (mulhu x, 1) -> 0 + if (N2C && N2C->getValue() == 1) + return DAG.getConstant(0, N0.getValueType()).Val; + return 0; + } + + SDNode *DAGCombiner::visitAnd(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + MVT::ValueType VT = N1.getValueType(); + + // fold (and c1, c2) -> c1&c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() & N2C->getValue(), VT).Val; + // fold (and x, 0) -> 0 + if (N2C && N2C->isNullValue()) + return N1.Val; + // fold (and x, -1) -> x + if (N2C && N2C->isAllOnesValue()) + return N0.Val; + // fold (and x, 0) -> 0 + if (MaskedValueIsZero(N0, N2C->getValue(), TLI)) + return DAG.getConstant(0, VT).Val; + // fold (and x, mask containing x) -> x + uint64_t NotC2 = ~N2C->getValue(); + if (MVT::i64 != VT) NotC2 &= (1ULL << MVT::getSizeInBits(VT))-1; + if (MaskedValueIsZero(N0, NotC2, TLI)) + return N0.Val; + // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) + if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { + unsigned ExtendBits = + MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); + if ((N2C->getValue() & (~0ULL << ExtendBits)) == 0) + return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1).Val; + } + // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF + if (N0.getOpcode() == ISD::OR) + if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) + if ((ORI->getValue() & N2C->getValue()) == N2C->getValue()) + return N1.Val; + // fold (and (assert_zext x, i16), 0xFFFF) -> (assert_zext x, i16) + if (N0.getOpcode() == ISD::AssertZext) { + unsigned ExtendBits = + MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); + if (N2C->getValue() == (1ULL << ExtendBits)-1) + return N0.Val; + } + return 0; + } + + SDNode *DAGCombiner::visitOr(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + + // fold (or c1, c2) -> c1|c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() | N2C->getValue(), + N->getValueType(0)).Val; + // fold (or x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // fold (or x, -1) -> -1 + if (N2C && N2C->isAllOnesValue()) + return N1.Val; + return 0; + } + + SDNode *DAGCombiner::visitXor(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + MVT::ValueType VT = N0.getValueType(); + + // fold (xor c1, c2) -> c1^c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() ^ N2C->getValue(), VT).Val; + // fold (xor x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // fold !(x cc y) -> (x !cc y) + if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::SETCC) { + bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); + ISD::CondCode CC = cast(N0.getOperand(2))->get(); + return DAG.getSetCC(VT, N0.getOperand(0), N0.getOperand(1), + ISD::getSetCCInverse(CC, isInt)).Val; + } + // fold !(x cc y) -> (x !cc y) + if (N2C && N2C->isAllOnesValue() && isSetCCEquivalent(N0)) { + bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); + ISD::CondCode CC = cast(N0.getOperand(4))->get(); + return DAG.getSelectCC(N0.getOperand(0), N0.getOperand(1), + N0.getOperand(2), N0.getOperand(3), + ISD::getSetCCInverse(CC, isInt)).Val; + } + // fold !(x or y) -> (!x and !y) iff x or y are freely invertible + if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::OR) { + SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); + if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { + LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS + RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS + return DAG.getNode(ISD::AND, VT, LHS, RHS).Val; + } + } + // fold !(x and y) -> (!x or !y) iff x or y are freely invertible + if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::AND) { + SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); + if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { + LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS + RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS + return DAG.getNode(ISD::OR, VT, LHS, RHS).Val; + } + } + return 0; + } + + SDNode *DAGCombiner::visitShl(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + MVT::ValueType VT = N0.getValueType(); + unsigned OpSizeInBits = MVT::getSizeInBits(VT); + + // fold (shl c1, c2) -> c1<getValue() << N2C->getValue(), VT).Val; + // fold (shl 0, x) -> 0 + if (N1C && N1C->isNullValue()) + return N0.Val; + // fold (shl x, c >= size(x)) -> undef + if (N2C && N2C->getValue() >= OpSizeInBits) + return DAG.getNode(ISD::UNDEF, VT).Val; + // fold (shl x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // if (shl x, c) is known to be zero, return 0 + if (N2C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))>>N2C->getValue(), + TLI)) + return DAG.getConstant(0, VT).Val; + // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2) + if (N2C && N0.getOpcode() == ISD::SHL && + N0.getOperand(1).getOpcode() == ISD::Constant) { + uint64_t c1 = cast(N0.getOperand(1))->getValue(); + uint64_t c2 = N2C->getValue(); + if (c1 + c2 > OpSizeInBits) + return DAG.getConstant(0, VT).Val; + return DAG.getNode(ISD::SHL, VT, N0.getOperand(0), + DAG.getConstant(c1 + c2, N1.getValueType())).Val; + } + // fold (shl (srl x, c1), c2) -> (shl (and x, -1 << c1), c2-c1) or + // (srl (and x, -1 << c1), c1-c2) + if (N2C && N0.getOpcode() == ISD::SRL && + N0.getOperand(1).getOpcode() == ISD::Constant) { + uint64_t c1 = cast(N0.getOperand(1))->getValue(); + uint64_t c2 = N2C->getValue(); + SDOperand Mask = DAG.getNode(ISD::AND, VT, N0.getOperand(0), + DAG.getConstant(~0ULL << c1, VT)); + if (c2 > c1) + return DAG.getNode(ISD::SHL, VT, Mask, + DAG.getConstant(c2-c1, N1.getValueType())).Val; + else + return DAG.getNode(ISD::SRL, VT, Mask, + DAG.getConstant(c1-c2, N1.getValueType())).Val; + } + // fold (shl (sra x, c1), c1) -> (and x, -1 << c1) + if (N2C && N0.getOpcode() == ISD::SRA && + N0.getOperand(1).getOpcode() == ISD::Constant) { + uint64_t c1 = cast(N0.getOperand(1))->getValue(); + uint64_t c2 = N2C->getValue(); + if (c1 == c2) + return DAG.getNode(ISD::AND, VT, N0.getOperand(0), + DAG.getConstant(~0ULL << c1, VT)).Val; + } + return 0; + } + + SDNode *DAGCombiner::visitSra(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + MVT::ValueType VT = N0.getValueType(); + unsigned OpSizeInBits = MVT::getSizeInBits(VT); + + // fold (sra c1, c2) -> c1>>c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getSignExtended() >> N2C->getValue(), VT).Val; + // fold (sra 0, x) -> 0 + if (N1C && N1C->isNullValue()) + return N0.Val; + // fold (sra -1, x) -> -1 + if (N1C && N1C->isAllOnesValue()) + return N0.Val; + // fold (sra x, c >= size(x)) -> undef + if (N2C && N2C->getValue() >= OpSizeInBits) + return DAG.getNode(ISD::UNDEF, VT).Val; + // fold (sra x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // If the sign bit is known to be zero, switch this to a SRL. + if (N2C && MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) + return DAG.getNode(ISD::SRL, VT, N0, N1).Val; + return 0; + } + + SDNode *DAGCombiner::visitSrl(SDNode *N) { + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N2C = dyn_cast(N1.Val); + MVT::ValueType VT = N0.getValueType(); + unsigned OpSizeInBits = MVT::getSizeInBits(VT); + + // fold (srl c1, c2) -> c1 >>u c2 + if (N1C && N2C) + return DAG.getConstant(N1C->getValue() >> N2C->getValue(), VT).Val; + // fold (srl 0, x) -> 0 + if (N1C && N1C->isNullValue()) + return N0.Val; + // fold (srl x, c >= size(x)) -> undef + if (N2C && N2C->getValue() >= OpSizeInBits) + return DAG.getNode(ISD::UNDEF, VT).Val; + // fold (srl x, 0) -> x + if (N2C && N2C->isNullValue()) + return N0.Val; + // if (srl x, c) is known to be zero, return 0 + if (N2C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))<getValue(), + TLI)) + return DAG.getConstant(0, VT).Val; + // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2) + if (N2C && N0.getOpcode() == ISD::SRL && + N0.getOperand(1).getOpcode() == ISD::Constant) { + uint64_t c1 = cast(N0.getOperand(1))->getValue(); + uint64_t c2 = N2C->getValue(); + if (c1 + c2 > OpSizeInBits) + return DAG.getConstant(0, VT).Val; + return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), + DAG.getConstant(c1 + c2, N1.getValueType())).Val; + } + return 0; + } + + SDNode *DAGCombiner::visitCtlz(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + + // fold (ctlz c1) -> c2 + if (N1C) + return DAG.getConstant(CountLeadingZeros_64(N1C->getValue()), + N0.getValueType()).Val; + return 0; + } + + SDNode *DAGCombiner::visitCttz(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + + // fold (cttz c1) -> c2 + if (N1C) + return DAG.getConstant(CountTrailingZeros_64(N1C->getValue()), + N0.getValueType()).Val; + return 0; + } + + SDNode *DAGCombiner::visitCtpop(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + + // fold (ctpop c1) -> c2 + if (N1C) + return DAG.getConstant(CountPopulation_64(N1C->getValue()), + N0.getValueType()).Val; + return 0; + } + + SDNode *DAGCombiner::visitSignExtend(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + MVT::ValueType VT = N->getValueType(0); + + // noop sext + if (N0.getValueType() == N->getValueType(0)) + return N0.Val; + // fold (sext c1) -> c1 + if (N1C) + return DAG.getConstant(N1C->getSignExtended(), VT).Val; + // fold (sext (sext x)) -> (sext x) + if (N0.getOpcode() == ISD::SIGN_EXTEND) + return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitZeroExtend(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + MVT::ValueType VT = N->getValueType(0); + + // noop zext + if (N0.getValueType() == N->getValueType(0)) + return N0.Val; + // fold (zext c1) -> c1 + if (N1C) + return DAG.getConstant(N1C->getValue(), VT).Val; + // fold (zext (zext x)) -> (zext x) + if (N0.getOpcode() == ISD::ZERO_EXTEND) + return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitSignExtendInReg(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); + + // noop sext_in_reg + if (EVT == VT) + return N0.Val; + // fold (sext_in_reg c1) -> c1 + if (N1C) { + SDOperand Truncate = DAG.getConstant(N1C->getValue(), EVT); + return DAG.getNode(ISD::SIGN_EXTEND, VT, Truncate).Val; + } + // fold (sext_in_reg (sext_in_reg x)) -> (sext_in_reg x) + if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && + cast(N0.getOperand(1))->getVT() <= EVT) { + return N0.Val; + } + // fold (sext_in_reg (assert_sext x)) -> (assert_sext x) + if (N0.getOpcode() == ISD::AssertSext && + cast(N0.getOperand(1))->getVT() <= EVT) { + return N0.Val; + } + // fold (sext_in_reg (sextload x)) -> (sextload x) + if (N0.getOpcode() == ISD::SEXTLOAD && + cast(N0.getOperand(3))->getVT() <= EVT) { + return N0.Val; + } + // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or 1 + if (N0.getOpcode() == ISD::SETCC && + TLI.getSetCCResultContents() == + TargetLowering::ZeroOrNegativeOneSetCCResult) + return N0.Val; + // FIXME: this code is currently just ported over from SelectionDAG.cpp + // we probably actually want to handle this in two pieces. Rather than + // checking all the top bits for zero, just check the sign bit here and turn + // it into a zero extend inreg (AND with constant). + // then, let the code for AND figure out if the mask is superfluous rather + // than doing so here. + if (N0.getOpcode() == ISD::AND && + N0.getOperand(1).getOpcode() == ISD::Constant) { + uint64_t Mask = cast(N0.getOperand(1))->getValue(); + unsigned NumBits = MVT::getSizeInBits(EVT); + if ((Mask & (~0ULL << (NumBits-1))) == 0) + return N0.Val; + } + return 0; + } + + SDNode *DAGCombiner::visitTruncate(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + MVT::ValueType VT = N->getValueType(0); + + // noop truncate + if (N0.getValueType() == N->getValueType(0)) + return N0.Val; + // fold (truncate c1) -> c1 + if (N1C) + return DAG.getConstant(N1C->getValue(), VT).Val; + // fold (truncate (truncate x)) -> (truncate x) + if (N0.getOpcode() == ISD::TRUNCATE) + return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; + // fold (truncate (ext x)) -> (ext x) or (truncate x) or x + if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND){ + if (N0.getValueType() < VT) + // if the source is smaller than the dest, we still need an extend + return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0)).Val; + else if (N0.getValueType() > VT) + // if the source is larger than the dest, than we just need the truncate + return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; + else + // if the source and dest are the same type, we can drop both the extend + // and the truncate + return N0.getOperand(0).Val; + } + return 0; + } + + SDNode *DAGCombiner::visitSintToFP(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + MVT::ValueType VT = N->getValueType(0); + + // fold (sint_to_fp c1) -> c1fp + if (N1C) + return DAG.getConstantFP(N1C->getSignExtended(), VT).Val; + return 0; + } + + SDNode *DAGCombiner::visitUintToFP(SDNode *N) { + SDOperand N0 = N->getOperand(0); + ConstantSDNode *N1C = dyn_cast(N0.Val); + MVT::ValueType VT = N->getValueType(0); + + // fold (uint_to_fp c1) -> c1fp + if (N1C) + return DAG.getConstantFP(N1C->getValue(), VT).Val; + return 0; + } + + SDNode *DAGCombiner::visitFPToSint(SDNode *N) { + ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); + + // fold (fp_to_sint c1fp) -> c1 + if (N1CFP) + return DAG.getConstant((int64_t)N1CFP->getValue(), N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitFPToUint(SDNode *N) { + ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); + + // fold (fp_to_uint c1fp) -> c1 + if (N1CFP) + return DAG.getConstant((uint64_t)N1CFP->getValue(), N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitFPRound(SDNode *N) { + ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); + + // fold (fp_round c1fp) -> c1fp + if (N1CFP) + return DAG.getConstantFP(N1CFP->getValue(), N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitFPRoundInReg(SDNode *N) { + SDOperand N0 = N->getOperand(0); + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); + ConstantFPSDNode *N1CFP = dyn_cast(N0); + + // noop fp_round_inreg + if (EVT == VT) + return N0.Val; + // fold (fp_round_inreg c1fp) -> c1fp + if (N1CFP) { + SDOperand Round = DAG.getConstantFP(N1CFP->getValue(), EVT); + return DAG.getNode(ISD::FP_EXTEND, VT, Round).Val; + } + return 0; + } + + SDNode *DAGCombiner::visitFPExtend(SDNode *N) { + ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); + + // fold (fp_extend c1fp) -> c1fp + if (N1CFP) + return DAG.getConstantFP(N1CFP->getValue(), N->getValueType(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitFneg(SDNode *N) { + ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); + // fold (neg c1) -> -c1 + if (N1CFP) + return DAG.getConstantFP(-N1CFP->getValue(), N->getValueType(0)).Val; + // fold (neg (sub x, y)) -> (sub y, x) + if (N->getOperand(0).getOpcode() == ISD::SUB) + return DAG.getNode(ISD::SUB, N->getValueType(0), N->getOperand(1), + N->getOperand(0)).Val; + // fold (neg (neg x)) -> x + if (N->getOperand(0).getOpcode() == ISD::FNEG) + return N->getOperand(0).getOperand(0).Val; + return 0; + } + + SDNode *DAGCombiner::visitFabs(SDNode *N) { + ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); + // fold (fabs c1) -> fabs(c1) + if (N1CFP) + return DAG.getConstantFP(fabs(N1CFP->getValue()), N->getValueType(0)).Val; + // fold (fabs (fabs x)) -> (fabs x) + if (N->getOperand(0).getOpcode() == ISD::FABS) + return N->getOperand(0).Val; + // fold (fabs (fneg x)) -> (fabs x) + if (N->getOperand(0).getOpcode() == ISD::FNEG) + return DAG.getNode(ISD::FABS, N->getValueType(0), + N->getOperand(0).getOperand(0)).Val; + return 0; + } + + SDNode *DAGCombiner::visitExtLoad(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType EVT = cast(N->getOperand(3))->getVT(); + + // fold (extload vt, x) -> (load x) + if (EVT == VT) + return DAG.getLoad(VT, N->getOperand(0), N->getOperand(1), + N->getOperand(2)).Val; + return 0; + } + + SDNode *DAGCombiner::visitSextLoad(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType EVT = cast(N->getOperand(3))->getVT(); + + // fold (sextload vt, x) -> (load x) + if (EVT == VT) + return DAG.getLoad(VT, N->getOperand(0), N->getOperand(1), + N->getOperand(2)).Val; + return 0; + } + + SDNode *DAGCombiner::visitZextLoad(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType EVT = cast(N->getOperand(3))->getVT(); + + // fold (zextload vt, x) -> (load x) + if (EVT == VT) + return DAG.getLoad(VT, N->getOperand(0), N->getOperand(1), + N->getOperand(2)).Val; + return 0; + } + + SDNode *DAGCombiner::visitTruncStore(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType EVT = cast(N->getOperand(4))->getVT(); + + // fold (truncstore x, vt) -> (store x) + if (N->getOperand(0).getValueType() == EVT) + return DAG.getNode(ISD::STORE, VT, N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3)).Val; + return 0; + } + + // SelectionDAG::Combine - This is the entry point for the file. + // + void SelectionDAG::Combine(bool AfterLegalize) { + /// run - This is the main entry point to this class. + /// + DAGCombiner(*this).Run(AfterLegalize); + } From natebegeman at mac.com Wed Aug 31 19:33:43 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 31 Aug 2005 19:33:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509010033.TAA28823@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.1 -> 1.2 --- Log message: Add the rest of the currently implemented visit routines to the switch statement in visit(). --- Diffs of the changes: (+36 -22) DAGCombiner.cpp | 58 ++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 36 insertions(+), 22 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.1 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.2 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.1 Wed Aug 31 19:19:25 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Aug 31 19:33:32 2005 @@ -263,28 +263,42 @@ SDNode *DAGCombiner::visit(SDNode *N) { switch(N->getOpcode()) { default: break; - case ISD::TokenFactor: - return visitTokenFactor(N); - case ISD::ADD: - return visitAdd(N); - case ISD::SUB: - return visitSub(N); - case ISD::MUL: - return visitMul(N); - case ISD::SDIV: - return visitSdiv(N); - case ISD::UDIV: - return visitUdiv(N); - case ISD::SREM: - return visitSrem(N); - case ISD::UREM: - return visitUrem(N); - case ISD::SIGN_EXTEND: - return visitSignExtend(N); - case ISD::ZERO_EXTEND: - return visitZeroExtend(N); - case ISD::FNEG: - return visitFneg(N); + case ISD::TokenFactor: return visitTokenFactor(N); + case ISD::ADD: return visitAdd(N); + case ISD::SUB: return visitSub(N); + case ISD::MUL: return visitMul(N); + case ISD::SDIV: return visitSdiv(N); + case ISD::UDIV: return visitUdiv(N); + case ISD::SREM: return visitSrem(N); + case ISD::UREM: return visitUrem(N); + case ISD::MULHU: return visitMulHiU(N); + case ISD::MULHS: return visitMulHiS(N); + case ISD::AND: return visitAnd(N); + case ISD::OR: return visitOr(N); + case ISD::XOR: return visitXor(N); + case ISD::SHL: return visitShl(N); + case ISD::SRA: return visitSra(N); + case ISD::SRL: return visitSrl(N); + case ISD::CTLZ: return visitCtlz(N); + case ISD::CTTZ: return visitCttz(N); + case ISD::CTPOP: return visitCtpop(N); + case ISD::SIGN_EXTEND: return visitSignExtend(N); + case ISD::ZERO_EXTEND: return visitZeroExtend(N); + case ISD::SIGN_EXTEND_INREG: return visitSignExtendInReg(N); + case ISD::TRUNCATE: return visitTruncate(N); + case ISD::SINT_TO_FP: return visitSintToFP(N); + case ISD::UINT_TO_FP: return visitUintToFP(N); + case ISD::FP_TO_SINT: return visitFPToSint(N); + case ISD::FP_TO_UINT: return visitFPToUint(N); + case ISD::FP_ROUND: return visitFPRound(N); + case ISD::FP_ROUND_INREG: return visitFPRoundInReg(N); + case ISD::FP_EXTEND: return visitFPExtend(N); + case ISD::FNEG: return visitFneg(N); + case ISD::FABS: return visitFabs(N); + case ISD::EXTLOAD: return visitExtLoad(N); + case ISD::SEXTLOAD: return visitSextLoad(N); + case ISD::ZEXTLOAD: return visitZextLoad(N); + case ISD::TRUNCSTORE: return visitTruncStore(N); } return 0; } From lattner at cs.uiuc.edu Thu Sep 1 13:44:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 13:44:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp Message-ID: <200509011844.NAA06385@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.20 -> 1.21 SelectionDAGISel.cpp updated: 1.77 -> 1.78 --- Log message: It is NDEBUG not _NDEBUG --- Diffs of the changes: (+3 -3) ScheduleDAG.cpp | 4 ++-- SelectionDAGISel.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.20 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.21 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.20 Mon Aug 29 20:58:51 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu Sep 1 13:44:10 2005 @@ -24,7 +24,7 @@ #include "llvm/Support/CommandLine.h" using namespace llvm; -#ifndef _NDEBUG +#ifndef NDEBUG static cl::opt ViewDAGs("view-sched-dags", cl::Hidden, cl::desc("Pop up a window to show sched dags as they are processed")); @@ -103,7 +103,7 @@ --NodeOperands; unsigned NumMIOperands = NodeOperands+NumResults; -#ifndef _NDEBUG +#ifndef NDEBUG assert((unsigned(II.numOperands) == NumMIOperands || II.numOperands == -1)&& "#operands for dag node doesn't match .td file!"); #endif Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.77 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.78 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.77 Sat Aug 27 11:16:51 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Sep 1 13:44:10 2005 @@ -36,7 +36,7 @@ #include using namespace llvm; -#ifndef _NDEBUG +#ifndef NDEBUG static cl::opt ViewDAGs("view-isel-dags", cl::Hidden, cl::desc("Pop up a window to show isel dags as they are selected")); From lattner at cs.uiuc.edu Thu Sep 1 13:55:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 13:55:17 -0500 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Applications/SPASS/Makefile Message-ID: <200509011855.NAA06755@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Applications/SPASS: Makefile updated: 1.6 -> 1.7 --- Log message: remove space from end of line --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/MultiSource/Applications/SPASS/Makefile diff -u llvm-test/MultiSource/Applications/SPASS/Makefile:1.6 llvm-test/MultiSource/Applications/SPASS/Makefile:1.7 --- llvm-test/MultiSource/Applications/SPASS/Makefile:1.6 Tue May 10 09:09:21 2005 +++ llvm-test/MultiSource/Applications/SPASS/Makefile Thu Sep 1 13:55:05 2005 @@ -1,5 +1,5 @@ LEVEL = ../../.. -PROG = SPASS +PROG = SPASS CPPFLAGS = -DCLOCK_NO_TIMING -fno-strict-aliasing -w LDFLAGS = -lm From lattner at cs.uiuc.edu Thu Sep 1 14:20:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 14:20:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509011920.OAA07222@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.67 -> 1.68 --- Log message: Do not select the operands being passed into SelectCC. IT does this itself and selecting early prevents folding immediates into the cmpw* instructions --- Diffs of the changes: (+2 -4) PPC32ISelDAGToDAG.cpp | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.67 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.68 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.67 Wed Aug 31 16:09:52 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Thu Sep 1 14:20:44 2005 @@ -1344,8 +1344,7 @@ bool Inv; unsigned Idx = getCRIdxForSetCC(CC, Inv); - SDOperand CCReg = - SelectCC(Select(N->getOperand(0)), Select(N->getOperand(1)), CC); + SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); SDOperand IntCR; // Force the ccreg into CR7. @@ -1396,8 +1395,7 @@ break; } - SDOperand CCReg = SelectCC(Select(N->getOperand(0)), - Select(N->getOperand(1)), CC); + SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); unsigned BROpc = getBCCForSetCC(CC); bool isFP = MVT::isFloatingPoint(N->getValueType(0)); From lattner at cs.uiuc.edu Thu Sep 1 14:38:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 14:38:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509011938.OAA07505@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.68 -> 1.69 --- Log message: Fix a bug where we were useing HA to get the high part, which seems like it could cause a miscompile. Fixing this didn't fix the two programs that fail though. :( This also changes the implementation to follow the pattern selector more closely, causing us to select 0 to li instead of lis. --- Diffs of the changes: (+10 -11) PPC32ISelDAGToDAG.cpp | 21 ++++++++++----------- 1 files changed, 10 insertions(+), 11 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.68 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.69 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.68 Thu Sep 1 14:20:44 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Thu Sep 1 14:38:28 2005 @@ -685,22 +685,21 @@ case ISD::Constant: { assert(N->getValueType(0) == MVT::i32); unsigned v = (unsigned)cast(N)->getValue(); - unsigned Hi = HA16(v); - unsigned Lo = Lo16(v); // NOTE: This doesn't use SelectNodeTo, because doing that will prevent // folding shared immediates into other the second instruction that // uses it. - if (Hi && Lo) { - SDOperand Top = CurDAG->getTargetNode(PPC::LIS, MVT::i32, - getI32Imm(v >> 16)); - return CurDAG->getTargetNode(PPC::ORI, MVT::i32, Top, - getI32Imm(v & 0xFFFF)); - } else if (Lo) { + if (isInt16(v)) return CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(v)); - } else { - return CurDAG->getTargetNode(PPC::LIS, MVT::i32, getI32Imm(v >> 16)); - } + + unsigned Hi = Hi16(v); + unsigned Lo = Lo16(v); + + if (!Lo) + return CurDAG->getTargetNode(PPC::LIS, MVT::i32, getI32Imm(Hi)); + + SDOperand Top = CurDAG->getTargetNode(PPC::LIS, MVT::i32, getI32Imm(Hi)); + return CurDAG->getTargetNode(PPC::ORI, MVT::i32, Top, getI32Imm(Lo)); } case ISD::UNDEF: if (N->getValueType(0) == MVT::i32) From lattner at cs.uiuc.edu Thu Sep 1 16:31:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 16:31:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509012131.QAA08813@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.69 -> 1.70 --- Log message: Implement dynamic allocas correctly. In particular, because we were copying directly out of R1 (without using a CopyFromReg, which uses a chain), multiple allocas were getting CSE'd together, producing bogus code. For this: int %foo(bool %X, int %A, int %B) { br bool %X, label %T, label %F F: %G = alloca int %H = alloca int store int %A, int* %G store int %B, int* %H %R = load int* %G ret int %R T: ret int 0 } We were generating: _foo: stwu r1, -16(r1) stw r31, 4(r1) or r31, r1, r1 stw r1, 12(r31) cmpwi cr0, r3, 0 bne cr0, .LBB_foo_2 ; T .LBB_foo_1: ; F li r2, 16 subf r2, r2, r1 ;; One alloca or r1, r2, r2 or r3, r1, r1 or r1, r2, r2 or r2, r1, r1 stw r4, 0(r3) stw r5, 0(r2) lwz r3, 0(r3) lwz r1, 12(r31) lwz r31, 4(r31) lwz r1, 0(r1) blr .LBB_foo_2: ; T li r3, 0 lwz r1, 12(r31) lwz r31, 4(r31) lwz r1, 0(r1) blr Now we generate: _foo: stwu r1, -16(r1) stw r31, 4(r1) or r31, r1, r1 stw r1, 12(r31) cmpwi cr0, r3, 0 bne cr0, .LBB_foo_2 ; T .LBB_foo_1: ; F or r2, r1, r1 li r3, 16 subf r2, r3, r2 ;; Alloca 1 or r1, r2, r2 or r2, r1, r1 or r6, r1, r1 subf r3, r3, r6 ;; Alloca 2 or r1, r3, r3 or r3, r1, r1 stw r4, 0(r2) stw r5, 0(r3) lwz r3, 0(r2) lwz r1, 12(r31) lwz r31, 4(r31) lwz r1, 0(r1) blr .LBB_foo_2: ; T li r3, 0 lwz r1, 12(r31) lwz r31, 4(r31) lwz r1, 0(r1) blr This fixes Povray and SPASS with the dag isel, the last two failing cases. Tommorow we will hopefully turn it on by default! :) --- Diffs of the changes: (+4 -1) PPC32ISelDAGToDAG.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.69 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.70 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.69 Thu Sep 1 14:38:28 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Thu Sep 1 16:31:30 2005 @@ -754,9 +754,12 @@ SDOperand R1Reg = CurDAG->getRegister(PPC::R1, MVT::i32); + SDOperand R1Val = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); + Chain = R1Val.getValue(1); + // Subtract the amount (guaranteed to be a multiple of the stack alignment) // from the stack pointer, giving us the result pointer. - SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Reg); + SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Val); // Copy this result back into R1. Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R1Reg, Result); From jlaskey at apple.com Thu Sep 1 16:36:30 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:36:30 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/SubtargetFeature.h Message-ID: <200509012136.QAA08973@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: SubtargetFeature.h added (r1.1) --- Log message: This new class provides support for platform specific "features". The intent is to manage processor specific attributes from the command line. See examples of use in llc/lli and PowerPCTargetSubtarget. --- Diffs of the changes: (+145 -0) SubtargetFeature.h | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 145 insertions(+) Index: llvm/include/llvm/Target/SubtargetFeature.h diff -c /dev/null llvm/include/llvm/Target/SubtargetFeature.h:1.1 *** /dev/null Thu Sep 1 16:36:28 2005 --- llvm/include/llvm/Target/SubtargetFeature.h Thu Sep 1 16:36:18 2005 *************** *** 0 **** --- 1,145 ---- + //===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Jim Laskey and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines and manages user or tool specified CPU characteristics. + // The intent is to be able to package specific features that should or should + // not be used on a specific target processor. A tool, such as llc, could, as + // as example, gather chip info from the command line, a long with features + // that should be used on that chip. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_TARGET_SUBTARGETFEATURE_H + #define LLVM_TARGET_SUBTARGETFEATURE_H + + + #include + #include + #include + #include + + namespace llvm { + + //===----------------------------------------------------------------------===// + /// + /// SubtargetFeatureKV - Used to provide key value pairs for feature and + /// CPU bit flags. + // + struct SubtargetFeatureKV { + const char *Key; // K-V key string + uint32_t Value; // K-V integer value + + // Compare routine for std binary search + bool operator<(const std::string &S) const { + return strcmp(Key, S.c_str()) < 0; + } + }; + + //===----------------------------------------------------------------------===// + /// + /// SubtargetFeatures - Manages the enabling and disabling of subtarget + /// specific features. Features are encoded as a string of the form + /// "cpu,+attr1,+attr2,-attr3,...,+attrN" + /// A comma separates each feature from the next (all lowercase.) + /// The first feature is always the CPU subtype (eg. pentiumm). If the CPU + /// value is "generic" then the CPU subtype should be generic for the target. + /// Each of the remaining features is prefixed with + or - indicating whether + /// that feature should be enabled or disabled contrary to the cpu + /// specification. + /// + + class SubtargetFeatures { + private: + std::vector Features; // Subtarget features as a vector + + // Determine if a feature has a flag; '+' or '-' + static inline bool hasFlag(const std::string &Feature) { + assert(!Feature.empty() && "Empty string"); + // Get first character + char Ch = Feature[0]; + // Check if first character is '+' or '-' flag + return Ch == '+' || Ch =='-'; + } + + // Return true if enable flag; '+'. + static inline bool isEnabled(const std::string &Feature) { + assert(!Feature.empty() && "Empty string"); + // Get first character + char Ch = Feature[0]; + // Check if first character is '+' for enabled + return Ch == '+'; + } + + // Return a string with a prepended flag; '+' or '-'. + static inline std::string PrependFlag(const std::string &Feature, + bool IsEnabled) { + assert(!Feature.empty() && "Empty string"); + if (hasFlag(Feature)) return Feature; + return std::string(IsEnabled ? "+" : "-") + Feature; + } + + // Return string stripped of flag. + static inline std::string StripFlag(const std::string &Feature) { + return hasFlag(Feature) ? Feature.substr(1) : Feature; + } + + /// Splits a string of comma separated items in to a vector of strings. + static void Split(std::vector &V, const std::string &S); + + /// Join a vector of strings into a string with a comma separating each + /// item. + static std::string Join(const std::vector &V); + + /// Convert a string to lowercase. + static std::string toLower(const std::string &S); + + /// Find item in array using binary search. + static const SubtargetFeatureKV *Find(const std::string &S, + const SubtargetFeatureKV *A, size_t L); + + public: + /// Ctor. + SubtargetFeatures(const std::string Initial = std::string()) { + // Break up string into separate features + Split(Features, Initial); + } + + /// Features string accessors. + inline std::string getString() const { return Join(Features); } + void setString(const std::string &Initial) { + // Throw out old features + Features.clear(); + // Break up string into separate features + Split(Features, toLower(Initial)); + } + + /// Setting CPU string. Replaces previous setting. Setting to "" clears CPU. + void setCPU(std::string String) { Features[0] = toLower(String); } + + /// Adding Features. + void AddFeature(const std::string &String, bool IsEnabled = true); + + /// Parse feature string for quick usage. + static uint32_t Parse(const std::string &String, + const std::string &DefaultCPU, + const SubtargetFeatureKV *CPUTable, + size_t CPUTableSize, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize); + + /// Print feature string. + void print(std::ostream &OS) const; + + // Dump feature info. + void dump() const; + }; + + } // End namespace llvm + + #endif From jlaskey at apple.com Thu Sep 1 16:36:30 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:36:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SubtargetFeature.cpp Message-ID: <200509012136.QAA08967@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: SubtargetFeature.cpp added (r1.1) --- Log message: This new class provides support for platform specific "features". The intent is to manage processor specific attributes from the command line. See examples of use in llc/lli and PowerPCTargetSubtarget. --- Diffs of the changes: (+173 -0) SubtargetFeature.cpp | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 173 insertions(+) Index: llvm/lib/Target/SubtargetFeature.cpp diff -c /dev/null llvm/lib/Target/SubtargetFeature.cpp:1.1 *** /dev/null Thu Sep 1 16:36:28 2005 --- llvm/lib/Target/SubtargetFeature.cpp Thu Sep 1 16:36:18 2005 *************** *** 0 **** --- 1,173 ---- + //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Jim Laskey and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the SubtargetFeature interface. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Target/SubtargetFeature.h" + + #include + #include + #include + #include + + + using namespace llvm; + + /// Splits a string of comma separated items in to a vector of strings. + void SubtargetFeatures::Split(std::vector &V, + const std::string &S) { + // Start at beginning of string. + size_t Pos = 0; + while (true) { + // Find the next comma + size_t Comma = S.find(',', Pos); + // If no comma found then the the rest of the string is used + if (Comma == std::string::npos) { + // Add string to vector + V.push_back(S.substr(Pos)); + break; + } + // Otherwise add substring to vector + V.push_back(S.substr(Pos, Comma - Pos)); + // Advance to next item + Pos = Comma + 1; + } + } + + /// Join a vector of strings to a string with a comma separating each element. + std::string SubtargetFeatures::Join(const std::vector &V) { + // Start with empty string. + std::string Result; + // If the vector is not empty + if (!V.empty()) { + // Start with the CPU feature + Result = V[0]; + // For each successive feature + for (size_t i = 1; i < V.size(); i++) { + // Add a comma + Result += ","; + // Add the feature + Result += V[i]; + } + } + // Return the features string + return Result; + } + + /// Convert a string to lowercase. + std::string SubtargetFeatures::toLower(const std::string &S) { + // Copy the string + std::string Result = S; + // For each character in string + for (size_t i = 0; i < Result.size(); i++) { + // Convert character to lowercase + Result[i] = std::tolower(Result[i]); + } + // Return the lowercased string + return Result; + } + + /// Adding features. + void SubtargetFeatures::AddFeature(const std::string &String, + bool IsEnabled) { + // Don't add empty features + if (!String.empty()) { + // Convert to lowercase, prepend flag and add to vector + Features.push_back(PrependFlag(toLower(String), IsEnabled)); + } + } + + /// Find item in array using binary search. + const SubtargetFeatureKV * + SubtargetFeatures::Find(const std::string &S, + const SubtargetFeatureKV *A, size_t L) { + // Determine the end of the array + const SubtargetFeatureKV *Hi = A + L; + // Binary search the array + const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S); + // If not found then return NULL + if (F == Hi || std::string(F->Key) != S) return NULL; + // Return the found array item + return F; + } + + /// Parse feature string for quick usage. + uint32_t SubtargetFeatures::Parse(const std::string &String, + const std::string &DefaultCPU, + const SubtargetFeatureKV *CPUTable, + size_t CPUTableSize, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize) { + assert(CPUTable && "missing CPU table"); + assert(FeatureTable && "missing features table"); + #ifndef NDEBUG + for (size_t i = 1; i < CPUTableSize; i++) { + assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 && + "CPU table is not sorted"); + } + for (size_t i = 1; i < FeatureTableSize; i++) { + assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 && + "CPU features table is not sorted"); + } + #endif + std::vector Features; // Subtarget features as a vector + uint32_t Bits = 0; // Resulting bits + // Split up features + Split(Features, String); + // Check if default is needed + if (Features[0].empty()) Features[0] = DefaultCPU; + // Find CPU entry + const SubtargetFeatureKV *CPUEntry = + Find(Features[0], CPUTable, CPUTableSize); + // If there is a match + if (CPUEntry) { + // Set base feature bits + Bits = CPUEntry->Value; + } else { + std::cerr << Features[0] + << " is not a recognized processor for this target" + << " (ignoring processor)" + << "\n"; + } + // Iterate through each feature + for (size_t i = 1; i < Features.size(); i++) { + // Get next feature + const std::string &Feature = Features[i]; + // Find feature in table. + const SubtargetFeatureKV *FeatureEntry = + Find(StripFlag(Feature), FeatureTable, FeatureTableSize); + // If there is a match + if (FeatureEntry) { + // Enable/disable feature in bits + if (isEnabled(Feature)) Bits |= FeatureEntry->Value; + else Bits &= ~FeatureEntry->Value; + } else { + std::cerr << Feature + << " is not a recognized feature for this target" + << " (ignoring feature)" + << "\n"; + } + } + return Bits; + } + + /// Print feature string. + void SubtargetFeatures::print(std::ostream &OS) const { + for (size_t i = 0; i < Features.size(); i++) { + OS << Features[i] << " "; + } + OS << "\n"; + } + + /// Dump feature info. + void SubtargetFeatures::dump() const { + print(std::cerr); + } From jlaskey at apple.com Thu Sep 1 16:38:36 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp SparcV9TargetMachine.h Message-ID: <200509012138.QAA09082@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TargetMachine.cpp updated: 1.141 -> 1.142 SparcV9TargetMachine.h updated: 1.13 -> 1.14 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+4 -2) SparcV9TargetMachine.cpp | 3 ++- SparcV9TargetMachine.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.141 llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.142 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.141 Fri Aug 19 11:56:56 2005 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Thu Sep 1 16:38:21 2005 @@ -148,7 +148,8 @@ SparcV9TargetMachine::SparcV9TargetMachine(const Module &M, - IntrinsicLowering *il) + IntrinsicLowering *il, + const std::string &FS) : TargetMachine("UltraSparcV9-Native", il, false), schedInfo(*this), regInfo(*this), Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.h diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.h:1.13 llvm/lib/Target/SparcV9/SparcV9TargetMachine.h:1.14 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.h:1.13 Fri Jun 24 21:48:37 2005 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.h Thu Sep 1 16:38:21 2005 @@ -32,7 +32,8 @@ SparcV9FrameInfo frameInfo; SparcV9JITInfo jitInfo; public: - SparcV9TargetMachine(const Module &M, IntrinsicLowering *IL); + SparcV9TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const TargetInstrInfo *getInstrInfo() const { return &instrInfo; } virtual const TargetSchedInfo *getSchedInfo() const { return &schedInfo; } From jlaskey at apple.com Thu Sep 1 16:38:37 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:37 -0500 Subject: [llvm-commits] CVS: llvm/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200509012138.QAA09090@zion.cs.uiuc.edu> Changes in directory llvm/Xcode/LLVM.xcodeproj: project.pbxproj updated: 1.6 -> 1.7 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+5 -1) project.pbxproj | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/Xcode/LLVM.xcodeproj/project.pbxproj diff -u llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.6 llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.7 --- llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.6 Thu Aug 25 11:44:13 2005 +++ llvm/Xcode/LLVM.xcodeproj/project.pbxproj Thu Sep 1 16:38:20 2005 @@ -33,6 +33,8 @@ /* End PBXBuildStyle section */ /* Begin PBXFileReference section */ + CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetFeature.h; sourceTree = ""; }; + CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetFeature.cpp; sourceTree = ""; }; DE66EC5B08ABE86900323D32 /* AsmWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AsmWriter.cpp; path = ../lib/VMCore/AsmWriter.cpp; sourceTree = SOURCE_ROOT; }; DE66EC5C08ABE86A00323D32 /* BasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BasicBlock.cpp; path = ../lib/VMCore/BasicBlock.cpp; sourceTree = SOURCE_ROOT; }; DE66EC5D08ABE86A00323D32 /* ConstantFolding.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ConstantFolding.cpp; path = ../lib/VMCore/ConstantFolding.cpp; sourceTree = SOURCE_ROOT; }; @@ -1249,6 +1251,7 @@ DE66EFC908ABEE5F00323D32 /* SparcV9 */, DE66F09308ABEE6000323D32 /* X86 */, DE66EF1008ABEE5E00323D32 /* MRegisterInfo.cpp */, + CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */, DE66F08A08ABEE6000323D32 /* Target.td */, DE66F08B08ABEE6000323D32 /* TargetData.cpp */, DE66F08C08ABEE6000323D32 /* TargetFrameInfo.cpp */, @@ -1958,6 +1961,7 @@ isa = PBXGroup; children = ( DE66F2A008ABF03200323D32 /* MRegisterInfo.h */, + CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */, DE66F2A108ABF03200323D32 /* TargetData.h */, DE66F2A208ABF03200323D32 /* TargetFrameInfo.h */, DE66F2A308ABF03200323D32 /* TargetInstrInfo.h */, @@ -2218,7 +2222,7 @@ PRODUCT_NAME = LLVM; }; buildToolPath = /usr/bin/make; - buildWorkingDirectory = /llvm/obj; + buildWorkingDirectory = /llvm/obj/; dependencies = ( ); name = LLVM; From jlaskey at apple.com Thu Sep 1 16:38:37 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Message-ID: <200509012138.QAA09097@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: TargetSelect.cpp updated: 1.7 -> 1.8 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+24 -1) TargetSelect.cpp | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) Index: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp diff -u llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.7 llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.8 --- llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.7 Thu Apr 21 17:45:04 2005 +++ llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Thu Sep 1 16:38:20 2005 @@ -15,6 +15,7 @@ #include "JIT.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" +#include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachineRegistry.h" #include @@ -23,6 +24,18 @@ static cl::opt MArch("march", cl::desc("Architecture to generate assembly for:")); +static cl::opt +MCPU("mcpu", + cl::desc("Target a specific cpu type"), + cl::value_desc("cpu-name"), + cl::init("")); + +static cl::list +MAttrs("mattr", + cl::CommaSeparated, + cl::desc("Target specific attributes:"), + cl::value_desc("attributes")); + /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// @@ -37,8 +50,18 @@ << "-march switch.\n"; } + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (MCPU.size() || MAttrs.size()) { + SubtargetFeatures Features; + Features.setCPU(MCPU); + for (unsigned i = 0; i != MAttrs.size(); ++i) + Features.AddFeature(MAttrs[i]); + FeaturesStr = Features.getString(); + } + // Allocate a target... - TargetMachine *Target = MArch->CtorFn(*MP->getModule(), IL); + TargetMachine *Target = MArch->CtorFn(*MP->getModule(), IL, FeaturesStr); assert(Target && "Could not allocate target machine!"); // If the target supports JIT code generation, return a new JIT now. From jlaskey at apple.com Thu Sep 1 16:38:37 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp AlphaTargetMachine.h Message-ID: <200509012138.QAA09089@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaTargetMachine.cpp updated: 1.11 -> 1.12 AlphaTargetMachine.h updated: 1.8 -> 1.9 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+4 -2) AlphaTargetMachine.cpp | 3 ++- AlphaTargetMachine.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.11 llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.12 --- llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.11 Wed Aug 3 17:33:21 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Thu Sep 1 16:38:20 2005 @@ -58,7 +58,8 @@ #endif } -AlphaTargetMachine::AlphaTargetMachine( const Module &M, IntrinsicLowering *IL) +AlphaTargetMachine::AlphaTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS) : TargetMachine("alpha", IL, true), FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), JITInfo(*this) Index: llvm/lib/Target/Alpha/AlphaTargetMachine.h diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.8 llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.9 --- llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.8 Fri Jul 22 15:52:16 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.h Thu Sep 1 16:38:20 2005 @@ -31,7 +31,8 @@ AlphaJITInfo JITInfo; public: - AlphaTargetMachine(const Module &M, IntrinsicLowering *IL); + AlphaTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const AlphaInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200509012138.QAA09140@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.111 -> 1.112 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+24 -1) llc.cpp | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.111 llvm/tools/llc/llc.cpp:1.112 --- llvm/tools/llc/llc.cpp:1.111 Sat Jul 30 13:33:25 2005 +++ llvm/tools/llc/llc.cpp Thu Sep 1 16:38:21 2005 @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Bytecode/Reader.h" +#include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Transforms/Scalar.h" @@ -47,6 +48,18 @@ static cl::opt MArch("march", cl::desc("Architecture to generate code for:")); +static cl::opt +MCPU("mcpu", + cl::desc("Target a specific cpu type"), + cl::value_desc("cpu-name"), + cl::init("")); + +static cl::list +MAttrs("mattr", + cl::CommaSeparated, + cl::desc("Target specific attributes:"), + cl::value_desc("attributes")); + cl::opt FileType("filetype", cl::init(TargetMachine::AssemblyFile), cl::desc("Choose a file type (not all types are supported by all targets):"), @@ -114,7 +127,17 @@ } } - std::auto_ptr target(MArch->CtorFn(mod, 0)); + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (MCPU.size() || MAttrs.size()) { + SubtargetFeatures Features; + Features.setCPU(MCPU); + for (unsigned i = 0; i != MAttrs.size(); ++i) + Features.AddFeature(MAttrs[i]); + FeaturesStr = Features.getString(); + } + + std::auto_ptr target(MArch->CtorFn(mod, 0, FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); const TargetData &TD = Target.getTargetData(); From jlaskey at apple.com Thu Sep 1 16:38:37 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:37 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachineRegistry.h Message-ID: <200509012138.QAA09108@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachineRegistry.h updated: 1.5 -> 1.6 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+7 -4) TargetMachineRegistry.h | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) Index: llvm/include/llvm/Target/TargetMachineRegistry.h diff -u llvm/include/llvm/Target/TargetMachineRegistry.h:1.5 llvm/include/llvm/Target/TargetMachineRegistry.h:1.6 --- llvm/include/llvm/Target/TargetMachineRegistry.h:1.5 Thu Apr 21 15:53:44 2005 +++ llvm/include/llvm/Target/TargetMachineRegistry.h Thu Sep 1 16:38:20 2005 @@ -49,7 +49,8 @@ struct Entry { const char *Name; const char *ShortDesc; - TargetMachine *(*CtorFn)(const Module &, IntrinsicLowering*); + TargetMachine *(*CtorFn)(const Module &, IntrinsicLowering*, + const std::string &); unsigned (*ModuleMatchQualityFn)(const Module &M); unsigned (*JITMatchQualityFn)(); @@ -57,7 +58,8 @@ protected: Entry(const char *N, const char *SD, - TargetMachine *(*CF)(const Module &, IntrinsicLowering*), + TargetMachine *(*CF)(const Module &, IntrinsicLowering*, + const std::string &), unsigned (*MMF)(const Module &M), unsigned (*JMF)()); private: const Entry *Next; // Next entry in the linked list. @@ -80,8 +82,9 @@ &TargetMachineImpl::getJITMatchQuality) { } private: - static TargetMachine *Allocator(const Module &M, IntrinsicLowering *IL) { - return new TargetMachineImpl(M, IL); + static TargetMachine *Allocator(const Module &M, IntrinsicLowering *IL, + const std::string &FS) { + return new TargetMachineImpl(M, IL, FS); } }; From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp SkeletonTargetMachine.h Message-ID: <200509012138.QAA09146@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Skeleton: SkeletonTargetMachine.cpp updated: 1.4 -> 1.5 SkeletonTargetMachine.h updated: 1.3 -> 1.4 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+4 -2) SkeletonTargetMachine.cpp | 3 ++- SkeletonTargetMachine.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp diff -u llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp:1.4 llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp:1.5 --- llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp:1.4 Fri Jun 24 21:48:37 2005 +++ llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp Thu Sep 1 16:38:21 2005 @@ -29,7 +29,8 @@ /// SkeletonTargetMachine ctor - Create an ILP32 architecture model /// SkeletonTargetMachine::SkeletonTargetMachine(const Module &M, - IntrinsicLowering *IL) + IntrinsicLowering *IL, + const std::string &FS) : TargetMachine("Skeleton", IL, true, 4, 4, 4, 4, 4), FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -4), JITInfo(*this) { } Index: llvm/lib/Target/Skeleton/SkeletonTargetMachine.h diff -u llvm/lib/Target/Skeleton/SkeletonTargetMachine.h:1.3 llvm/lib/Target/Skeleton/SkeletonTargetMachine.h:1.4 --- llvm/lib/Target/Skeleton/SkeletonTargetMachine.h:1.3 Fri Jun 24 21:48:37 2005 +++ llvm/lib/Target/Skeleton/SkeletonTargetMachine.h Thu Sep 1 16:38:21 2005 @@ -28,7 +28,8 @@ TargetFrameInfo FrameInfo; SkeletonJITInfo JITInfo; public: - SkeletonTargetMachine(const Module &M, IntrinsicLowering *IL); + SkeletonTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const SkeletonInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32TargetMachine.h PowerPCSubtarget.cpp PowerPCSubtarget.h PowerPCTargetMachine.cpp PowerPCTargetMachine.h Message-ID: <200509012138.QAA09130@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32TargetMachine.h updated: 1.7 -> 1.8 PowerPCSubtarget.cpp updated: 1.3 -> 1.4 PowerPCSubtarget.h updated: 1.2 -> 1.3 PowerPCTargetMachine.cpp updated: 1.65 -> 1.66 PowerPCTargetMachine.h updated: 1.14 -> 1.15 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+94 -16) PPC32TargetMachine.h | 3 + PowerPCSubtarget.cpp | 92 +++++++++++++++++++++++++++++++++++++++++------ PowerPCSubtarget.h | 4 +- PowerPCTargetMachine.cpp | 8 ++-- PowerPCTargetMachine.h | 3 + 5 files changed, 94 insertions(+), 16 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32TargetMachine.h diff -u llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.7 llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.8 --- llvm/lib/Target/PowerPC/PPC32TargetMachine.h:1.7 Thu Apr 21 18:20:02 2005 +++ llvm/lib/Target/PowerPC/PPC32TargetMachine.h Thu Sep 1 16:38:20 2005 @@ -28,7 +28,8 @@ PPC32JITInfo JITInfo; public: - PPC32TargetMachine(const Module &M, IntrinsicLowering *IL); + PPC32TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const PPC32InstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.3 llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.4 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.3 Fri Aug 5 17:05:03 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Thu Sep 1 16:38:21 2005 @@ -15,6 +15,8 @@ #include "PowerPC.h" #include "llvm/Module.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Target/SubtargetFeature.h" + using namespace llvm; PPCTargetEnum llvm::PPCTarget = TargetDefault; @@ -30,42 +32,112 @@ cl::desc("Enable optimizations for GP cpus")); } +enum PowerPCFeature { + PowerPCFeature64Bit = 1 << 0, + PowerPCFeatureAltivec = 1 << 1, + PowerPCFeatureFSqrt = 1 << 2, + PowerPCFeatureGPUL = 1 << 3, +}; + +/// Sorted (by key) array of values for CPU subtype. +static const SubtargetFeatureKV PowerPCSubTypeKV[] = { + { "601" , 0 }, + { "602" , 0 }, + { "603" , 0 }, + { "603e" , 0 }, + { "603ev" , 0 }, + { "604" , 0 }, + { "604e" , 0 }, + { "620" , 0 }, + { "7400" , PowerPCFeatureAltivec }, + { "7450" , PowerPCFeatureAltivec }, + { "750" , 0 }, + { "970" , PowerPCFeature64Bit | PowerPCFeatureAltivec | + PowerPCFeatureFSqrt | PowerPCFeatureGPUL }, + { "g3" , 0 }, + { "g4" , PowerPCFeatureAltivec }, + { "g4+" , PowerPCFeatureAltivec }, + { "g5" , PowerPCFeature64Bit | PowerPCFeatureAltivec | + PowerPCFeatureFSqrt | PowerPCFeatureGPUL }, + { "generic", 0 } +}; +/// Length of PowerPCSubTypeKV. +static const unsigned PowerPCSubTypeKVSize = sizeof(PowerPCSubTypeKV) + / sizeof(SubtargetFeatureKV); + +/// Sorted (by key) array of values for CPU features. +static SubtargetFeatureKV PowerPCFeatureKV[] = { + { "64bit" , PowerPCFeature64Bit }, + { "altivec", PowerPCFeatureAltivec }, + { "fsqrt" , PowerPCFeatureFSqrt }, + { "gpul" , PowerPCFeatureGPUL } + }; +/// Length of PowerPCFeatureKV. +static const unsigned PowerPCFeatureKVSize = sizeof(PowerPCFeatureKV) + / sizeof(SubtargetFeatureKV); + + #if defined(__APPLE__) #include #include #include #include -static boolean_t IsGP() { +/// GetCurrentPowerPCFeatures - Returns the current CPUs features. +static const char *GetCurrentPowerPCCPU() { host_basic_info_data_t hostInfo; mach_msg_type_number_t infoCount; infoCount = HOST_BASIC_INFO_COUNT; host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount); + + if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic"; + + switch(hostInfo.cpu_subtype) { + case CPU_SUBTYPE_POWERPC_601: return "601"; + case CPU_SUBTYPE_POWERPC_602: return "602"; + case CPU_SUBTYPE_POWERPC_603: return "603"; + case CPU_SUBTYPE_POWERPC_603e: return "603e"; + case CPU_SUBTYPE_POWERPC_603ev: return "603ev"; + case CPU_SUBTYPE_POWERPC_604: return "604"; + case CPU_SUBTYPE_POWERPC_604e: return "604e"; + case CPU_SUBTYPE_POWERPC_620: return "620"; + case CPU_SUBTYPE_POWERPC_750: return "750"; + case CPU_SUBTYPE_POWERPC_7400: return "7400"; + case CPU_SUBTYPE_POWERPC_7450: return "7450"; + case CPU_SUBTYPE_POWERPC_970: return "970"; + default: ; + } - return ((hostInfo.cpu_type == CPU_TYPE_POWERPC) && - (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970)); -} + return "generic"; +} #endif -PPCSubtarget::PPCSubtarget(const Module &M) +PPCSubtarget::PPCSubtarget(const Module &M, const std::string &FS) : StackAlignment(16), IsGigaProcessor(false), IsAIX(false), IsDarwin(false) { - // Set the boolean corresponding to the current target triple, or the default + // Determine default and user specified characteristics + std::string CPU; +#if defined(__APPLE__) + CPU = GetCurrentPowerPCCPU(); +#endif + uint32_t Bits = + SubtargetFeatures::Parse(FS, CPU, + PowerPCSubTypeKV, PowerPCSubTypeKVSize, + PowerPCFeatureKV, PowerPCFeatureKVSize); + IsGigaProcessor = (Bits & PowerPCFeatureGPUL) != 0; + + // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. const std::string& TT = M.getTargetTriple(); if (TT.length() > 5) { IsDarwin = TT.find("darwin") != std::string::npos; -#if defined(__APPLE__) - IsGigaProcessor = IsGP(); -#endif } else if (TT.empty()) { #if defined(_POWER) IsAIX = true; #elif defined(__APPLE__) IsDarwin = true; - IsGigaProcessor = IsGP(); #endif } Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.2 llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.3 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.2 Fri Aug 5 17:05:03 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.h Thu Sep 1 16:38:21 2005 @@ -16,6 +16,8 @@ #include "llvm/Target/TargetSubtarget.h" +#include + namespace llvm { class Module; @@ -33,7 +35,7 @@ /// This constructor initializes the data members to match that /// of the specified module. /// - PPCSubtarget(const Module &M); + PPCSubtarget(const Module &M, const std::string &FS); /// getStackAlignment - Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.65 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.66 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.65 Thu Aug 18 18:53:15 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Thu Sep 1 16:38:21 2005 @@ -43,9 +43,10 @@ PowerPCTargetMachine::PowerPCTargetMachine(const std::string &name, IntrinsicLowering *IL, const Module &M, + const std::string &FS, const TargetData &TD, const PowerPCFrameInfo &TFI) -: TargetMachine(name, IL, TD), FrameInfo(TFI), Subtarget(M) { +: TargetMachine(name, IL, TD), FrameInfo(TFI), Subtarget(M, FS) { if (TargetDefault == PPCTarget) { if (Subtarget.isAIX()) PPCTarget = TargetAIX; if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; @@ -154,8 +155,9 @@ /// PowerPCTargetMachine ctor - Create an ILP32 architecture model /// -PPC32TargetMachine::PPC32TargetMachine(const Module &M, IntrinsicLowering *IL) - : PowerPCTargetMachine(PPC32ID, IL, M, +PPC32TargetMachine::PPC32TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS) + : PowerPCTargetMachine(PPC32ID, IL, M, FS, TargetData(PPC32ID,false,4,4,4,4,4,4,2,1,1), PowerPCFrameInfo(*this, false)), JITInfo(*this) {} Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.h:1.14 llvm/lib/Target/PowerPC/PowerPCTargetMachine.h:1.15 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.h:1.14 Thu Aug 4 02:12:08 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.h Thu Sep 1 16:38:21 2005 @@ -30,7 +30,8 @@ PPCSubtarget Subtarget; protected: PowerPCTargetMachine(const std::string &name, IntrinsicLowering *IL, - const Module &M, const TargetData &TD, + const Module &M, const std::string &FS, + const TargetData &TD, const PowerPCFrameInfo &TFI); public: virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachineRegistry.cpp Message-ID: <200509012138.QAA09132@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachineRegistry.cpp updated: 1.4 -> 1.5 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+2 -1) TargetMachineRegistry.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/TargetMachineRegistry.cpp diff -u llvm/lib/Target/TargetMachineRegistry.cpp:1.4 llvm/lib/Target/TargetMachineRegistry.cpp:1.5 --- llvm/lib/Target/TargetMachineRegistry.cpp:1.4 Thu Apr 21 17:55:34 2005 +++ llvm/lib/Target/TargetMachineRegistry.cpp Thu Sep 1 16:38:20 2005 @@ -26,7 +26,8 @@ static TargetRegistrationListener *Listeners = 0; TargetMachineRegistry::Entry::Entry(const char *N, const char *SD, - TargetMachine *(*CF)(const Module &, IntrinsicLowering*), + TargetMachine *(*CF)(const Module &, IntrinsicLowering*, + const std::string &), unsigned (*MMF)(const Module &M), unsigned (*JMF)()) : Name(N), ShortDesc(SD), CtorFn(CF), ModuleMatchQualityFn(MMF), JITMatchQualityFn(JMF), Next(List) { From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/CTargetMachine.h Message-ID: <200509012138.QAA09110@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: CTargetMachine.h updated: 1.7 -> 1.8 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+2 -1) CTargetMachine.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/CBackend/CTargetMachine.h diff -u llvm/lib/Target/CBackend/CTargetMachine.h:1.7 llvm/lib/Target/CBackend/CTargetMachine.h:1.8 --- llvm/lib/Target/CBackend/CTargetMachine.h:1.7 Fri Jun 24 21:48:36 2005 +++ llvm/lib/Target/CBackend/CTargetMachine.h Thu Sep 1 16:38:20 2005 @@ -20,7 +20,8 @@ class IntrinsicLowering; struct CTargetMachine : public TargetMachine { - CTargetMachine(const Module &M, IntrinsicLowering *IL) : + CTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS) : TargetMachine("CBackend", IL, M) {} // This is the only thing that actually does anything here. From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64TargetMachine.cpp IA64TargetMachine.h Message-ID: <200509012138.QAA09152@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64TargetMachine.cpp updated: 1.4 -> 1.5 IA64TargetMachine.h updated: 1.3 -> 1.4 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+4 -2) IA64TargetMachine.cpp | 3 ++- IA64TargetMachine.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/IA64/IA64TargetMachine.cpp diff -u llvm/lib/Target/IA64/IA64TargetMachine.cpp:1.4 llvm/lib/Target/IA64/IA64TargetMachine.cpp:1.5 --- llvm/lib/Target/IA64/IA64TargetMachine.cpp:1.4 Fri Jun 24 21:48:36 2005 +++ llvm/lib/Target/IA64/IA64TargetMachine.cpp Thu Sep 1 16:38:20 2005 @@ -72,7 +72,8 @@ /// IA64TargetMachine ctor - Create an LP64 architecture model /// -IA64TargetMachine::IA64TargetMachine(const Module &M, IntrinsicLowering *IL) +IA64TargetMachine::IA64TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS) : TargetMachine("IA64", IL, true), FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0) { // FIXME? check this stuff } Index: llvm/lib/Target/IA64/IA64TargetMachine.h diff -u llvm/lib/Target/IA64/IA64TargetMachine.h:1.3 llvm/lib/Target/IA64/IA64TargetMachine.h:1.4 --- llvm/lib/Target/IA64/IA64TargetMachine.h:1.3 Fri Jun 24 21:48:36 2005 +++ llvm/lib/Target/IA64/IA64TargetMachine.h Thu Sep 1 16:38:20 2005 @@ -27,7 +27,8 @@ TargetFrameInfo FrameInfo; //IA64JITInfo JITInfo; public: - IA64TargetMachine(const Module &M, IntrinsicLowering *IL); + IA64TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const IA64InstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp SparcV8TargetMachine.h Message-ID: <200509012138.QAA09125@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8TargetMachine.cpp updated: 1.28 -> 1.29 SparcV8TargetMachine.h updated: 1.6 -> 1.7 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+4 -2) SparcV8TargetMachine.cpp | 3 ++- SparcV8TargetMachine.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp diff -u llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.28 llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.29 --- llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.28 Fri Jun 24 21:48:37 2005 +++ llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp Thu Sep 1 16:38:21 2005 @@ -31,7 +31,8 @@ /// SparcV8TargetMachine ctor - Create an ILP32 architecture model /// SparcV8TargetMachine::SparcV8TargetMachine(const Module &M, - IntrinsicLowering *IL) + IntrinsicLowering *IL, + const std::string &FS) : TargetMachine("SparcV8", IL, false, 4, 4), FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0), JITInfo(*this) { } Index: llvm/lib/Target/SparcV8/SparcV8TargetMachine.h diff -u llvm/lib/Target/SparcV8/SparcV8TargetMachine.h:1.6 llvm/lib/Target/SparcV8/SparcV8TargetMachine.h:1.7 --- llvm/lib/Target/SparcV8/SparcV8TargetMachine.h:1.6 Fri Jun 24 21:48:37 2005 +++ llvm/lib/Target/SparcV8/SparcV8TargetMachine.h Thu Sep 1 16:38:21 2005 @@ -30,7 +30,8 @@ TargetFrameInfo FrameInfo; SparcV8JITInfo JITInfo; public: - SparcV8TargetMachine(const Module &M, IntrinsicLowering *IL); + SparcV8TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const SparcV8InstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } From jlaskey at apple.com Thu Sep 1 16:38:38 2005 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 1 Sep 2005 16:38:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86Subtarget.cpp X86Subtarget.h X86TargetMachine.cpp X86TargetMachine.h Message-ID: <200509012138.QAA09106@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86Subtarget.cpp updated: 1.5 -> 1.6 X86Subtarget.h updated: 1.4 -> 1.5 X86TargetMachine.cpp updated: 1.85 -> 1.86 X86TargetMachine.h updated: 1.29 -> 1.30 --- Log message: 1. Use SubtargetFeatures in llc/lli. 2. Propagate feature "string" to all targets. 3. Implement use of SubtargetFeatures in PowerPCTargetSubtarget. --- Diffs of the changes: (+10 -5) X86Subtarget.cpp | 2 +- X86Subtarget.h | 4 +++- X86TargetMachine.cpp | 6 ++++-- X86TargetMachine.h | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) Index: llvm/lib/Target/X86/X86Subtarget.cpp diff -u llvm/lib/Target/X86/X86Subtarget.cpp:1.5 llvm/lib/Target/X86/X86Subtarget.cpp:1.6 --- llvm/lib/Target/X86/X86Subtarget.cpp:1.5 Thu Aug 4 02:12:09 2005 +++ llvm/lib/Target/X86/X86Subtarget.cpp Thu Sep 1 16:38:21 2005 @@ -15,7 +15,7 @@ #include "llvm/Module.h" using namespace llvm; -X86Subtarget::X86Subtarget(const Module &M) +X86Subtarget::X86Subtarget(const Module &M, const std::string &FS) : TargetSubtarget(), stackAlignment(8), indirectExternAndWeakGlobals(false), asmDarwinLinkerStubs(false), asmLeadingUnderscore(false), asmAlignmentIsInBytes(false), Index: llvm/lib/Target/X86/X86Subtarget.h diff -u llvm/lib/Target/X86/X86Subtarget.h:1.4 llvm/lib/Target/X86/X86Subtarget.h:1.5 --- llvm/lib/Target/X86/X86Subtarget.h:1.4 Thu Aug 4 02:12:09 2005 +++ llvm/lib/Target/X86/X86Subtarget.h Thu Sep 1 16:38:21 2005 @@ -16,6 +16,8 @@ #include "llvm/Target/TargetSubtarget.h" +#include + namespace llvm { class Module; @@ -39,7 +41,7 @@ /// This constructor initializes the data members to match that /// of the specified module. /// - X86Subtarget(const Module &M); + X86Subtarget(const Module &M, const std::string &FS); /// getStackAlignment - Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.85 llvm/lib/Target/X86/X86TargetMachine.cpp:1.86 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.85 Thu Aug 18 18:53:15 2005 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Thu Sep 1 16:38:21 2005 @@ -90,9 +90,11 @@ /// X86TargetMachine ctor - Create an ILP32 architecture model /// -X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *IL) +X86TargetMachine::X86TargetMachine(const Module &M, + IntrinsicLowering *IL, + const std::string &FS) : TargetMachine("X86", IL, true, 4, 4, 4, 4, 4), - Subtarget(M), + Subtarget(M, FS), FrameInfo(TargetFrameInfo::StackGrowsDown, Subtarget.getStackAlignment(), -4), JITInfo(*this) { Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.29 llvm/lib/Target/X86/X86TargetMachine.h:1.30 --- llvm/lib/Target/X86/X86TargetMachine.h:1.29 Mon Jul 11 20:41:54 2005 +++ llvm/lib/Target/X86/X86TargetMachine.h Thu Sep 1 16:38:21 2005 @@ -30,7 +30,8 @@ TargetFrameInfo FrameInfo; X86JITInfo JITInfo; public: - X86TargetMachine(const Module &M, IntrinsicLowering *IL); + X86TargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); virtual const X86InstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } From lattner at cs.uiuc.edu Thu Sep 1 16:48:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 16:48:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200509012148.QAA09350@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.89 -> 1.90 --- Log message: Local labels on darwin apparently start with just 'L', not .L like other platforms. This reduces executable size and makes shark realize the actual bounds of functions instead of showing each MBB as a function :) --- Diffs of the changes: (+2 -2) PowerPCAsmPrinter.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.89 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.90 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.89 Fri Aug 26 17:04:17 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Thu Sep 1 16:48:35 2005 @@ -283,7 +283,7 @@ case MachineOperand::MO_MachineBasicBlock: { MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) + O << "LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) << "_" << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName(); return; @@ -393,7 +393,7 @@ I != E; ++I) { // Print a label for the basic block. if (I != MF.begin()) { - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"; + O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"; if (!I->getBasicBlock()->getName().empty()) O << CommentString << " " << I->getBasicBlock()->getName(); O << "\n"; From lattner at cs.uiuc.edu Thu Sep 1 17:05:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 17:05:08 -0500 Subject: [llvm-commits] CVS: llvm-www/ProjectsWithLLVM/index.html Message-ID: <200509012205.RAA09688@zion.cs.uiuc.edu> Changes in directory llvm-www/ProjectsWithLLVM: index.html updated: 1.24 -> 1.25 --- Log message: Add a blurb about pypy --- Diffs of the changes: (+27 -0) index.html | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm-www/ProjectsWithLLVM/index.html diff -u llvm-www/ProjectsWithLLVM/index.html:1.24 llvm-www/ProjectsWithLLVM/index.html:1.25 --- llvm-www/ProjectsWithLLVM/index.html:1.24 Sun May 29 21:30:03 2005 +++ llvm-www/ProjectsWithLLVM/index.html Thu Sep 1 17:04:56 2005 @@ -35,6 +35,7 @@ + + + + +
+By Eric van Riet Paap and the PyPy Team +
+ +
+

+The PyPy Project is a reimplementation +of Python written in Python itself, +that is flexible and easy to experiment with. Our + long-term goals are to target a large variety of platforms, small and large, +by providing a compiler toolsuite that can produce custom Python versions. +Platform, Memory and Threading models are to become aspects of the translation +process - as opposed to encoding low level details into a language +implementation itself. Eventually, dynamic optimization techniques - +implemented as another translation aspect - should become robust against +language changes.

+ +

At the time of this writing, PyPy currently targets LLVM and C.

+ +
From lattner at cs.uiuc.edu Thu Sep 1 18:06:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 18:06:02 -0500 Subject: [llvm-commits] CVS: llvm-www/Developers.html Message-ID: <200509012306.SAA10094@zion.cs.uiuc.edu> Changes in directory llvm-www: Developers.html updated: 1.29 -> 1.30 --- Log message: add henrik, upon request --- Diffs of the changes: (+13 -14) Developers.html | 27 +++++++++++++-------------- 1 files changed, 13 insertions(+), 14 deletions(-) Index: llvm-www/Developers.html diff -u llvm-www/Developers.html:1.29 llvm-www/Developers.html:1.30 --- llvm-www/Developers.html:1.29 Tue May 17 11:53:58 2005 +++ llvm-www/Developers.html Thu Sep 1 18:05:51 2005 @@ -11,7 +11,7 @@ Name Picture -   +   Name Picture @@ -19,13 +19,23 @@ Vikram Adve vadve + alt="vadve"/> + Brian Gaeke + + brg + + + + Henrik Bach + + Henrik Brad Jones KungFooMaster - @@ -96,17 +106,6 @@ Bill Wendling Bill - - - - - Brian Gaeke - - brg - - - From lattner at cs.uiuc.edu Thu Sep 1 18:06:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 18:06:04 -0500 Subject: [llvm-commits] CVS: llvm-www/img/PhotoHenrik.jpg Message-ID: <200509012306.SAA10101@zion.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoHenrik.jpg added (r1.1) --- Log message: add henrik, upon request --- Diffs of the changes: (+0 -0) PhotoHenrik.jpg | 0 1 files changed Index: llvm-www/img/PhotoHenrik.jpg From lattner at cs.uiuc.edu Thu Sep 1 18:09:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 18:09:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200509012309.SAA10161@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.90 -> 1.91 --- Log message: Align functions to 16-byte boundaries, to eliminate noise in performance measurements. This improves the performance of 'treeadd' by about 20% with the dag isel, restoring it to the pattern-isel level (which happens to get the alignment right). --- Diffs of the changes: (+1 -1) PowerPCAsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.90 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.91 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.90 Thu Sep 1 16:48:35 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Thu Sep 1 18:08:50 2005 @@ -384,7 +384,7 @@ // Print out labels for the function. O << "\t.text\n"; - emitAlignment(2); + emitAlignment(4); O << "\t.globl\t" << CurrentFnName << "\n"; O << CurrentFnName << ":\n"; From natebegeman at mac.com Thu Sep 1 18:24:15 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 1 Sep 2005 18:24:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509012324.SAA10202@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.2 -> 1.3 --- Log message: Implement first round of feedback from chris (there's still a couple things left to do). --- Diffs of the changes: (+137 -201) DAGCombiner.cpp | 338 ++++++++++++++++++++++---------------------------------- 1 files changed, 137 insertions(+), 201 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.2 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.3 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.2 Wed Aug 31 19:33:32 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Sep 1 18:24:04 2005 @@ -1,4 +1,4 @@ -//===-- DAGCombiner.cpp - Implement a trivial DAG combiner ----------------===// +//===-- DAGCombiner.cpp - Implement a DAG node combiner -------------------===// // // The LLVM Compiler Infrastructure // @@ -21,10 +21,16 @@ // we don't have yet. // // FIXME: mul (x, const) -> shifts + adds -// // FIXME: undef values -// // FIXME: zero extend when top bits are 0 -> drop it ? +// FIXME: make truncate see through SIGN_EXTEND and AND +// FIXME: sext_in_reg(setcc) on targets that return zero or one, and where +// EVT != MVT::i1 can drop the sext. +// FIXME: (or x, c) -> c iff maskedValueIsZero(x, ~c) +// FIXME: MaskedValueIsZero can see through SRL, so it should be sufficient to: +//if (N2C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) +// return DAG.getConstant(0, VT).Val; +// FIXME: (sra (sra x, c1), c2) -> (sra x, c1+c2) // //===----------------------------------------------------------------------===// @@ -42,6 +48,7 @@ class DAGCombiner { SelectionDAG &DAG; TargetLowering &TLI; + bool AfterLegalize; // Worklist of all of the nodes that need to be simplified. std::vector WorkList; @@ -52,11 +59,8 @@ /// void AddUsersToWorkList(SDNode *N) { for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); - UI != UE; ++UI) { - SDNode *U = *UI; - for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) - WorkList.push_back(U->getOperand(i).Val); - } + UI != UE; ++UI) + WorkList.push_back(*UI); } /// removeFromWorkList - remove all instances of N from the worklist. @@ -120,13 +124,13 @@ // brtwoway_cc public: DAGCombiner(SelectionDAG &D) - : DAG(D), TLI(D.getTargetLoweringInfo()) { + : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) { // Add all the dag nodes to the worklist. WorkList.insert(WorkList.end(), D.allnodes_begin(), D.allnodes_end()); } /// Run - runs the dag combiner on all nodes in the work list - void Run(bool AfterLegalize); + void Run(bool RunningAfterLegalize); }; } @@ -140,79 +144,69 @@ // If we know the result of a setcc has the top bits zero, use this info. switch (Op.getOpcode()) { - case ISD::Constant: - return (cast(Op)->getValue() & Mask) == 0; - - case ISD::SETCC: - return ((Mask & 1) == 0) && - TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; - - case ISD::ZEXTLOAD: - SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); - return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. - case ISD::ZERO_EXTEND: - case ISD::AssertZext: - SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); - return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); - - case ISD::AND: - // (X & C1) & C2 == 0 iff C1 & C2 == 0. - if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) - return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI); - - // FALL THROUGH - case ISD::OR: - case ISD::XOR: - return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(1), Mask, TLI); - case ISD::SELECT: - return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(2), Mask, TLI); - case ISD::SELECT_CC: - return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) && - MaskedValueIsZero(Op.getOperand(3), Mask, TLI); - case ISD::SRL: - // (ushr X, C1) & C2 == 0 iff X & (C2 << C1) == 0 - if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { - uint64_t NewVal = Mask << ShAmt->getValue(); - SrcBits = MVT::getSizeInBits(Op.getValueType()); - if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1; - return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); - } - return false; - case ISD::SHL: - // (ushl X, C1) & C2 == 0 iff X & (C2 >> C1) == 0 - if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { - uint64_t NewVal = Mask >> ShAmt->getValue(); - return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); - } - return false; - case ISD::CTTZ: - case ISD::CTLZ: - case ISD::CTPOP: - // Bit counting instructions can not set the high bits of the result - // register. The max number of bits sets depends on the input. - return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0; - - // TODO we could handle some SRA cases here. - default: break; - } - - return false; -} + case ISD::Constant: + return (cast(Op)->getValue() & Mask) == 0; + case ISD::SETCC: + return ((Mask & 1) == 0) && + TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; + case ISD::ZEXTLOAD: + SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); + return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. + case ISD::ZERO_EXTEND: + SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); + return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); + case ISD::AssertZext: + SrcBits = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); + return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. + case ISD::AND: + // (X & C1) & C2 == 0 iff C1 & C2 == 0. + if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) + return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI); + // FALL THROUGH + case ISD::OR: + case ISD::XOR: + return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(1), Mask, TLI); + case ISD::SELECT: + return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(2), Mask, TLI); + case ISD::SELECT_CC: + return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) && + MaskedValueIsZero(Op.getOperand(3), Mask, TLI); + case ISD::SRL: + // (ushr X, C1) & C2 == 0 iff X & (C2 << C1) == 0 + if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { + uint64_t NewVal = Mask << ShAmt->getValue(); + SrcBits = MVT::getSizeInBits(Op.getValueType()); + if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1; + return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); + } + return false; + case ISD::SHL: + // (ushl X, C1) & C2 == 0 iff X & (C2 >> C1) == 0 + if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { + uint64_t NewVal = Mask >> ShAmt->getValue(); + return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); + } + return false; + case ISD::CTTZ: + case ISD::CTLZ: + case ISD::CTPOP: + // Bit counting instructions can not set the high bits of the result + // register. The max number of bits sets depends on the input. + return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0; -// isInvertibleForFree - Return true if there is no cost to emitting the logical -// inverse of this node. -static bool isInvertibleForFree(SDOperand N) { - if (isa(N.Val)) return true; - if (N.Val->getOpcode() == ISD::SETCC && N.Val->hasOneUse()) - return true; + // TODO we could handle some SRA cases here. + default: break; + } return false; } -// isSetCCEquivalent - Return true if this node is a select_cc that selects -// between the values 1 and 0, making it equivalent to a setcc. +// isSetCCEquivalent - Return true if this node is a setcc, or is a select_cc +// that selects between the values 1 and 0, making it equivalent to a setcc. static bool isSetCCEquivalent(SDOperand N) { + if (N.getOpcode() == ISD::SETCC) + return true; if (N.getOpcode() == ISD::SELECT_CC && N.getOperand(2).getOpcode() == ISD::Constant && N.getOperand(3).getOpcode() == ISD::Constant && @@ -222,7 +216,19 @@ return false; } -void DAGCombiner::Run(bool AfterLegalize) { +// isInvertibleForFree - Return true if there is no cost to emitting the logical +// inverse of this node. +static bool isInvertibleForFree(SDOperand N) { + if (isa(N.Val)) return true; + if (isSetCCEquivalent(N) && N.Val->hasOneUse()) + return true; + return false; +} + +void DAGCombiner::Run(bool RunningAfterLegalize) { + // set the instance variable, so that the various visit routines may use it. + AfterLegalize = RunningAfterLegalize; + // while the worklist isn't empty, inspect the node on the end of it and // try and combine it. while (!WorkList.empty()) { @@ -295,10 +301,6 @@ case ISD::FP_EXTEND: return visitFPExtend(N); case ISD::FNEG: return visitFneg(N); case ISD::FABS: return visitFabs(N); - case ISD::EXTLOAD: return visitExtLoad(N); - case ISD::SEXTLOAD: return visitSextLoad(N); - case ISD::ZEXTLOAD: return visitZextLoad(N); - case ISD::TRUNCSTORE: return visitTruncStore(N); } return 0; } @@ -322,10 +324,10 @@ SDNode *DAGCombiner::visitAdd(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); + ConstantFPSDNode *N1CFP = dyn_cast(N0); + ConstantFPSDNode *N2CFP = dyn_cast(N1); // fold (add c1, c2) -> c1+c2 if (N1C && N2C) @@ -395,10 +397,10 @@ SDNode *DAGCombiner::visitMul(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); + ConstantFPSDNode *N1CFP = dyn_cast(N0); + ConstantFPSDNode *N2CFP = dyn_cast(N1); // fold (mul c1, c2) -> c1*c2 if (N1C && N2C) @@ -463,10 +465,10 @@ SDNode *DAGCombiner::visitSrem(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); + ConstantFPSDNode *N1CFP = dyn_cast(N0); + ConstantFPSDNode *N2CFP = dyn_cast(N1); // fold (srem c1, c2) -> c1%c2 if (N1C && N2C) @@ -482,8 +484,8 @@ SDNode *DAGCombiner::visitUrem(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); // fold (urem c1, c2) -> c1%c2 if (N1C && N2C) @@ -495,7 +497,7 @@ SDNode *DAGCombiner::visitMulHiS(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N2C = dyn_cast(N1); // fold (mulhs x, 0) -> 0 if (N2C && N2C->isNullValue()) @@ -512,7 +514,7 @@ SDNode *DAGCombiner::visitMulHiU(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N2C = dyn_cast(N1); // fold (mulhu x, 0) -> 0 if (N2C && N2C->isNullValue()) @@ -527,27 +529,26 @@ SDNode *DAGCombiner::visitAnd(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); // fold (and c1, c2) -> c1&c2 if (N1C && N2C) return DAG.getConstant(N1C->getValue() & N2C->getValue(), VT).Val; - // fold (and x, 0) -> 0 - if (N2C && N2C->isNullValue()) - return N1.Val; // fold (and x, -1) -> x if (N2C && N2C->isAllOnesValue()) return N0.Val; // fold (and x, 0) -> 0 - if (MaskedValueIsZero(N0, N2C->getValue(), TLI)) + if (N2C && MaskedValueIsZero(N0, N2C->getValue(), TLI)) return DAG.getConstant(0, VT).Val; // fold (and x, mask containing x) -> x - uint64_t NotC2 = ~N2C->getValue(); - if (MVT::i64 != VT) NotC2 &= (1ULL << MVT::getSizeInBits(VT))-1; - if (MaskedValueIsZero(N0, NotC2, TLI)) - return N0.Val; + if (N2C) { + uint64_t NotC2 = ~N2C->getValue(); + NotC2 &= ~0ULL >> (64-MVT::getSizeInBits(VT)); + if (MaskedValueIsZero(N0, NotC2, TLI)) + return N0.Val; + } // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned ExtendBits = @@ -560,21 +561,14 @@ if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N2C->getValue()) == N2C->getValue()) return N1.Val; - // fold (and (assert_zext x, i16), 0xFFFF) -> (assert_zext x, i16) - if (N0.getOpcode() == ISD::AssertZext) { - unsigned ExtendBits = - MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); - if (N2C->getValue() == (1ULL << ExtendBits)-1) - return N0.Val; - } return 0; } SDNode *DAGCombiner::visitOr(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); // fold (or c1, c2) -> c1|c2 if (N1C && N2C) @@ -592,8 +586,8 @@ SDNode *DAGCombiner::visitXor(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); // fold (xor c1, c2) -> c1^c2 @@ -603,14 +597,14 @@ if (N2C && N2C->isNullValue()) return N0.Val; // fold !(x cc y) -> (x !cc y) - if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::SETCC) { + if (N2C && N2C->getValue() == 1 && N0.getOpcode() == ISD::SETCC) { bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); ISD::CondCode CC = cast(N0.getOperand(2))->get(); return DAG.getSetCC(VT, N0.getOperand(0), N0.getOperand(1), ISD::getSetCCInverse(CC, isInt)).Val; } // fold !(x cc y) -> (x !cc y) - if (N2C && N2C->isAllOnesValue() && isSetCCEquivalent(N0)) { + if (N2C && N2C->getValue() == 1 && isSetCCEquivalent(N0)) { bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); ISD::CondCode CC = cast(N0.getOperand(4))->get(); return DAG.getSelectCC(N0.getOperand(0), N0.getOperand(1), @@ -641,8 +635,8 @@ SDNode *DAGCombiner::visitShl(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); unsigned OpSizeInBits = MVT::getSizeInBits(VT); @@ -688,22 +682,17 @@ DAG.getConstant(c1-c2, N1.getValueType())).Val; } // fold (shl (sra x, c1), c1) -> (and x, -1 << c1) - if (N2C && N0.getOpcode() == ISD::SRA && - N0.getOperand(1).getOpcode() == ISD::Constant) { - uint64_t c1 = cast(N0.getOperand(1))->getValue(); - uint64_t c2 = N2C->getValue(); - if (c1 == c2) - return DAG.getNode(ISD::AND, VT, N0.getOperand(0), - DAG.getConstant(~0ULL << c1, VT)).Val; - } + if (N2C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) + return DAG.getNode(ISD::AND, VT, N0.getOperand(0), + DAG.getConstant(~0ULL << N2C->getValue(), VT)).Val; return 0; } SDNode *DAGCombiner::visitSra(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); unsigned OpSizeInBits = MVT::getSizeInBits(VT); @@ -731,8 +720,8 @@ SDNode *DAGCombiner::visitSrl(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N2C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); unsigned OpSizeInBits = MVT::getSizeInBits(VT); @@ -767,7 +756,7 @@ SDNode *DAGCombiner::visitCtlz(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); // fold (ctlz c1) -> c2 if (N1C) @@ -778,7 +767,7 @@ SDNode *DAGCombiner::visitCttz(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); // fold (cttz c1) -> c2 if (N1C) @@ -789,7 +778,7 @@ SDNode *DAGCombiner::visitCtpop(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); // fold (ctpop c1) -> c2 if (N1C) @@ -800,12 +789,9 @@ SDNode *DAGCombiner::visitSignExtend(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); - // noop sext - if (N0.getValueType() == N->getValueType(0)) - return N0.Val; // fold (sext c1) -> c1 if (N1C) return DAG.getConstant(N1C->getSignExtended(), VT).Val; @@ -817,12 +803,9 @@ SDNode *DAGCombiner::visitZeroExtend(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); - // noop zext - if (N0.getValueType() == N->getValueType(0)) - return N0.Val; // fold (zext c1) -> c1 if (N1C) return DAG.getConstant(N1C->getValue(), VT).Val; @@ -834,13 +817,10 @@ SDNode *DAGCombiner::visitSignExtendInReg(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); - // noop sext_in_reg - if (EVT == VT) - return N0.Val; // fold (sext_in_reg c1) -> c1 if (N1C) { SDOperand Truncate = DAG.getConstant(N1C->getValue(), EVT); @@ -861,7 +841,7 @@ cast(N0.getOperand(3))->getVT() <= EVT) { return N0.Val; } - // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or 1 + // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1 if (N0.getOpcode() == ISD::SETCC && TLI.getSetCCResultContents() == TargetLowering::ZeroOrNegativeOneSetCCResult) @@ -884,7 +864,7 @@ SDNode *DAGCombiner::visitTruncate(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // noop truncate @@ -914,7 +894,7 @@ SDNode *DAGCombiner::visitSintToFP(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (sint_to_fp c1) -> c1fp @@ -925,7 +905,7 @@ SDNode *DAGCombiner::visitUintToFP(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (uint_to_fp c1) -> c1fp @@ -1017,54 +997,10 @@ return 0; } -SDNode *DAGCombiner::visitExtLoad(SDNode *N) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType EVT = cast(N->getOperand(3))->getVT(); - - // fold (extload vt, x) -> (load x) - if (EVT == VT) - return DAG.getLoad(VT, N->getOperand(0), N->getOperand(1), - N->getOperand(2)).Val; - return 0; -} - -SDNode *DAGCombiner::visitSextLoad(SDNode *N) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType EVT = cast(N->getOperand(3))->getVT(); - - // fold (sextload vt, x) -> (load x) - if (EVT == VT) - return DAG.getLoad(VT, N->getOperand(0), N->getOperand(1), - N->getOperand(2)).Val; - return 0; -} - -SDNode *DAGCombiner::visitZextLoad(SDNode *N) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType EVT = cast(N->getOperand(3))->getVT(); - - // fold (zextload vt, x) -> (load x) - if (EVT == VT) - return DAG.getLoad(VT, N->getOperand(0), N->getOperand(1), - N->getOperand(2)).Val; - return 0; -} - -SDNode *DAGCombiner::visitTruncStore(SDNode *N) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType EVT = cast(N->getOperand(4))->getVT(); - - // fold (truncstore x, vt) -> (store x) - if (N->getOperand(0).getValueType() == EVT) - return DAG.getNode(ISD::STORE, VT, N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3)).Val; - return 0; -} - // SelectionDAG::Combine - This is the entry point for the file. // -void SelectionDAG::Combine(bool AfterLegalize) { +void SelectionDAG::Combine(bool RunningAfterLegalize) { /// run - This is the main entry point to this class. /// - DAGCombiner(*this).Run(AfterLegalize); + DAGCombiner(*this).Run(RunningAfterLegalize); } From natebegeman at mac.com Thu Sep 1 18:26:00 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 1 Sep 2005 18:26:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509012326.SAA10217@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.181 -> 1.182 --- Log message: Fix some code in the current node combining code, spotted when it was moved over to DAGCombiner.cpp 1. Don't assume that SetCC returns i1 when folding (xor (setcc) constant) 2. Don't duplicate code in folding AND with AssertZext that is handled by MaskedValueIsZero --- Diffs of the changes: (+3 -11) SelectionDAG.cpp | 14 +++----------- 1 files changed, 3 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.181 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.182 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.181 Tue Aug 30 21:47:06 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Sep 1 18:25:49 2005 @@ -1394,14 +1394,6 @@ // we know the result of the AND will be the AND mask itself. return N2; } - } else if (N1.getOpcode() == ISD::AssertZext) { - // If we are masking out the part of our input that was already masked - // out, just return the input directly. - unsigned ExtendBits = - MVT::getSizeInBits(cast(N1.getOperand(1))->getVT()); - uint64_t ExtendMask = (1ULL << ExtendBits) - 1; - if (ExtendMask == C2) - return N1.getOperand(0); } break; case ISD::OR: @@ -1411,8 +1403,7 @@ break; case ISD::XOR: if (!C2) return N1; // X xor 0 -> X - if (N2C->isAllOnesValue()) { - if (N1.Val->getOpcode() == ISD::SETCC){ + if (N2C->getValue() == 1 && N1.Val->getOpcode() == ISD::SETCC) { SDNode *SetCC = N1.Val; // !(X op Y) -> (X !op Y) bool isInteger = MVT::isInteger(SetCC->getOperand(0).getValueType()); @@ -1420,7 +1411,8 @@ return getSetCC(SetCC->getValueType(0), SetCC->getOperand(0), SetCC->getOperand(1), ISD::getSetCCInverse(CC, isInteger)); - } else if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) { + } else if (N2C->isAllOnesValue()) { + if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) { SDNode *Op = N1.Val; // !(X or Y) -> (!X and !Y) iff X or Y are freely invertible // !(X and Y) -> (!X or !Y) iff X or Y are freely invertible From lattner at cs.uiuc.edu Thu Sep 1 18:44:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 18:44:09 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Message-ID: <200509012344.SAA10354@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: small-arguments.ll updated: 1.1 -> 1.2 --- Log message: Another case that shouldn't have sign extends: functions returning short are known to return properly sign extended values, no need for an explicit extension. --- Diffs of the changes: (+14 -0) small-arguments.ll | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll diff -u llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.1 Wed Aug 31 13:19:50 2005 +++ llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Thu Sep 1 18:43:58 2005 @@ -10,3 +10,17 @@ %Z = and int %Y, 65535 ;; dead ret int %Z } + +void %test3() { + %tmp.0 = call short %foo() ;; no extsh! + %tmp.1 = setlt short %tmp.0, 1234 + br bool %tmp.1, label %then, label %UnifiedReturnBlock + +then: + call int %test1(short 0) + ret void +UnifiedReturnBlock: + ret void +} + +declare short %foo() From lattner at cs.uiuc.edu Thu Sep 1 18:44:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 18:44:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200509012344.SAA10364@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.17 -> 1.18 --- Log message: Implement small-arguments.ll:test3 by teaching the DAG optimizer that the results of calls to functions returning small values are properly sign/zero extended. --- Diffs of the changes: (+16 -2) PPC32ISelLowering.cpp | 18 ++++++++++++++++-- 1 files changed, 16 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.17 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.18 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.17 Wed Aug 31 16:09:52 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Thu Sep 1 18:44:32 2005 @@ -613,8 +613,12 @@ std::vector RetVals; MVT::ValueType RetTyVT = getValueType(RetTy); + MVT::ValueType ActualRetTyVT = RetTyVT; + if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16) + ActualRetTyVT = MVT::i32; // Promote result to i32. + if (RetTyVT != MVT::isVoid) - RetVals.push_back(RetTyVT); + RetVals.push_back(ActualRetTyVT); RetVals.push_back(MVT::Other); SDOperand TheCall = SDOperand(DAG.getCall(RetVals, @@ -622,7 +626,17 @@ Chain = TheCall.getValue(RetTyVT != MVT::isVoid); Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); - return std::make_pair(TheCall, Chain); + SDOperand RetVal = TheCall; + + // If the result is a small value, add a note so that we keep track of the + // information about whether it is sign or zero extended. + if (RetTyVT != ActualRetTyVT) { + RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, + MVT::i32, RetVal, DAG.getValueType(RetTyVT)); + RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); + } + + return std::make_pair(RetVal, Chain); } SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, From lattner at cs.uiuc.edu Thu Sep 1 19:14:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:14:08 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Message-ID: <200509020014.TAA10470@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: small-arguments.ll updated: 1.2 -> 1.3 --- Log message: This should permit NOT and's, not even dead ones. --- Diffs of the changes: (+1 -1) small-arguments.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll diff -u llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.2 llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.3 --- llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.2 Thu Sep 1 18:43:58 2005 +++ llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Thu Sep 1 19:13:56 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=ppc32 | not grep 'extsh\|rlwinm r3, r3' +; RUN: llvm-as < %s | llc -march=ppc32 | not grep 'extsh\|rlwinm' int %test1(short %X) { %Y = cast short %X to int ;; dead From lattner at cs.uiuc.edu Thu Sep 1 19:14:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:14:51 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200509020014.TAA10530@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.66 -> 1.67 --- Log message: Add a new ANY_EXTEND node, which operates like an extension but has undefined top bits. --- Diffs of the changes: (+3 -0) SelectionDAGNodes.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.66 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.67 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.66 Mon Aug 29 21:39:32 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Thu Sep 1 19:14:40 2005 @@ -158,6 +158,9 @@ // ZERO_EXTEND - Used for integer types, zeroing the new bits. ZERO_EXTEND, + // ANY_EXTEND - Used for integer types. The high bits are undefined. + ANY_EXTEND, + // TRUNCATE - Completely drop the high bits. TRUNCATE, From lattner at cs.uiuc.edu Thu Sep 1 19:15:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:15:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200509020015.TAA10597@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.63 -> 1.64 --- Log message: Handle ANY_EXTEND like ZERO_EXTEND. Simplify the extend/truncate code on the observation that it only has to handle i1 -> i64 and i64 -> i1. --- Diffs of the changes: (+24 -60) IA64ISelPattern.cpp | 84 ++++++++++++++-------------------------------------- 1 files changed, 24 insertions(+), 60 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.63 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.64 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.63 Fri Aug 26 12:18:44 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Thu Sep 1 19:15:30 2005 @@ -1157,77 +1157,41 @@ return Result; } + case ISD::ANY_EXTEND: case ISD::ZERO_EXTEND: { Tmp1 = SelectExpr(N.getOperand(0)); // value - switch (N.getOperand(0).getValueType()) { - default: assert(0 && "Cannot zero-extend this type!"); - case MVT::i8: Opc = IA64::ZXT1; break; - case MVT::i16: Opc = IA64::ZXT2; break; - case MVT::i32: Opc = IA64::ZXT4; break; + assert(N.getOperand(0).getValueType() == MVT::i1 && + "Cannot zero-extend this type!"); - // we handle bools differently! : - case MVT::i1: { // if the predicate reg has 1, we want a '1' in our GR. - unsigned dummy = MakeReg(MVT::i64); - // first load zero: - BuildMI(BB, IA64::MOV, 1, dummy).addReg(IA64::r0); - // ...then conditionally (PR:Tmp1) add 1: - BuildMI(BB, IA64::TPCADDIMM22, 2, Result).addReg(dummy) - .addImm(1).addReg(Tmp1); - return Result; // XXX early exit! - } - } - - BuildMI(BB, Opc, 1, Result).addReg(Tmp1); - return Result; - } - - case ISD::SIGN_EXTEND: { // we should only have to handle i1 -> i64 here!!! - -assert(0 && "hmm, ISD::SIGN_EXTEND: shouldn't ever be reached. bad luck!\n"); + // if the predicate reg has 1, we want a '1' in our GR. + unsigned dummy = MakeReg(MVT::i64); + // first load zero: + BuildMI(BB, IA64::MOV, 1, dummy).addReg(IA64::r0); + // ...then conditionally (PR:Tmp1) add 1: + BuildMI(BB, IA64::TPCADDIMM22, 2, Result).addReg(dummy) + .addImm(1).addReg(Tmp1); + return Result; // XXX early exit! + } + + case ISD::SIGN_EXTEND: + assert(N.getOperand(0).getValueType() == MVT::i1 && + "Cannot zero-extend this type!"); Tmp1 = SelectExpr(N.getOperand(0)); // value + assert(0 && "don't know how to sign_extend from bool yet!"); + abort(); - switch (N.getOperand(0).getValueType()) { - default: assert(0 && "Cannot sign-extend this type!"); - case MVT::i1: assert(0 && "trying to sign extend a bool? ow.\n"); - Opc = IA64::SXT1; break; - // FIXME: for now, we treat bools the same as i8s - case MVT::i8: Opc = IA64::SXT1; break; - case MVT::i16: Opc = IA64::SXT2; break; - case MVT::i32: Opc = IA64::SXT4; break; - } - - BuildMI(BB, Opc, 1, Result).addReg(Tmp1); - return Result; - } - - case ISD::TRUNCATE: { + case ISD::TRUNCATE: // we use the funky dep.z (deposit (zero)) instruction to deposit bits // of R0 appropriately. - switch (N.getOperand(0).getValueType()) { - default: assert(0 && "Unknown truncate!"); - case MVT::i64: break; - } + assert(N.getOperand(0).getValueType() == MVT::i64 && + N.getValueType() == MVT::i1 && "Unknown truncate!"); Tmp1 = SelectExpr(N.getOperand(0)); - unsigned depositPos, depositLen; - switch (N.getValueType()) { - default: assert(0 && "Unknown truncate!"); - case MVT::i1: { - // if input (normal reg) is 0, 0!=0 -> false (0), if 1, 1!=0 ->true (1): - BuildMI(BB, IA64::CMPNE, 2, Result).addReg(Tmp1) - .addReg(IA64::r0); - return Result; // XXX early exit! - } - case MVT::i8: depositPos=0; depositLen=8; break; - case MVT::i16: depositPos=0; depositLen=16; break; - case MVT::i32: depositPos=0; depositLen=32; break; - } - BuildMI(BB, IA64::DEPZ, 3, Result).addReg(Tmp1) - .addImm(depositPos).addImm(depositLen); - return Result; - } + // if input (normal reg) is 0, 0!=0 -> false (0), if 1, 1!=0 ->true (1): + BuildMI(BB, IA64::CMPNE, 2, Result).addReg(Tmp1).addReg(IA64::r0); + return Result; // XXX early exit! /* case ISD::FP_ROUND: { From lattner at cs.uiuc.edu Thu Sep 1 19:16:20 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:16:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200509020016.TAA10656@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.176 -> 1.177 --- Log message: Handle any_extend like zext --- Diffs of the changes: (+1 -0) X86ISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.176 llvm/lib/Target/X86/X86ISelPattern.cpp:1.177 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.176 Sat Aug 27 14:09:48 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Thu Sep 1 19:16:09 2005 @@ -2394,6 +2394,7 @@ BuildMI(BB, X86::MOV32ri, 1, Result).addExternalSymbol(Sym); return Result; } + case ISD::ANY_EXTEND: // treat any extend like zext case ISD::ZERO_EXTEND: { int DestIs16 = N.getValueType() == MVT::i16; int SrcIs16 = N.getOperand(0).getValueType() == MVT::i16; From lattner at cs.uiuc.edu Thu Sep 1 19:17:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:17:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509020017.TAA10761@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.182 -> 1.183 --- Log message: Add support for ANY_EXTEND and add a few minor folds for it --- Diffs of the changes: (+11 -1) SelectionDAG.cpp | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.182 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.183 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.182 Thu Sep 1 18:25:49 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Sep 1 19:17:32 2005 @@ -1000,6 +1000,7 @@ switch (Opcode) { default: break; case ISD::SIGN_EXTEND: return getConstant(C->getSignExtended(), VT); + case ISD::ANY_EXTEND: case ISD::ZERO_EXTEND: return getConstant(Val, VT); case ISD::TRUNCATE: return getConstant(Val, VT); case ISD::SINT_TO_FP: return getConstantFP(C->getSignExtended(), VT); @@ -1034,11 +1035,18 @@ if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x) return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0)); break; + case ISD::ANY_EXTEND: + if (Operand.getValueType() == VT) return Operand; // noop extension + if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND) + // (ext (zext x)) -> (zext x) and (ext (sext x)) -> (sext x) + return getNode(OpOpcode, VT, Operand.Val->getOperand(0)); + break; case ISD::TRUNCATE: if (Operand.getValueType() == VT) return Operand; // noop truncate if (OpOpcode == ISD::TRUNCATE) return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0)); - else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND) { + else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND || + OpOpcode == ISD::ANY_EXTEND) { // If the source is smaller than the dest, we still need an extend. if (Operand.Val->getOperand(0).getValueType() < VT) return getNode(OpOpcode, VT, Operand.Val->getOperand(0)); @@ -1378,6 +1386,7 @@ // FIXME: Should add a corresponding version of this for // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which // we don't have yet. + // FIXME: NOW WE DO, add this. // and (sign_extend_inreg x:16:32), 1 -> and x, 1 if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) { @@ -2251,6 +2260,7 @@ // Conversion operators. case ISD::SIGN_EXTEND: return "sign_extend"; case ISD::ZERO_EXTEND: return "zero_extend"; + case ISD::ANY_EXTEND: return "any_extend"; case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg"; case ISD::TRUNCATE: return "truncate"; case ISD::FP_ROUND: return "fp_round"; From lattner at cs.uiuc.edu Thu Sep 1 19:18:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:18:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200509020018.TAA10818@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.181 -> 1.182 --- Log message: legalize ANY_EXTEND appropriately --- Diffs of the changes: (+26 -6) LegalizeDAG.cpp | 32 ++++++++++++++++++++++++++------ 1 files changed, 26 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.181 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.182 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.181 Wed Aug 31 14:01:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Sep 1 19:18:10 2005 @@ -1088,7 +1088,7 @@ TLI.getTypeToPromoteTo(ISD::SELECT, Tmp2.getValueType()); unsigned ExtOp, TruncOp; if (MVT::isInteger(Tmp2.getValueType())) { - ExtOp = ISD::ZERO_EXTEND; + ExtOp = ISD::ANY_EXTEND; TruncOp = ISD::TRUNCATE; } else { ExtOp = ISD::FP_EXTEND; @@ -1866,6 +1866,7 @@ } break; + case ISD::ANY_EXTEND: case ISD::ZERO_EXTEND: case ISD::SIGN_EXTEND: case ISD::FP_EXTEND: @@ -1881,17 +1882,19 @@ case Promote: switch (Node->getOpcode()) { + case ISD::ANY_EXTEND: + Result = PromoteOp(Node->getOperand(0)); + Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result); + break; case ISD::ZERO_EXTEND: Result = PromoteOp(Node->getOperand(0)); - // NOTE: Any extend would work here... - Result = DAG.getNode(ISD::ZERO_EXTEND, Op.getValueType(), Result); + Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result); Result = DAG.getZeroExtendInReg(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::ZERO_EXTEND, Op.getValueType(), Result); + Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result); Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), Result, DAG.getValueType(Node->getOperand(0).getValueType())); @@ -2051,6 +2054,7 @@ break; case ISD::SIGN_EXTEND: case ISD::ZERO_EXTEND: + case ISD::ANY_EXTEND: switch (getTypeAction(Node->getOperand(0).getValueType())) { case Expand: assert(0 && "BUG: Smaller reg should have been promoted!"); case Legal: @@ -2065,7 +2069,7 @@ if (Node->getOpcode() == ISD::SIGN_EXTEND) Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result, DAG.getValueType(Node->getOperand(0).getValueType())); - else + else if (Node->getOpcode() == ISD::ZERO_EXTEND) Result = DAG.getZeroExtendInReg(Result, Node->getOperand(0).getValueType()); break; @@ -3010,6 +3014,22 @@ Hi = LegalizeOp(Hi); break; } + case ISD::ANY_EXTEND: { + SDOperand In; + switch (getTypeAction(Node->getOperand(0).getValueType())) { + case Expand: assert(0 && "expand-expand not implemented yet!"); + case Legal: In = LegalizeOp(Node->getOperand(0)); break; + case Promote: + In = PromoteOp(Node->getOperand(0)); + break; + } + + // The low part is any extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, In); + // The high part is undefined. + Hi = DAG.getNode(ISD::UNDEF, NVT); + break; + } case ISD::SIGN_EXTEND: { SDOperand In; switch (getTypeAction(Node->getOperand(0).getValueType())) { From lattner at cs.uiuc.edu Thu Sep 1 19:19:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:19:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200509020019.TAA10878@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.78 -> 1.79 --- Log message: For values that are live across basic blocks and need promotion, use ANY_EXTEND instead of ZERO_EXTEND to eliminate extraneous extensions. This eliminates dead zero extensions on formal arguments and other cases on PPC, implementing the newly tightened up test/Regression/CodeGen/PowerPC/small-arguments.ll test. --- Diffs of the changes: (+5 -10) SelectionDAGISel.cpp | 15 +++++---------- 1 files changed, 5 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.78 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.79 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.78 Thu Sep 1 13:44:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Sep 1 19:19:37 2005 @@ -491,7 +491,7 @@ SDOperand Op2 = getValue(I.getOperand(1)); if (isShift) - Op2 = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), Op2); + Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2); setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); } @@ -1025,7 +1025,7 @@ if (MVT::isFloatingPoint(SrcVT)) Op = DAG.getNode(ISD::FP_EXTEND, DestVT, Op); else - Op = DAG.getNode(ISD::ZERO_EXTEND, DestVT, Op); + Op = DAG.getNode(ISD::ANY_EXTEND, DestVT, Op); return DAG.getCopyToReg(SDL.getRoot(), Reg, Op); } else { // The src value is expanded into multiple registers. @@ -1078,14 +1078,9 @@ if (!AI->use_empty()) { SDL.setValue(AI, Args[a]); - if (0 && IsOnlyUsedInOneBasicBlock(AI) == F.begin()) { - // Only used in the entry block, no need to copy it to a vreg for - // other blocks. - } else { - SDOperand Copy = - CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]); - UnorderedChains.push_back(Copy); - } + 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, From lattner at cs.uiuc.edu Thu Sep 1 19:20:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:20:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp LiveIntervalAnalysis.h Message-ID: <200509020020.TAA10970@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.144 -> 1.145 LiveIntervalAnalysis.h updated: 1.45 -> 1.46 --- Log message: Teach live intervals to not crash on dead livein regs --- Diffs of the changes: (+13 -7) LiveIntervalAnalysis.cpp | 17 +++++++++++------ LiveIntervalAnalysis.h | 3 ++- 2 files changed, 13 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.144 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.145 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.144 Tue Aug 23 17:51:41 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Sep 1 19:20:32 2005 @@ -131,10 +131,10 @@ for (MachineFunction::livein_iterator I = fn.livein_begin(), E = fn.livein_end(); I != E; ++I) { handlePhysicalRegisterDef(Entry, Entry->begin(), - getOrCreateInterval(I->first), 0, 0); + getOrCreateInterval(I->first), 0, 0, true); for (const unsigned* AS = mri_->getAliasSet(I->first); *AS; ++AS) handlePhysicalRegisterDef(Entry, Entry->begin(), - getOrCreateInterval(*AS), 0, 0); + getOrCreateInterval(*AS), 0, 0, true); } } @@ -478,7 +478,8 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator mi, LiveInterval& interval, - unsigned SrcReg, unsigned DestReg) + unsigned SrcReg, unsigned DestReg, + bool isLiveIn) { // A physical register cannot be live across basic block, so its // lifetime must end somewhere in its defining basic block. @@ -501,9 +502,7 @@ // If it is not dead on definition, it must be killed by a // subsequent instruction. Hence its interval is: // [defSlot(def), useSlot(kill)+1) - while (true) { - ++mi; - assert(mi != MBB->end() && "physreg was not killed in defining block!"); + while (++mi != MBB->end()) { baseIndex += InstrSlots::NUM; if (lv_->KillsRegister(mi, interval.reg)) { DEBUG(std::cerr << " killed"); @@ -511,6 +510,12 @@ goto exit; } } + + // The only case we should have a dead physreg here without a killing or + // instruction where we know it's dead is if it is live-in to the function + // and never used. + assert(isLiveIn && "physreg was not killed in defining block!"); + end = getDefIndex(start) + 1; // It's dead. exit: assert(start < end && "did not find end of interval?"); Index: llvm/lib/CodeGen/LiveIntervalAnalysis.h diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.45 llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.46 --- llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.45 Wed Mar 9 17:05:19 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.h Thu Sep 1 19:20:32 2005 @@ -164,7 +164,8 @@ void handlePhysicalRegisterDef(MachineBasicBlock* mbb, MachineBasicBlock::iterator mi, LiveInterval& interval, - unsigned SrcReg, unsigned DestReg); + unsigned SrcReg, unsigned DestReg, + bool isLiveIn = false); /// Return true if the two specified registers belong to different /// register classes. The registers may be either phys or virt regs. From lattner at cs.uiuc.edu Thu Sep 1 19:47:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 19:47:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200509020047.TAA11203@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.18 -> 1.19 --- Log message: Revert the previous patch which causes a mysterious regression in toast. --- Diffs of the changes: (+2 -16) PPC32ISelLowering.cpp | 18 ++---------------- 1 files changed, 2 insertions(+), 16 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.18 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.19 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.18 Thu Sep 1 18:44:32 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Thu Sep 1 19:47:05 2005 @@ -613,12 +613,8 @@ std::vector RetVals; MVT::ValueType RetTyVT = getValueType(RetTy); - MVT::ValueType ActualRetTyVT = RetTyVT; - if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16) - ActualRetTyVT = MVT::i32; // Promote result to i32. - if (RetTyVT != MVT::isVoid) - RetVals.push_back(ActualRetTyVT); + RetVals.push_back(RetTyVT); RetVals.push_back(MVT::Other); SDOperand TheCall = SDOperand(DAG.getCall(RetVals, @@ -626,17 +622,7 @@ Chain = TheCall.getValue(RetTyVT != MVT::isVoid); Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); - SDOperand RetVal = TheCall; - - // If the result is a small value, add a note so that we keep track of the - // information about whether it is sign or zero extended. - if (RetTyVT != ActualRetTyVT) { - RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, - MVT::i32, RetVal, DAG.getValueType(RetTyVT)); - RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); - } - - return std::make_pair(RetVal, Chain); + return std::make_pair(TheCall, Chain); } SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, From lattner at cs.uiuc.edu Thu Sep 1 20:15:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 20:15:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200509020115.UAA11565@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.182 -> 1.183 --- Log message: Make sure to legalize assert[zs]ext's operand correctly --- Diffs of the changes: (+7 -2) LegalizeDAG.cpp | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.182 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.183 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.182 Thu Sep 1 19:18:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Sep 1 20:15:01 2005 @@ -456,14 +456,19 @@ assert(0 && "Do not know how to legalize this operator!"); abort(); case ISD::EntryToken: - case ISD::AssertSext: - case ISD::AssertZext: case ISD::FrameIndex: case ISD::GlobalAddress: case ISD::ExternalSymbol: case ISD::ConstantPool: // Nothing to do. assert(isTypeLegal(Node->getValueType(0)) && "This must be legal!"); break; + case ISD::AssertSext: + case ISD::AssertZext: + Tmp1 = LegalizeOp(Node->getOperand(0)); + if (Tmp1 != Node->getOperand(0)) + Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, + Node->getOperand(1)); + break; case ISD::CopyFromReg: Tmp1 = LegalizeOp(Node->getOperand(0)); if (Tmp1 != Node->getOperand(0)) From lattner at cs.uiuc.edu Thu Sep 1 20:25:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 1 Sep 2005 20:25:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Message-ID: <200509020125.UAA11633@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.19 -> 1.20 --- Log message: Restore this patch now that the latent bug has been fixed --- Diffs of the changes: (+16 -2) PPC32ISelLowering.cpp | 18 ++++++++++++++++-- 1 files changed, 16 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.19 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.20 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.19 Thu Sep 1 19:47:05 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Thu Sep 1 20:24:55 2005 @@ -613,8 +613,12 @@ std::vector RetVals; MVT::ValueType RetTyVT = getValueType(RetTy); + MVT::ValueType ActualRetTyVT = RetTyVT; + if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16) + ActualRetTyVT = MVT::i32; // Promote result to i32. + if (RetTyVT != MVT::isVoid) - RetVals.push_back(RetTyVT); + RetVals.push_back(ActualRetTyVT); RetVals.push_back(MVT::Other); SDOperand TheCall = SDOperand(DAG.getCall(RetVals, @@ -622,7 +626,17 @@ Chain = TheCall.getValue(RetTyVT != MVT::isVoid); Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); - return std::make_pair(TheCall, Chain); + SDOperand RetVal = TheCall; + + // If the result is a small value, add a note so that we keep track of the + // information about whether it is sign or zero extended. + if (RetTyVT != ActualRetTyVT) { + RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, + MVT::i32, RetVal, DAG.getValueType(RetTyVT)); + RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); + } + + return std::make_pair(RetVal, Chain); } SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, From jeffc at jolt-lang.org Thu Sep 1 21:51:54 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 1 Sep 2005 21:51:54 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/SubtargetFeature.h Message-ID: <200509020251.VAA12020@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: SubtargetFeature.h updated: 1.1 -> 1.2 --- Log message: Fix VC++ build errors --- Diffs of the changes: (+1 -0) SubtargetFeature.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/Target/SubtargetFeature.h diff -u llvm/include/llvm/Target/SubtargetFeature.h:1.1 llvm/include/llvm/Target/SubtargetFeature.h:1.2 --- llvm/include/llvm/Target/SubtargetFeature.h:1.1 Thu Sep 1 16:36:18 2005 +++ llvm/include/llvm/Target/SubtargetFeature.h Thu Sep 1 21:51:42 2005 @@ -23,6 +23,7 @@ #include #include #include +#include "llvm/Support/DataTypes.h" namespace llvm { From jeffc at jolt-lang.org Thu Sep 1 21:51:54 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 1 Sep 2005 21:51:54 -0500 Subject: [llvm-commits] CVS: llvm/win32/Target/Target.vcproj Message-ID: <200509020251.VAA12024@zion.cs.uiuc.edu> Changes in directory llvm/win32/Target: Target.vcproj updated: 1.9 -> 1.10 --- Log message: Fix VC++ build errors --- Diffs of the changes: (+6 -0) Target.vcproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/win32/Target/Target.vcproj diff -u llvm/win32/Target/Target.vcproj:1.9 llvm/win32/Target/Target.vcproj:1.10 --- llvm/win32/Target/Target.vcproj:1.9 Mon Jul 11 22:00:20 2005 +++ llvm/win32/Target/Target.vcproj Thu Sep 1 21:51:42 2005 @@ -110,6 +110,9 @@ RelativePath="..\..\lib\Target\MRegisterInfo.cpp"> + + + + Changes in directory llvm/lib/Target: SubtargetFeature.cpp updated: 1.1 -> 1.2 --- Log message: Fix VC++ build errors --- Diffs of the changes: (+1 -1) SubtargetFeature.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SubtargetFeature.cpp diff -u llvm/lib/Target/SubtargetFeature.cpp:1.1 llvm/lib/Target/SubtargetFeature.cpp:1.2 --- llvm/lib/Target/SubtargetFeature.cpp:1.1 Thu Sep 1 16:36:18 2005 +++ llvm/lib/Target/SubtargetFeature.cpp Thu Sep 1 21:51:42 2005 @@ -17,7 +17,7 @@ #include #include #include - +#include using namespace llvm; From lattner at cs.uiuc.edu Fri Sep 2 00:23:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 00:23:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/Reassociate.cpp Message-ID: <200509020523.AAA13609@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: Reassociate.cpp updated: 1.52 -> 1.53 --- Log message: add some assertions and fix problems where reassociate could access the Ops vector out of range --- Diffs of the changes: (+11 -2) Reassociate.cpp | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/Reassociate.cpp diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.52 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.53 --- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.52 Wed Aug 24 12:55:32 2005 +++ llvm/lib/Transforms/Scalar/Reassociate.cpp Fri Sep 2 00:23:22 2005 @@ -455,6 +455,7 @@ Ops.pop_back(); break; } + if (Ops.size() == 1) return; // Handle destructive annihilation do to identities between elements in the // argument list here. @@ -467,6 +468,7 @@ // If we find any, we can simplify the expression. X&~X == 0, X|~X == -1. for (unsigned i = 0, e = Ops.size(); i != e; ++i) { // First, check for X and ~X in the operand list. + assert(i < Ops.size()); if (BinaryOperator::isNot(Ops[i].Op)) { // Cannot occur for ^. Value *X = BinaryOperator::getNotArgument(Ops[i].Op); unsigned FoundX = FindInOperandList(Ops, i, X); @@ -487,6 +489,7 @@ // Next, check for duplicate pairs of values, which we assume are next to // each other, due to our sorting criteria. + assert(i < Ops.size()); if (i+1 != Ops.size() && Ops[i+1].Op == Ops[i].Op) { if (Opcode == Instruction::And || Opcode == Instruction::Or) { // Drop duplicate values. @@ -516,6 +519,7 @@ // Scan the operand lists looking for X and -X pairs. If we find any, we // can simplify the expression. X+-X == 0 for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + assert(i < Ops.size()); // Check for X and -X in the operand list. if (BinaryOperator::isNeg(Ops[i].Op)) { Value *X = BinaryOperator::getNegArgument(Ops[i].Op); @@ -524,15 +528,20 @@ // Remove X and -X from the operand list. if (Ops.size() == 2) { Ops[0].Op = Constant::getNullValue(X->getType()); - Ops.erase(Ops.begin()+1); + Ops.pop_back(); ++NumAnnihil; return; } else { Ops.erase(Ops.begin()+i); - if (i < FoundX) --FoundX; + if (i < FoundX) + --FoundX; + else + --i; // Need to back up an extra one. Ops.erase(Ops.begin()+FoundX); IterateOptimization = true; ++NumAnnihil; + --i; // Revisit element. + e -= 2; // Removed two elements. } } } From lattner at cs.uiuc.edu Fri Sep 2 01:12:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 01:12:24 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Reassociate/2005-09-01-ArrayOutOfBounds.ll Message-ID: <200509020612.BAA13992@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Reassociate: 2005-09-01-ArrayOutOfBounds.ll added (r1.1) --- Log message: new testcase for recent bugfix --- Diffs of the changes: (+21 -0) 2005-09-01-ArrayOutOfBounds.ll | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/test/Regression/Transforms/Reassociate/2005-09-01-ArrayOutOfBounds.ll diff -c /dev/null llvm/test/Regression/Transforms/Reassociate/2005-09-01-ArrayOutOfBounds.ll:1.1 *** /dev/null Fri Sep 2 01:12:22 2005 --- llvm/test/Regression/Transforms/Reassociate/2005-09-01-ArrayOutOfBounds.ll Fri Sep 2 01:12:12 2005 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | opt -reassociate -instcombine | llvm-dis | grep 'ret int 0' + + int %f(int %a0, int %a1, int %a2, int %a3, int %a4) { + %tmp.2 = add int %a4, %a3 ; [#uses=1] + %tmp.4 = add int %tmp.2, %a2 ; [#uses=1] + %tmp.6 = add int %tmp.4, %a1 ; [#uses=1] + %tmp.8 = add int %tmp.6, %a0 ; [#uses=1] + %tmp.11 = add int %a3, %a2 ; [#uses=1] + %tmp.13 = add int %tmp.11, %a1 ; [#uses=1] + %tmp.15 = add int %tmp.13, %a0 ; [#uses=1] + %tmp.18 = add int %a2, %a1 ; [#uses=1] + %tmp.20 = add int %tmp.18, %a0 ; [#uses=1] + %tmp.23 = add int %a1, %a0 ; [#uses=1] + %tmp.26 = sub int %tmp.8, %tmp.15 ; [#uses=1] + %tmp.28 = add int %tmp.26, %tmp.20 ; [#uses=1] + %tmp.30 = sub int %tmp.28, %tmp.23 ; [#uses=1] + %tmp.32 = sub int %tmp.30, %a4 ; [#uses=1] + %tmp.34 = sub int %tmp.32, %a2 ; [#uses=2] + %T = mul int %tmp.34, %tmp.34 + ret int %T + } From lattner at cs.uiuc.edu Fri Sep 2 01:38:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 01:38:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/Reassociate.cpp Message-ID: <200509020638.BAA15971@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: Reassociate.cpp updated: 1.53 -> 1.54 --- Log message: Avoid creating garbage instructions, just move the old add instruction to where we need it when converting -(A+B+C) -> -A + -B + -C. --- Diffs of the changes: (+11 -9) Reassociate.cpp | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) Index: llvm/lib/Transforms/Scalar/Reassociate.cpp diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.53 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.54 --- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.53 Fri Sep 2 00:23:22 2005 +++ llvm/lib/Transforms/Scalar/Reassociate.cpp Fri Sep 2 01:38:04 2005 @@ -318,16 +318,18 @@ // if (Instruction *I = dyn_cast(V)) if (I->getOpcode() == Instruction::Add && I->hasOneUse()) { - Value *RHS = NegateValue(I->getOperand(1), BI); - Value *LHS = NegateValue(I->getOperand(0), BI); - - // We must actually insert a new add instruction here, because the neg - // instructions do not dominate the old add instruction in general. By - // adding it now, we are assured that the neg instructions we just - // inserted dominate the instruction we are about to insert after them. + // Push the negates through the add. + I->setOperand(0, NegateValue(I->getOperand(0), BI)); + I->setOperand(1, NegateValue(I->getOperand(1), BI)); + + // We must move the add instruction here, because the neg instructions do + // not dominate the old add instruction in general. By moving it, we are + // assured that the neg instructions we just inserted dominate the + // instruction we are about to insert after them. // - return BinaryOperator::create(Instruction::Add, LHS, RHS, - I->getName()+".neg", BI); + I->moveBefore(BI); + I->setName(I->getName()+".neg"); + return I; } // Insert a 'neg' instruction that subtracts the value from zero to get the From lattner at cs.uiuc.edu Fri Sep 2 01:48:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 01:48:58 -0500 Subject: [llvm-commits] CVS: llvm-www/ProjectsWithLLVM/index.html Message-ID: <200509020648.BAA17492@zion.cs.uiuc.edu> Changes in directory llvm-www/ProjectsWithLLVM: index.html updated: 1.25 -> 1.26 --- Log message: corrections suggested by Eric --- Diffs of the changes: (+3 -2) index.html | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm-www/ProjectsWithLLVM/index.html diff -u llvm-www/ProjectsWithLLVM/index.html:1.25 llvm-www/ProjectsWithLLVM/index.html:1.26 --- llvm-www/ProjectsWithLLVM/index.html:1.25 Thu Sep 1 17:04:56 2005 +++ llvm-www/ProjectsWithLLVM/index.html Fri Sep 2 01:48:47 2005 @@ -58,12 +58,13 @@
-By Eric van Riet Paap and the PyPy Team +By Eric van Riet Paap and the PyPy Team

-The PyPy Project is a reimplementation +The PyPy Project +is a reimplementation of Python written in Python itself, that is flexible and easy to experiment with. Our long-term goals are to target a large variety of platforms, small and large, From lattner at cs.uiuc.edu Fri Sep 2 02:08:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 02:08:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/Reassociate.cpp Message-ID: <200509020708.CAA19945@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: Reassociate.cpp updated: 1.54 -> 1.55 --- Log message: Fix a problem that Dan Berlin noticed, where reassociation would not succeed in building maximal expressions before simplifying them. In particular, i cases like this: X-(A+B+X) the code would consider A+B+X to be a maximal expression (not understanding that the single use '-' would be turned into a + later), simplify it (a noop) then later get simplified again. Each of these simplify steps is where the cost of reassociation comes from, so this patch should speed up the already fast pass a bit. Thanks to Dan for noticing this! --- Diffs of the changes: (+6 -0) Reassociate.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Transforms/Scalar/Reassociate.cpp diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.54 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.55 --- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.54 Fri Sep 2 01:38:04 2005 +++ llvm/lib/Transforms/Scalar/Reassociate.cpp Fri Sep 2 02:07:58 2005 @@ -612,6 +612,12 @@ if (I->hasOneUse() && isReassociableOp(I->use_back(), I->getOpcode())) continue; + // If this is an add tree that is used by a sub instruction, ignore it + // until we process the subtract. + if (I->hasOneUse() && I->getOpcode() == Instruction::Add && + cast(I->use_back())->getOpcode() == Instruction::Sub) + continue; + // First, walk the expression tree, linearizing the tree, collecting std::vector Ops; LinearizeExprTree(I, Ops); From lattner at cs.uiuc.edu Fri Sep 2 02:09:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 02:09:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp Message-ID: <200509020709.CAA20402@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.21 -> 1.22 SelectionDAGISel.cpp updated: 1.79 -> 1.80 --- Log message: Fix the release build, noticed by Eric van Riet Paap --- Diffs of the changes: (+2 -2) ScheduleDAG.cpp | 2 +- SelectionDAGISel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.21 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.22 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.21 Thu Sep 1 13:44:10 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Sep 2 02:09:28 2005 @@ -29,7 +29,7 @@ ViewDAGs("view-sched-dags", cl::Hidden, cl::desc("Pop up a window to show sched dags as they are processed")); #else -static const bool ViewDAGS = 0; +static const bool ViewDAGs = 0; #endif namespace { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.79 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.80 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.79 Thu Sep 1 19:19:37 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Sep 2 02:09:28 2005 @@ -41,7 +41,7 @@ ViewDAGs("view-isel-dags", cl::Hidden, cl::desc("Pop up a window to show isel dags as they are selected")); #else -static const bool ViewDAGS = 0; +static const bool ViewDAGs = 0; #endif namespace llvm { From lattner at cs.uiuc.edu Fri Sep 2 02:10:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 02:10:27 -0500 Subject: [llvm-commits] CVS: llvm-www/ProjectsWithLLVM/index.html Message-ID: <200509020710.CAA20464@zion.cs.uiuc.edu> Changes in directory llvm-www/ProjectsWithLLVM: index.html updated: 1.26 -> 1.27 --- Log message: another change requested by eric --- Diffs of the changes: (+2 -1) index.html | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm-www/ProjectsWithLLVM/index.html diff -u llvm-www/ProjectsWithLLVM/index.html:1.26 llvm-www/ProjectsWithLLVM/index.html:1.27 --- llvm-www/ProjectsWithLLVM/index.html:1.26 Fri Sep 2 01:48:47 2005 +++ llvm-www/ProjectsWithLLVM/index.html Fri Sep 2 02:10:16 2005 @@ -58,7 +58,8 @@

-By Eric van Riet Paap and the PyPy Team +By Carl Friedrich Bolz, Richard Emslie, Eric van Riet Paap and the rest +of the PyPy Team
From lattner at cs.uiuc.edu Fri Sep 2 13:16:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 13:16:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200509021816.NAA25569@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.79 -> 1.80 --- Log message: Move a bunch of non-deprecated methods above the "deprecated line" --- Diffs of the changes: (+30 -27) TargetInstrInfo.h | 57 ++++++++++++++++++++++++++++-------------------------- 1 files changed, 30 insertions(+), 27 deletions(-) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.79 llvm/include/llvm/Target/TargetInstrInfo.h:1.80 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.79 Fri Aug 26 15:31:24 2005 +++ llvm/include/llvm/Target/TargetInstrInfo.h Fri Sep 2 13:16:20 2005 @@ -174,6 +174,34 @@ bool isTerminatorInstr(unsigned Opcode) const { return get(Opcode).Flags & M_TERMINATOR_FLAG; } + + bool isBranch(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_BRANCH_FLAG; + } + + /// isBarrier - Returns true if the specified instruction stops control flow + /// from executing the instruction immediately following it. Examples include + /// unconditional branches and return instructions. + bool isBarrier(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_BARRIER_FLAG; + } + + bool isCall(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_CALL_FLAG; + } + bool isLoad(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_LOAD_FLAG; + } + bool isStore(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_STORE_FLAG; + } + + /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires + /// custom insertion support when the DAG scheduler is inserting it into a + /// machine basic block. + bool usesCustomDAGSchedInsertionHook(unsigned Opcode) const { + return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; + } /// Return true if the instruction is a register to register move /// and leave the source and dest operands in the passed parameters. @@ -224,6 +252,7 @@ abort(); return MI; } + //------------------------------------------------------------------------- // Code generation support for creating individual machine instructions @@ -243,39 +272,13 @@ bool isNop(MachineOpCode Opcode) const { return get(Opcode).Flags & M_NOP_FLAG; } - bool isBranch(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_BRANCH_FLAG; - } - /// isBarrier - Returns true if the specified instruction stops control flow - /// from executing the instruction immediately following it. Examples include - /// unconditional branches and return instructions. - bool isBarrier(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_BARRIER_FLAG; - } - - bool isCall(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_CALL_FLAG; - } - bool isLoad(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_LOAD_FLAG; - } - bool isStore(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_STORE_FLAG; - } - + /// hasDelaySlot - Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. bool hasDelaySlot(unsigned Opcode) const { return get(Opcode).Flags & M_DELAY_SLOT_FLAG; } - /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires - /// custom insertion support when the DAG scheduler is inserting it into a - /// machine basic block. - bool usesCustomDAGSchedInsertionHook(unsigned Opcode) const { - return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; - } - virtual bool hasResultInterlock(MachineOpCode Opcode) const { return true; } From lattner at cs.uiuc.edu Fri Sep 2 13:32:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 13:32:33 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fsqrt.ll Message-ID: <200509021832.NAA25828@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fsqrt.ll added (r1.1) --- Log message: new testcase to ensure fsqrt is generated for correct subtargets only, and that the fsqrt feature works. --- Diffs of the changes: (+13 -0) fsqrt.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/fsqrt.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fsqrt.ll:1.1 *** /dev/null Fri Sep 2 13:32:32 2005 --- llvm/test/Regression/CodeGen/PowerPC/fsqrt.ll Fri Sep 2 13:32:22 2005 *************** *** 0 **** --- 1,13 ---- + ; fsqrt should be generated when the fsqrt feature is enabled, but not + ; otherwise. + + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=+fsqrt | grep 'fsqrt f1, f1' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 | grep 'fsqrt f1, f1' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=-fsqrt | not grep 'fsqrt f1, f1' && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g4 | not grep 'fsqrt f1, f1' + + declare double %llvm.sqrt(double) + double %X(double %Y) { + %Z = call double %llvm.sqrt(double %Y) + ret double %Z + } From lattner at cs.uiuc.edu Fri Sep 2 13:33:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 13:33:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp PowerPCSubtarget.cpp PowerPCSubtarget.h Message-ID: <200509021833.NAA25844@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelLowering.cpp updated: 1.20 -> 1.21 PowerPCSubtarget.cpp updated: 1.4 -> 1.5 PowerPCSubtarget.h updated: 1.3 -> 1.4 --- Log message: Decouple fsqrt from gpul optimizations, implementing fsqrt.ll. Remove the -enable-gpopt option which is subsumed by feature flags. --- Diffs of the changes: (+8 -8) PPC32ISelLowering.cpp | 2 +- PowerPCSubtarget.cpp | 11 ++++------- PowerPCSubtarget.h | 3 +++ 3 files changed, 8 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.20 llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.21 --- llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp:1.20 Thu Sep 1 20:24:55 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelLowering.cpp Fri Sep 2 13:33:05 2005 @@ -54,7 +54,7 @@ setOperationAction(ISD::SREM , MVT::f32, Expand); // If we're enabling GP optimizations, use hardware square root - if (!TM.getSubtarget().isGigaProcessor()) { + if (!TM.getSubtarget().hasFSQRT()) { setOperationAction(ISD::FSQRT, MVT::f64, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand); } Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.4 llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.5 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.4 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Fri Sep 2 13:33:05 2005 @@ -25,11 +25,10 @@ PPCTargetArg(cl::desc("Force generation of code for a specific PPC target:"), cl::values( clEnumValN(TargetAIX, "aix", " Enable AIX codegen"), - clEnumValN(TargetDarwin,"darwin"," Enable Darwin codegen"), + clEnumValN(TargetDarwin,"darwin", + " Enable Darwin codegen"), clEnumValEnd), cl::location(PPCTarget), cl::init(TargetDefault)); - cl::opt EnableGPOPT("enable-gpopt", cl::Hidden, - cl::desc("Enable optimizations for GP cpus")); } enum PowerPCFeature { @@ -126,7 +125,8 @@ SubtargetFeatures::Parse(FS, CPU, PowerPCSubTypeKV, PowerPCSubTypeKVSize, PowerPCFeatureKV, PowerPCFeatureKVSize); - IsGigaProcessor = (Bits & PowerPCFeatureGPUL) != 0; + IsGigaProcessor = (Bits & PowerPCFeatureGPUL ) != 0; + HasFSQRT = (Bits & PowerPCFeatureFSqrt) != 0; // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. @@ -140,7 +140,4 @@ IsDarwin = true; #endif } - - // If GP opts are forced on by the commandline, do so now. - if (EnableGPOPT) IsGigaProcessor = true; } Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.3 llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.4 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.h:1.3 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.h Fri Sep 2 13:33:05 2005 @@ -29,6 +29,7 @@ /// Used by the ISel to turn in optimizations for POWER4-derived architectures bool IsGigaProcessor; + bool HasFSQRT; bool IsAIX; bool IsDarwin; public: @@ -42,6 +43,8 @@ /// function for this subtarget. unsigned getStackAlignment() const { return StackAlignment; } + bool hasFSQRT() const { return HasFSQRT; } + bool isAIX() const { return IsAIX; } bool isDarwin() const { return IsDarwin; } From lattner at cs.uiuc.edu Fri Sep 2 13:41:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 13:41:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200509021841.NAA25938@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.80 -> 1.81 --- Log message: Don't create zero sized stack objects even for array allocas with a zero number of elements. --- Diffs of the changes: (+2 -1) SelectionDAGISel.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.80 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.81 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.80 Fri Sep 2 02:09:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Sep 2 13:41:28 2005 @@ -150,7 +150,8 @@ // TargetData. It serves primarily to 8-byte align doubles for X86. if (Align < TySize && TySize <= 8) Align = TySize; - TySize *= CUI->getValue(); // Get total allocated size. + if (CUI->getValue()) // Don't produce zero sized stack objects + TySize *= CUI->getValue(); // Get total allocated size. StaticAllocaMap[AI] = MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align); } From alenhar2 at cs.uiuc.edu Fri Sep 2 13:46:20 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 2 Sep 2005 13:46:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp AlphaISelLowering.h AlphaISelPattern.cpp Message-ID: <200509021846.NAA19156@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp added (r1.1) AlphaISelLowering.h added (r1.1) AlphaISelPattern.cpp updated: 1.166 -> 1.167 --- Log message: Pull out Lowering in preperation for multiple ISels. Oh, and get rid of some stuff --- Diffs of the changes: (+435 -434) AlphaISelLowering.cpp | 376 +++++++++++++++++++++++++++++++++++++++++++ AlphaISelLowering.h | 58 ++++++ AlphaISelPattern.cpp | 435 -------------------------------------------------- 3 files changed, 435 insertions(+), 434 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.1 *** /dev/null Fri Sep 2 13:46:12 2005 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp Fri Sep 2 13:46:02 2005 *************** *** 0 **** --- 1,376 ---- + //===-- AlphaISelLowering.cpp - Alpha DAG Lowering Implementation ---------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Andrew Lenharth and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the AlphaISelLowering class. + // + //===----------------------------------------------------------------------===// + + #include "AlphaISelLowering.h" + #include "AlphaTargetMachine.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Constants.h" + #include "llvm/Function.h" + #include "llvm/Support/CommandLine.h" + #include + + using namespace llvm; + + namespace llvm { + extern cl::opt EnableAlphaIDIV; + extern cl::opt EnableAlphaFTOI; + extern cl::opt EnableAlphaCT; + extern cl::opt EnableAlphaCount; + extern cl::opt EnableAlphaLSMark; + } + + /// AddLiveIn - This helper function adds the specified physical register to the + /// MachineFunction as a live in value. It also creates a corresponding virtual + /// register for it. + static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, + TargetRegisterClass *RC) { + assert(RC->contains(PReg) && "Not the correct regclass!"); + unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); + MF.addLiveIn(PReg, VReg); + return VReg; + } + + AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { + // Set up the TargetLowering object. + //I am having problems with shr n ubyte 1 + setShiftAmountType(MVT::i64); + setSetCCResultType(MVT::i64); + setSetCCResultContents(ZeroOrOneSetCCResult); + + addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); + addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); + addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass); + + setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); + setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand); + + setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); + setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); + + setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote); + setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand); + + setOperationAction(ISD::SEXTLOAD, MVT::i1, Promote); + setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); + setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); + + setOperationAction(ISD::SREM, MVT::f32, Expand); + setOperationAction(ISD::SREM, MVT::f64, Expand); + + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); + + if (!EnableAlphaCT) { + setOperationAction(ISD::CTPOP , MVT::i64 , Expand); + setOperationAction(ISD::CTTZ , MVT::i64 , Expand); + setOperationAction(ISD::CTLZ , MVT::i64 , Expand); + } + + //If this didn't legalize into a div.... + // setOperationAction(ISD::SREM , MVT::i64, Expand); + // setOperationAction(ISD::UREM , MVT::i64, Expand); + + setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); + setOperationAction(ISD::MEMSET , MVT::Other, Expand); + setOperationAction(ISD::MEMCPY , MVT::Other, Expand); + + // We don't support sin/cos/sqrt + setOperationAction(ISD::FSIN , MVT::f64, Expand); + setOperationAction(ISD::FCOS , MVT::f64, Expand); + setOperationAction(ISD::FSQRT, MVT::f64, Expand); + setOperationAction(ISD::FSIN , MVT::f32, Expand); + setOperationAction(ISD::FCOS , MVT::f32, Expand); + setOperationAction(ISD::FSQRT, MVT::f32, Expand); + + //Doesn't work yet + setOperationAction(ISD::SETCC, MVT::f32, Promote); + + computeRegisterProperties(); + + addLegalFPImmediate(+0.0); //F31 + addLegalFPImmediate(-0.0); //-F31 + } + + + //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) + + // //#define FP $15 + // //#define RA $26 + // //#define PV $27 + // //#define GP $29 + // //#define SP $30 + + std::vector + AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) + { + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineBasicBlock& BB = MF.front(); + std::vector ArgValues; + + static const unsigned args_int[] = { + Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; + static const unsigned args_float[] = { + Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; + unsigned added_int = 0; + unsigned added_fp = 0; + + int count = 0; + + GP = AddLiveIn(MF, Alpha::R29, getRegClassFor(MVT::i64)); + RA = AddLiveIn(MF, Alpha::R26, getRegClassFor(MVT::i64)); + + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) + { + SDOperand argt; + if (count < 6) { + unsigned Vreg; + MVT::ValueType VT = getValueType(I->getType()); + switch (VT) { + default: + std::cerr << "Unknown Type " << VT << "\n"; + abort(); + case MVT::f64: + case MVT::f32: + MF.addLiveIn(args_float[count]); + added_fp |= (1 << count); + argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[count], VT); + DAG.setRoot(argt.getValue(1)); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + MF.addLiveIn(args_int[count]); + added_int |= (1 << count); + argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[count], MVT::i64); + DAG.setRoot(argt.getValue(1)); + if (VT != MVT::i64) { + unsigned AssertOp = + I->getType()->isSigned() ? ISD::AssertSext : ISD::AssertZext; + argt = DAG.getNode(AssertOp, MVT::i64, argt, + DAG.getValueType(VT)); + argt = DAG.getNode(ISD::TRUNCATE, VT, argt); + } + break; + } + } else { //more args + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(8, 8 * (count - 6)); + + // Create the SelectionDAG nodes corresponding to a load + //from this parameter + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); + argt = DAG.getLoad(getValueType(I->getType()), + DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL)); + } + ++count; + ArgValues.push_back(argt); + } + + // If the functions takes variable number of arguments, copy all regs to stack + if (F.isVarArg()) { + VarArgsOffset = count * 8; + std::vector LS; + for (int i = 0; i < 6; ++i) { + if (!(added_int & (1 << i))) + MF.addLiveIn(args_int[i]); + SDOperand argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[i], MVT::i64); + int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); + if (i == 0) VarArgsBase = FI; + SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); + LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, + SDFI, DAG.getSrcValue(NULL))); + + if (!(added_fp & (1 << i))) + MF.addLiveIn(args_float[i]); + argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[i], MVT::f64); + FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); + SDFI = DAG.getFrameIndex(FI, MVT::i64); + LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, + SDFI, DAG.getSrcValue(NULL))); + } + + //Set up a token factor with all the stack traffic + DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, LS)); + } + + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + MF.addLiveOut(Alpha::R0); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(Alpha::F0); + break; + } + + //return the arguments + return ArgValues; + } + + std::pair + AlphaTargetLowering::LowerCallTo(SDOperand Chain, + const Type *RetTy, bool isVarArg, + unsigned CallingConv, bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { + int NumBytes = 0; + if (Args.size() > 6) + NumBytes = (Args.size() - 6) * 8; + + Chain = DAG.getNode(ISD::CALLSEQ_START, 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: + case MVT::f64: + case MVT::f32: + 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::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + return std::make_pair(TheCall, Chain); + } + + SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + // vastart stores the address of the VarArgsBase and VarArgsOffset + SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); + SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + DAG.getSrcValue(VAListV)); + SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, + DAG.getConstant(8, MVT::i64)); + return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, + DAG.getConstant(VarArgsOffset, MVT::i64), SA2, + DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32)); + } + + std::pair AlphaTargetLowering:: + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { + SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, + DAG.getSrcValue(VAListV)); + SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, + DAG.getConstant(8, MVT::i64)); + SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), + Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); + SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); + if (ArgTy->isFloatingPoint()) + { + //if fp && Offset < 6*8, then subtract 6*8 from DataPtr + SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, + DAG.getConstant(8*6, MVT::i64)); + SDOperand CC = DAG.getSetCC(MVT::i64, Offset, + DAG.getConstant(8*6, MVT::i64), ISD::SETLT); + DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); + } + + SDOperand Result; + if (ArgTy == Type::IntTy) + Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Offset.getValue(1), + DataPtr, DAG.getSrcValue(NULL), MVT::i32); + else if (ArgTy == Type::UIntTy) + Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1), + DataPtr, DAG.getSrcValue(NULL), MVT::i32); + else + Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr, + DAG.getSrcValue(NULL)); + + SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, + DAG.getConstant(8, MVT::i64)); + SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, + Result.getValue(1), NewOffset, + Tmp, DAG.getSrcValue(VAListV, 8), + DAG.getValueType(MVT::i32)); + Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result); + + return std::make_pair(Result, Update); + } + + + SDOperand AlphaTargetLowering:: + LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP, + Value *DestV, SelectionDAG &DAG) { + SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, + DAG.getSrcValue(SrcV)); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), + Val, DestP, DAG.getSrcValue(DestV)); + SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, + DAG.getConstant(8, MVT::i64)); + Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, + DAG.getSrcValue(SrcV, 8), MVT::i32); + SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, + DAG.getConstant(8, MVT::i64)); + return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), + Val, NPD, DAG.getSrcValue(DestV, 8), + DAG.getValueType(MVT::i32)); + } + + void AlphaTargetLowering::restoreGP(MachineBasicBlock* BB) + { + BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); + } + void AlphaTargetLowering::restoreRA(MachineBasicBlock* BB) + { + BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(RA).addReg(RA); + } + + Index: llvm/lib/Target/Alpha/AlphaISelLowering.h diff -c /dev/null llvm/lib/Target/Alpha/AlphaISelLowering.h:1.1 *** /dev/null Fri Sep 2 13:46:20 2005 --- llvm/lib/Target/Alpha/AlphaISelLowering.h Fri Sep 2 13:46:02 2005 *************** *** 0 **** --- 1,58 ---- + //===-- AlphaISelLowering.h - Alpha DAG Lowering Interface ------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Andrew Lenharth and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the interfaces that Alpha uses to lower LLVM code into a + // selection DAG. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H + #define LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H + + #include "llvm/Target/TargetLowering.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "Alpha.h" + + namespace llvm { + + class AlphaTargetLowering : public TargetLowering { + int VarArgsOffset; // What is the offset to the first vaarg + int VarArgsBase; // What is the base FrameIndex + unsigned GP; //GOT vreg + unsigned RA; //Return Address + public: + AlphaTargetLowering(TargetMachine &TM); + + /// 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, bool isVarArg, unsigned CC, + bool isTailCall, SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG); + + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, + SDOperand DestP, Value *DestV, + SelectionDAG &DAG); + virtual std::pair + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + + void restoreGP(MachineBasicBlock* BB); + void restoreRA(MachineBasicBlock* BB); + }; + } + + #endif // LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.166 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.167 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.166 Fri Aug 26 12:15:30 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Fri Sep 2 13:46:02 2005 @@ -13,6 +13,7 @@ #include "Alpha.h" #include "AlphaRegisterInfo.h" +#include "AlphaISelLowering.h" #include "llvm/Constants.h" // FIXME: REMOVE #include "llvm/Function.h" #include "llvm/Module.h" @@ -52,440 +53,6 @@ } namespace { - // Alpha Specific DAG Nodes - namespace AlphaISD { - enum NodeType { - // Start the numbering where the builtin ops leave off. - FIRST_NUMBER = ISD::BUILTIN_OP_END, - - //Convert an int bit pattern in an FP reg to a Double or Float - //Has a dest type and a source - CVTQ, - //Move an Ireg to a FPreg - ITOF, - //Move a FPreg to an Ireg - FTOI, - }; - } -} - -//===----------------------------------------------------------------------===// -// AlphaTargetLowering - Alpha Implementation of the TargetLowering interface -namespace { - class AlphaTargetLowering : public TargetLowering { - int VarArgsOffset; // What is the offset to the first vaarg - int VarArgsBase; // What is the base FrameIndex - unsigned GP; //GOT vreg - unsigned RA; //Return Address - public: - AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { - // Set up the TargetLowering object. - //I am having problems with shr n ubyte 1 - setShiftAmountType(MVT::i64); - setSetCCResultType(MVT::i64); - setSetCCResultContents(ZeroOrOneSetCCResult); - - addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); - addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); - addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass); - - setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); - setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand); - - setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); - setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); - - setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand); - - setOperationAction(ISD::SEXTLOAD, MVT::i1, Promote); - setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); - setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); - - setOperationAction(ISD::SREM, MVT::f32, Expand); - setOperationAction(ISD::SREM, MVT::f64, Expand); - - setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); - - if (!EnableAlphaCT) { - setOperationAction(ISD::CTPOP , MVT::i64 , Expand); - setOperationAction(ISD::CTTZ , MVT::i64 , Expand); - setOperationAction(ISD::CTLZ , MVT::i64 , Expand); - } - - //If this didn't legalize into a div.... - // setOperationAction(ISD::SREM , MVT::i64, Expand); - // setOperationAction(ISD::UREM , MVT::i64, Expand); - - setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); - setOperationAction(ISD::MEMSET , MVT::Other, Expand); - setOperationAction(ISD::MEMCPY , MVT::Other, Expand); - - // We don't support sin/cos/sqrt - setOperationAction(ISD::FSIN , MVT::f64, Expand); - setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FSQRT, MVT::f64, Expand); - setOperationAction(ISD::FSIN , MVT::f32, Expand); - setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FSQRT, MVT::f32, Expand); - - //Doesn't work yet - setOperationAction(ISD::SETCC, MVT::f32, Promote); - - //Try a couple things with a custom expander - //setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); - - computeRegisterProperties(); - - addLegalFPImmediate(+0.0); //F31 - addLegalFPImmediate(-0.0); //-F31 - } - - /// LowerOperation - Provide custom lowering hooks for some operations. - /// - virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - - /// 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, bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG); - - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, - SDOperand DestP, Value *DestV, - SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - - void restoreGP(MachineBasicBlock* BB) - { - BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); - } - void restoreRA(MachineBasicBlock* BB) - { - BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(RA).addReg(RA); - } - unsigned getRA() - { - return RA; - } - - }; -} - -/// LowerOperation - Provide custom lowering hooks for some operations. -/// -SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { - MachineFunction &MF = DAG.getMachineFunction(); - switch (Op.getOpcode()) { - default: assert(0 && "Should not custom lower this!"); -#if 0 - case ISD::SINT_TO_FP: - { - assert (Op.getOperand(0).getValueType() == MVT::i64 - && "only quads can be loaded from"); - SDOperand SRC; - if (EnableAlphaFTOI) - { - std::vector RTs; - RTs.push_back(Op.getValueType()); - std::vector Ops; - Ops.push_back(Op.getOperand(0)); - SRC = DAG.getNode(AlphaISD::ITOF, RTs, Ops); - } else { - int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, - DAG.getEntryNode(), Op.getOperand(0), - StackSlot, DAG.getSrcValue(NULL)); - SRC = DAG.getLoad(Op.getValueType(), Store.getValue(0), StackSlot, - DAG.getSrcValue(NULL)); - } - std::vector RTs; - RTs.push_back(Op.getValueType()); - std::vector Ops; - Ops.push_back(SRC); - return DAG.getNode(AlphaISD::CVTQ, RTs, Ops); - } -#endif - } - return SDOperand(); -} - - -/// AddLiveIn - This helper function adds the specified physical register to the -/// MachineFunction as a live in value. It also creates a corresponding virtual -/// register for it. -static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, - TargetRegisterClass *RC) { - assert(RC->contains(PReg) && "Not the correct regclass!"); - unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); - MF.addLiveIn(PReg, VReg); - return VReg; -} - -//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) - -// //#define FP $15 -// //#define RA $26 -// //#define PV $27 -// //#define GP $29 -// //#define SP $30 - -std::vector -AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) -{ - std::vector ArgValues; - - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo*MFI = MF.getFrameInfo(); - - MachineBasicBlock& BB = MF.front(); - - unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18, - Alpha::R19, Alpha::R20, Alpha::R21}; - unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, - Alpha::F19, Alpha::F20, Alpha::F21}; - int count = 0; - - GP = AddLiveIn(MF, Alpha::R29, getRegClassFor(MVT::i64)); - RA = AddLiveIn(MF, Alpha::R26, getRegClassFor(MVT::i64)); - - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) - { - SDOperand argt; - if (count < 6) { - unsigned Vreg; - MVT::ValueType VT = getValueType(I->getType()); - switch (VT) { - default: - std::cerr << "Unknown Type " << VT << "\n"; - abort(); - case MVT::f64: - case MVT::f32: - args_float[count] = AddLiveIn(MF,args_float[count], getRegClassFor(VT)); - argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[count], VT); - DAG.setRoot(argt.getValue(1)); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - args_int[count] = AddLiveIn(MF, args_int[count], - getRegClassFor(MVT::i64)); - argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[count], MVT::i64); - DAG.setRoot(argt.getValue(1)); - if (VT != MVT::i64) - argt = DAG.getNode(ISD::TRUNCATE, VT, argt); - break; - } - } else { //more args - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(8, 8 * (count - 6)); - - // Create the SelectionDAG nodes corresponding to a load - //from this parameter - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); - argt = DAG.getLoad(getValueType(I->getType()), - DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL)); - } - ++count; - ArgValues.push_back(argt); - } - - // If the functions takes variable number of arguments, copy all regs to stack - if (F.isVarArg()) { - VarArgsOffset = count * 8; - std::vector LS; - for (int i = 0; i < 6; ++i) { - if (args_int[i] < 1024) - args_int[i] = AddLiveIn(MF,args_int[i], getRegClassFor(MVT::i64)); - SDOperand argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[i], MVT::i64); - int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); - if (i == 0) VarArgsBase = FI; - SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); - LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, - SDFI, DAG.getSrcValue(NULL))); - - if (args_float[i] < 1024) - args_float[i] = AddLiveIn(MF,args_float[i], getRegClassFor(MVT::f64)); - argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[i], MVT::f64); - FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); - SDFI = DAG.getFrameIndex(FI, MVT::i64); - LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, - SDFI, DAG.getSrcValue(NULL))); - } - - //Set up a token factor with all the stack traffic - DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, LS)); - } - - // Finally, inform the code generator which regs we return values in. - switch (getValueType(F.getReturnType())) { - default: assert(0 && "Unknown type!"); - case MVT::isVoid: break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - MF.addLiveOut(Alpha::R0); - break; - case MVT::f32: - case MVT::f64: - MF.addLiveOut(Alpha::F0); - break; - } - - //return the arguments - return ArgValues; -} - -std::pair -AlphaTargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, bool isVarArg, - unsigned CallingConv, bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - int NumBytes = 0; - if (Args.size() > 6) - NumBytes = (Args.size() - 6) * 8; - - Chain = DAG.getNode(ISD::CALLSEQ_START, 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: - case MVT::f64: - case MVT::f32: - 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::CALLSEQ_END, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - return std::make_pair(TheCall, Chain); -} - -SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart stores the address of the VarArgsBase and VarArgsOffset - SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); - SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); - SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, - DAG.getConstant(8, MVT::i64)); - return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, - DAG.getConstant(VarArgsOffset, MVT::i64), SA2, - DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32)); -} - -std::pair AlphaTargetLowering:: -LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, - DAG.getSrcValue(VAListV)); - SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, - DAG.getConstant(8, MVT::i64)); - SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), - Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); - SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); - if (ArgTy->isFloatingPoint()) - { - //if fp && Offset < 6*8, then subtract 6*8 from DataPtr - SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, - DAG.getConstant(8*6, MVT::i64)); - SDOperand CC = DAG.getSetCC(MVT::i64, Offset, - DAG.getConstant(8*6, MVT::i64), ISD::SETLT); - DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); - } - - SDOperand Result; - if (ArgTy == Type::IntTy) - Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Offset.getValue(1), - DataPtr, DAG.getSrcValue(NULL), MVT::i32); - else if (ArgTy == Type::UIntTy) - Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1), - DataPtr, DAG.getSrcValue(NULL), MVT::i32); - else - Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr, - DAG.getSrcValue(NULL)); - - SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, - DAG.getConstant(8, MVT::i64)); - SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, - Result.getValue(1), NewOffset, - Tmp, DAG.getSrcValue(VAListV, 8), - DAG.getValueType(MVT::i32)); - Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result); - - return std::make_pair(Result, Update); -} - - -SDOperand AlphaTargetLowering:: -LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP, - Value *DestV, SelectionDAG &DAG) { - SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, - DAG.getSrcValue(SrcV)); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, DestP, DAG.getSrcValue(DestV)); - SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, - DAG.getConstant(8, MVT::i64)); - Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, - DAG.getSrcValue(SrcV, 8), MVT::i32); - SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, - DAG.getConstant(8, MVT::i64)); - return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), - Val, NPD, DAG.getSrcValue(DestV, 8), - DAG.getValueType(MVT::i32)); -} - -namespace { //===--------------------------------------------------------------------===// /// ISel - Alpha specific code to select Alpha machine instructions for From lattner at cs.uiuc.edu Fri Sep 2 14:15:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 14:15:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509021915.OAA26484@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.183 -> 1.184 --- Log message: Fix some buggy logic where we would try to remove nodes with two operands from the binary ops map, even if they had multiple results. This latent bug caused a few failures with the dag isel last night. To prevent stuff like this from happening in the future, add some really strict checking to make sure that the CSE maps always match up with reality! --- Diffs of the changes: (+56 -34) SelectionDAG.cpp | 90 ++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 56 insertions(+), 34 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.183 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.184 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.183 Thu Sep 1 19:17:32 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 2 14:15:44 2005 @@ -260,89 +260,111 @@ /// the node. We don't want future request for structurally identical nodes /// to return N anymore. void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { + bool Erased = false; switch (N->getOpcode()) { case ISD::Constant: - Constants.erase(std::make_pair(cast(N)->getValue(), - N->getValueType(0))); + Erased = Constants.erase(std::make_pair(cast(N)->getValue(), + N->getValueType(0))); break; case ISD::TargetConstant: - TargetConstants.erase(std::make_pair(cast(N)->getValue(), - N->getValueType(0))); + Erased = TargetConstants.erase(std::make_pair( + cast(N)->getValue(), + N->getValueType(0))); break; case ISD::ConstantFP: { uint64_t V = DoubleToBits(cast(N)->getValue()); - ConstantFPs.erase(std::make_pair(V, N->getValueType(0))); + Erased = ConstantFPs.erase(std::make_pair(V, N->getValueType(0))); break; } case ISD::CONDCODE: assert(CondCodeNodes[cast(N)->get()] && "Cond code doesn't exist!"); + Erased = CondCodeNodes[cast(N)->get()] != 0; CondCodeNodes[cast(N)->get()] = 0; break; case ISD::GlobalAddress: - GlobalValues.erase(cast(N)->getGlobal()); + Erased = GlobalValues.erase(cast(N)->getGlobal()); break; case ISD::TargetGlobalAddress: - TargetGlobalValues.erase(cast(N)->getGlobal()); + Erased =TargetGlobalValues.erase(cast(N)->getGlobal()); break; case ISD::FrameIndex: - FrameIndices.erase(cast(N)->getIndex()); + Erased = FrameIndices.erase(cast(N)->getIndex()); break; case ISD::TargetFrameIndex: - TargetFrameIndices.erase(cast(N)->getIndex()); + Erased = TargetFrameIndices.erase(cast(N)->getIndex()); break; case ISD::ConstantPool: - ConstantPoolIndices.erase(cast(N)->get()); + Erased = ConstantPoolIndices.erase(cast(N)->get()); break; case ISD::TargetConstantPool: - TargetConstantPoolIndices.erase(cast(N)->get()); + Erased =TargetConstantPoolIndices.erase(cast(N)->get()); break; case ISD::BasicBlock: - BBNodes.erase(cast(N)->getBasicBlock()); + Erased = BBNodes.erase(cast(N)->getBasicBlock()); break; case ISD::ExternalSymbol: - ExternalSymbols.erase(cast(N)->getSymbol()); + Erased = ExternalSymbols.erase(cast(N)->getSymbol()); break; case ISD::VALUETYPE: + Erased = ValueTypeNodes[cast(N)->getVT()] != 0; ValueTypeNodes[cast(N)->getVT()] = 0; break; case ISD::Register: - RegNodes.erase(std::make_pair(cast(N)->getReg(), - N->getValueType(0))); + Erased = RegNodes.erase(std::make_pair(cast(N)->getReg(), + N->getValueType(0))); break; case ISD::SRCVALUE: { SrcValueSDNode *SVN = cast(N); - ValueNodes.erase(std::make_pair(SVN->getValue(), SVN->getOffset())); + Erased =ValueNodes.erase(std::make_pair(SVN->getValue(), SVN->getOffset())); break; } case ISD::LOAD: - Loads.erase(std::make_pair(N->getOperand(1), - std::make_pair(N->getOperand(0), - N->getValueType(0)))); + Erased = Loads.erase(std::make_pair(N->getOperand(1), + std::make_pair(N->getOperand(0), + N->getValueType(0)))); break; default: - if (N->getNumOperands() == 1) - UnaryOps.erase(std::make_pair(N->getOpcode(), - std::make_pair(N->getOperand(0), - N->getValueType(0)))); - else if (N->getNumOperands() == 2) - BinaryOps.erase(std::make_pair(N->getOpcode(), - std::make_pair(N->getOperand(0), - N->getOperand(1)))); - else if (N->getNumValues() == 1) { - std::vector Ops(N->op_begin(), N->op_end()); - OneResultNodes.erase(std::make_pair(N->getOpcode(), - std::make_pair(N->getValueType(0), - Ops))); + if (N->getNumValues() == 1) { + if (N->getNumOperands() == 1) { + Erased = + UnaryOps.erase(std::make_pair(N->getOpcode(), + std::make_pair(N->getOperand(0), + N->getValueType(0)))); + } else if (N->getNumOperands() == 2) { + Erased = + BinaryOps.erase(std::make_pair(N->getOpcode(), + std::make_pair(N->getOperand(0), + N->getOperand(1)))); + } else { + std::vector Ops(N->op_begin(), N->op_end()); + Erased = + OneResultNodes.erase(std::make_pair(N->getOpcode(), + std::make_pair(N->getValueType(0), + Ops))); + } } else { // Remove the node from the ArbitraryNodes map. std::vector RV(N->value_begin(), N->value_end()); std::vector Ops(N->op_begin(), N->op_end()); - ArbitraryNodes.erase(std::make_pair(N->getOpcode(), - std::make_pair(RV, Ops))); + Erased = + ArbitraryNodes.erase(std::make_pair(N->getOpcode(), + std::make_pair(RV, Ops))); } break; } +#ifndef NDEBUG + // Verify that the node was actually in one of the CSE maps, unless it has a + // flag result (which cannot be CSE'd) or is one of the special cases that are + // not subject to CSE. + if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag && + N->getOpcode() != ISD::CALL && N->getOpcode() != ISD::CALLSEQ_START && + N->getOpcode() != ISD::CALLSEQ_END) { + + N->dump(); + assert(0 && "Node is not in map!"); + } +#endif } /// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps. It From jlaskey at apple.com Fri Sep 2 14:27:56 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 2 Sep 2005 14:27:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Message-ID: <200509021927.OAA26558@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: TargetSelect.cpp updated: 1.8 -> 1.9 --- Log message: Add help support for -mcpu and -mattr. --- Diffs of the changes: (+3 -3) TargetSelect.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp diff -u llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.8 llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.9 --- llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.8 Thu Sep 1 16:38:20 2005 +++ llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Fri Sep 2 14:27:43 2005 @@ -26,15 +26,15 @@ static cl::opt MCPU("mcpu", - cl::desc("Target a specific cpu type"), + cl::desc("Target a specific cpu type (-mcpu=help for list of choices)"), cl::value_desc("cpu-name"), cl::init("")); static cl::list MAttrs("mattr", cl::CommaSeparated, - cl::desc("Target specific attributes:"), - cl::value_desc("attributes")); + cl::desc("Target specific attributes (-mattr=help for list of choices)"), + cl::value_desc("attr1,+attr2, ..., -attrN")); /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. From jlaskey at apple.com Fri Sep 2 14:27:57 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 2 Sep 2005 14:27:57 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/SubtargetFeature.h Message-ID: <200509021927.OAA26570@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: SubtargetFeature.h updated: 1.2 -> 1.3 --- Log message: Add help support for -mcpu and -mattr. --- Diffs of the changes: (+5 -0) SubtargetFeature.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/Target/SubtargetFeature.h diff -u llvm/include/llvm/Target/SubtargetFeature.h:1.2 llvm/include/llvm/Target/SubtargetFeature.h:1.3 --- llvm/include/llvm/Target/SubtargetFeature.h:1.2 Thu Sep 1 21:51:42 2005 +++ llvm/include/llvm/Target/SubtargetFeature.h Fri Sep 2 14:27:43 2005 @@ -34,6 +34,7 @@ // struct SubtargetFeatureKV { const char *Key; // K-V key string + const char *Desc; // Help descriptor uint32_t Value; // K-V integer value // Compare routine for std binary search @@ -126,6 +127,10 @@ /// Adding Features. void AddFeature(const std::string &String, bool IsEnabled = true); + /// Display help for feature choices. + static void Help(const char *Heading, + const SubtargetFeatureKV *Table, size_t TableSize); + /// Parse feature string for quick usage. static uint32_t Parse(const std::string &String, const std::string &DefaultCPU, From jlaskey at apple.com Fri Sep 2 14:27:57 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 2 Sep 2005 14:27:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Message-ID: <200509021927.OAA26574@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCSubtarget.cpp updated: 1.5 -> 1.6 --- Log message: Add help support for -mcpu and -mattr. --- Diffs of the changes: (+27 -21) PowerPCSubtarget.cpp | 48 +++++++++++++++++++++++++++--------------------- 1 files changed, 27 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.5 llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.6 --- llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp:1.5 Fri Sep 2 13:33:05 2005 +++ llvm/lib/Target/PowerPC/PowerPCSubtarget.cpp Fri Sep 2 14:27:43 2005 @@ -40,25 +40,31 @@ /// Sorted (by key) array of values for CPU subtype. static const SubtargetFeatureKV PowerPCSubTypeKV[] = { - { "601" , 0 }, - { "602" , 0 }, - { "603" , 0 }, - { "603e" , 0 }, - { "603ev" , 0 }, - { "604" , 0 }, - { "604e" , 0 }, - { "620" , 0 }, - { "7400" , PowerPCFeatureAltivec }, - { "7450" , PowerPCFeatureAltivec }, - { "750" , 0 }, - { "970" , PowerPCFeature64Bit | PowerPCFeatureAltivec | + { "601" , "Select the PowerPC 601 processor", 0 }, + { "602" , "Select the PowerPC 602 processor", 0 }, + { "603" , "Select the PowerPC 603 processor", 0 }, + { "603e" , "Select the PowerPC 603e processor", 0 }, + { "603ev" , "Select the PowerPC 603ev processor", 0 }, + { "604" , "Select the PowerPC 604 processor", 0 }, + { "604e" , "Select the PowerPC 604e processor", 0 }, + { "620" , "Select the PowerPC 620 processor", 0 }, + { "7400" , "Select the PowerPC 7400 (G4) processor", + PowerPCFeatureAltivec }, + { "7450" , "Select the PowerPC 7450 (G4+) processor", + PowerPCFeatureAltivec }, + { "750" , "Select the PowerPC 750 (G3) processor", 0 }, + { "970" , "Select the PowerPC 970 (G5 - GPUL) processor", + PowerPCFeature64Bit | PowerPCFeatureAltivec | PowerPCFeatureFSqrt | PowerPCFeatureGPUL }, - { "g3" , 0 }, - { "g4" , PowerPCFeatureAltivec }, - { "g4+" , PowerPCFeatureAltivec }, - { "g5" , PowerPCFeature64Bit | PowerPCFeatureAltivec | + { "g3" , "Select the PowerPC G3 (750) processor", 0 }, + { "g4" , "Select the PowerPC G4 (7400) processor", + PowerPCFeatureAltivec }, + { "g4+" , "Select the PowerPC G4+ (7450) processor", + PowerPCFeatureAltivec }, + { "g5" , "Select the PowerPC g5 (970 - GPUL) processor", + PowerPCFeature64Bit | PowerPCFeatureAltivec | PowerPCFeatureFSqrt | PowerPCFeatureGPUL }, - { "generic", 0 } + { "generic", "Select instructions for a generic PowerPC processor", 0 } }; /// Length of PowerPCSubTypeKV. static const unsigned PowerPCSubTypeKVSize = sizeof(PowerPCSubTypeKV) @@ -66,10 +72,10 @@ /// Sorted (by key) array of values for CPU features. static SubtargetFeatureKV PowerPCFeatureKV[] = { - { "64bit" , PowerPCFeature64Bit }, - { "altivec", PowerPCFeatureAltivec }, - { "fsqrt" , PowerPCFeatureFSqrt }, - { "gpul" , PowerPCFeatureGPUL } + { "64bit" , "Should 64 bit instructions be used" , PowerPCFeature64Bit }, + { "altivec", "Should Altivec instructions be used" , PowerPCFeatureAltivec }, + { "fsqrt" , "Should the fsqrt instruction be used", PowerPCFeatureFSqrt }, + { "gpul" , "Should GPUL instructions be used" , PowerPCFeatureGPUL } }; /// Length of PowerPCFeatureKV. static const unsigned PowerPCFeatureKVSize = sizeof(PowerPCFeatureKV) From jlaskey at apple.com Fri Sep 2 14:27:57 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 2 Sep 2005 14:27:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SubtargetFeature.cpp Message-ID: <200509021927.OAA26566@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: SubtargetFeature.cpp updated: 1.2 -> 1.3 --- Log message: Add help support for -mcpu and -mattr. --- Diffs of the changes: (+27 -0) SubtargetFeature.cpp | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm/lib/Target/SubtargetFeature.cpp diff -u llvm/lib/Target/SubtargetFeature.cpp:1.2 llvm/lib/Target/SubtargetFeature.cpp:1.3 --- llvm/lib/Target/SubtargetFeature.cpp:1.2 Thu Sep 1 21:51:42 2005 +++ llvm/lib/Target/SubtargetFeature.cpp Fri Sep 2 14:27:43 2005 @@ -99,6 +99,29 @@ return F; } +/// Display help for feature choices. +void SubtargetFeatures::Help(const char *Heading, + const SubtargetFeatureKV *Table, size_t TableSize) { + // Determine the length of the longest key + size_t MaxLen = 0; + for (size_t i = 0; i < TableSize; i++) + MaxLen = std::max(MaxLen, std::strlen(Table[i].Key)); + // Print heading + std::cerr << "Help for " << Heading << " choices\n\n"; + // For each feature + for (size_t i = 0; i < TableSize; i++) { + // Compute required padding + size_t Pad = MaxLen - std::strlen(Table[i].Key) + 1; + // Print details + std::cerr << Table[i].Key << std::string(Pad, ' ') << " - " + << Table[i].Desc << "\n"; + } + // Wrap it up + std::cerr << "\n\n"; + // Leave tool + exit(1); +} + /// Parse feature string for quick usage. uint32_t SubtargetFeatures::Parse(const std::string &String, const std::string &DefaultCPU, @@ -124,6 +147,8 @@ Split(Features, String); // Check if default is needed if (Features[0].empty()) Features[0] = DefaultCPU; + // Check for help + if (Features[0] == "help") Help("CPU", CPUTable, CPUTableSize); // Find CPU entry const SubtargetFeatureKV *CPUEntry = Find(Features[0], CPUTable, CPUTableSize); @@ -141,6 +166,8 @@ for (size_t i = 1; i < Features.size(); i++) { // Get next feature const std::string &Feature = Features[i]; + // Check for help + if (Feature == "+help") Help("feature", FeatureTable, FeatureTableSize); // Find feature in table. const SubtargetFeatureKV *FeatureEntry = Find(StripFlag(Feature), FeatureTable, FeatureTableSize); From jlaskey at apple.com Fri Sep 2 14:27:56 2005 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 2 Sep 2005 14:27:56 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200509021927.OAA26562@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.112 -> 1.113 --- Log message: Add help support for -mcpu and -mattr. --- Diffs of the changes: (+3 -3) llc.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.112 llvm/tools/llc/llc.cpp:1.113 --- llvm/tools/llc/llc.cpp:1.112 Thu Sep 1 16:38:21 2005 +++ llvm/tools/llc/llc.cpp Fri Sep 2 14:27:43 2005 @@ -50,15 +50,15 @@ static cl::opt MCPU("mcpu", - cl::desc("Target a specific cpu type"), + cl::desc("Target a specific cpu type (-mcpu=help for list of choices)"), cl::value_desc("cpu-name"), cl::init("")); static cl::list MAttrs("mattr", cl::CommaSeparated, - cl::desc("Target specific attributes:"), - cl::value_desc("attributes")); + cl::desc("Target specific attributes (-mattr=help for list of choices)"), + cl::value_desc("attr1,+attr2, ..., -attrN")); cl::opt FileType("filetype", cl::init(TargetMachine::AssemblyFile), From lattner at cs.uiuc.edu Fri Sep 2 14:35:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 14:35:53 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200509021935.OAA26698@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.59 -> 1.60 --- Log message: add a map for nullary ops --- Diffs of the changes: (+1 -0) SelectionDAG.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.59 llvm/include/llvm/CodeGen/SelectionDAG.h:1.60 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.59 Wed Aug 31 19:19:25 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Fri Sep 2 14:35:42 2005 @@ -356,6 +356,7 @@ SDOperand N4, ISD::CondCode CC); // Maps to auto-CSE operations. + std::map, SDNode *> NullaryOps; std::map >, SDNode *> UnaryOps; std::map >, From lattner at cs.uiuc.edu Fri Sep 2 14:36:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 14:36:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509021936.OAA26758@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.184 -> 1.185 --- Log message: Make sure to auto-cse nullary ops --- Diffs of the changes: (+9 -3) SelectionDAG.cpp | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.184 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.185 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.184 Fri Sep 2 14:15:44 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 2 14:36:17 2005 @@ -326,7 +326,10 @@ break; default: if (N->getNumValues() == 1) { - if (N->getNumOperands() == 1) { + if (N->getNumOperands() == 0) { + Erased = NullaryOps.erase(std::make_pair(N->getOpcode(), + N->getValueType(0))); + } else if (N->getNumOperands() == 1) { Erased = UnaryOps.erase(std::make_pair(N->getOpcode(), std::make_pair(N->getOperand(0), @@ -1010,8 +1013,11 @@ /// getNode - Gets or creates the specified node. /// SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) { - SDNode *N = new SDNode(Opcode, VT); - AllNodes.push_back(N); + SDNode *&N = NullaryOps[std::make_pair(Opcode, VT)]; + if (!N) { + N = new SDNode(Opcode, VT); + AllNodes.push_back(N); + } return SDOperand(N, 0); } From lattner at cs.uiuc.edu Fri Sep 2 14:51:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 14:51:35 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200509021951.OAA26994@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.167 -> 1.168 --- Log message: This is no longer the beta option --- 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.167 llvm-test/Makefile.programs:1.168 --- llvm-test/Makefile.programs:1.167 Fri Aug 26 16:26:42 2005 +++ llvm-test/Makefile.programs Fri Sep 2 14:51:24 2005 @@ -187,7 +187,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -enable-ppc-dag-isel +LLCBETAOPTION := endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-alpha-FTOI -enable-lsr-for-alpha From lattner at cs.uiuc.edu Fri Sep 2 14:54:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 14:54:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Message-ID: <200509021954.OAA27066@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCTargetMachine.cpp updated: 1.66 -> 1.67 --- Log message: turn on dag isel by default --- Diffs of the changes: (+3 -3) PowerPCTargetMachine.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.66 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.67 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.66 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Fri Sep 2 14:53:54 2005 @@ -32,8 +32,8 @@ namespace { const char *PPC32ID = "PowerPC/32bit"; - static cl::opt EnablePPCDAGDAG("enable-ppc-dag-isel", cl::Hidden, - cl::desc("Enable DAG-to-DAG isel for PPC (beta)")); + static cl::opt DisablePPCDAGDAG("disable-ppc-dag-isel", cl::Hidden, + cl::desc("Disable DAG-to-DAG isel for PPC")); // Register the targets RegisterTarget @@ -86,7 +86,7 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - if (EnablePPCDAGDAG) + if (!DisablePPCDAGDAG) PM.add(createPPC32ISelDag(*this)); else PM.add(createPPC32ISelPattern(*this)); From lattner at cs.uiuc.edu Fri Sep 2 15:24:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 15:24:21 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll Message-ID: <200509022024.PAA27411@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: 2005-09-02-LegalizeDuplicatesCalls.ll added (r1.1) --- Log message: Test that converting from double to int64 results in one libcall, not one and a dead one. This is a legalize bug --- Diffs of the changes: (+9 -0) 2005-09-02-LegalizeDuplicatesCalls.ll | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll:1.1 *** /dev/null Fri Sep 2 15:24:20 2005 --- llvm/test/Regression/CodeGen/PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll Fri Sep 2 15:24:10 2005 *************** *** 0 **** --- 1,9 ---- + ; This function should have exactly one call to fixdfdi, no more! + + ; RUN: llvm-as < %s | llc -march=ppc32 | grep 'bl .*fixdfdi' | wc -l | grep 1 + + double %test2(double %tmp.7705) { + %mem_tmp.2.0.in = cast double %tmp.7705 to long ; [#uses=1] + %mem_tmp.2.0 = cast long %mem_tmp.2.0.in to double + ret double %mem_tmp.2.0 + } From lattner at cs.uiuc.edu Fri Sep 2 15:27:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 15:27:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200509022027.PAA27490@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.183 -> 1.184 --- Log message: Fix a bug in legalize where it would emit two calls to libcalls that return i64 values on targets that need that expanded to 32-bit registers. This fixes PowerPC/2005-09-02-LegalizeDuplicatesCalls.ll and speeds up 189.lucas from taking 122.72s to 81.96s on my desktop. --- Diffs of the changes: (+13 -10) LegalizeDAG.cpp | 23 +++++++++++++---------- 1 files changed, 13 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.183 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.184 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.183 Thu Sep 1 20:15:01 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Sep 2 15:26:58 2005 @@ -1996,7 +1996,7 @@ SDOperand Result; SDNode *Node = Op.Val; - if (!Node->hasOneUse()) { + if (1 || !Node->hasOneUse()) { std::map::iterator I = PromotedNodes.find(Op); if (I != PromotedNodes.end()) return I->second; } else { @@ -2709,21 +2709,24 @@ std::pair CallInfo = TLI.LowerCallTo(InChain, RetTy, false, CallingConv::C, false, Callee, Args, DAG); - SpliceCallInto(CallInfo.second, OutChain); - - NeedsAnotherIteration = true; + SDOperand Result; switch (getTypeAction(CallInfo.first.getValueType())) { default: assert(0 && "Unknown thing"); case Legal: - return CallInfo.first; + Result = CallInfo.first; + break; case Promote: assert(0 && "Cannot promote this yet!"); case Expand: - SDOperand Lo; - ExpandOp(CallInfo.first, Lo, Hi); - return Lo; + ExpandOp(CallInfo.first, Result, Hi); + CallInfo.second = LegalizeOp(CallInfo.second); + break; } + + SpliceCallInto(CallInfo.second, OutChain); + NeedsAnotherIteration = true; + return Result; } @@ -2845,7 +2848,7 @@ // If there is more than one use of this, see if we already expanded it. // There is no use remembering values that only have a single use, as the map // entries will never be reused. - if (!Node->hasOneUse()) { + if (1 || !Node->hasOneUse()) { std::map >::iterator I = ExpandedNodes.find(Op); if (I != ExpandedNodes.end()) { @@ -3259,7 +3262,7 @@ } // Remember in a map if the values will be reused later. - if (!Node->hasOneUse()) { + if (1 || !Node->hasOneUse()) { bool isNew = ExpandedNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second; assert(isNew && "Value already expanded?!?"); From lattner at cs.uiuc.edu Fri Sep 2 15:32:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 15:32:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200509022032.PAA27605@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.184 -> 1.185 --- Log message: Clean up some code from the last checkin --- Diffs of the changes: (+12 -24) LegalizeDAG.cpp | 36 ++++++++++++------------------------ 1 files changed, 12 insertions(+), 24 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.184 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.185 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.184 Fri Sep 2 15:26:58 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Sep 2 15:32:45 2005 @@ -1996,12 +1996,8 @@ SDOperand Result; SDNode *Node = Op.Val; - if (1 || !Node->hasOneUse()) { - std::map::iterator I = PromotedNodes.find(Op); - if (I != PromotedNodes.end()) return I->second; - } else { - assert(!PromotedNodes.count(Op) && "Repromoted this node??"); - } + std::map::iterator I = PromotedNodes.find(Op); + if (I != PromotedNodes.end()) return I->second; // Promotion needs an optimization step to clean up after it, and is not // careful to avoid operations the target does not support. Make sure that @@ -2845,19 +2841,13 @@ assert(MVT::isInteger(NVT) && NVT < VT && "Cannot expand to FP value or to larger int value!"); - // If there is more than one use of this, see if we already expanded it. - // There is no use remembering values that only have a single use, as the map - // entries will never be reused. - if (1 || !Node->hasOneUse()) { - std::map >::iterator I - = ExpandedNodes.find(Op); - if (I != ExpandedNodes.end()) { - Lo = I->second.first; - Hi = I->second.second; - return; - } - } else { - assert(!ExpandedNodes.count(Op) && "Re-expanding a node!"); + // See if we already expanded it. + std::map >::iterator I + = ExpandedNodes.find(Op); + if (I != ExpandedNodes.end()) { + Lo = I->second.first; + Hi = I->second.second; + return; } // Expanding to multiple registers needs to perform an optimization step, and @@ -3262,11 +3252,9 @@ } // Remember in a map if the values will be reused later. - if (1 || !Node->hasOneUse()) { - bool isNew = ExpandedNodes.insert(std::make_pair(Op, - std::make_pair(Lo, Hi))).second; - assert(isNew && "Value already expanded?!?"); - } + bool isNew = ExpandedNodes.insert(std::make_pair(Op, + std::make_pair(Lo, Hi))).second; + assert(isNew && "Value already expanded?!?"); } From lattner at cs.uiuc.edu Fri Sep 2 16:18:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 16:18:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td PowerPCInstrInfo.td Message-ID: <200509022118.QAA28276@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrFormats.td updated: 1.45 -> 1.46 PowerPCInstrInfo.td updated: 1.86 -> 1.87 --- Log message: Add some initial patterns to simple binary instructions, though they currently don't do anything. This elides patterns for binary operators that ping on the carry flag, since we don't model it yet. This patch also removes PPC::SUB, because it is dead. --- Diffs of the changes: (+43 -25) PowerPCInstrFormats.td | 13 ++++------- PowerPCInstrInfo.td | 55 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 25 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.45 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.46 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.45 Thu Aug 25 23:11:42 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Fri Sep 2 16:18:00 2005 @@ -424,12 +424,15 @@ } // 1.7.11 XO-Form -class XOForm_1 opcode, bits<9> xo, bit oe, dag OL, string asmstr> +class XOForm_1 opcode, bits<9> xo, bit oe, dag OL, string asmstr, + list pattern> : I { bits<5> RT; bits<5> RA; bits<5> RB; + let Pattern = pattern; + bit RC = 0; // set by isDOT let Inst{6-10} = RT; @@ -440,15 +443,9 @@ let Inst{31} = RC; } -class XOForm_1r opcode, bits<9> xo, bit oe, dag OL, string asmstr> - : XOForm_1 { - let Inst{11-15} = RB; - let Inst{16-20} = RA; -} - class XOForm_3 opcode, bits<9> xo, bit oe, dag OL, string asmstr> - : XOForm_1 { + : XOForm_1 { let RB = 0; } Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.86 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.87 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.86 Fri Aug 26 18:42:05 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Fri Sep 2 16:18:00 2005 @@ -14,6 +14,15 @@ include "PowerPCInstrFormats.td" +def set; +def mul; +def udiv; +def sdiv; +def sub; +def add; +def mulhs; +def mulhu; + class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } class isDOT { @@ -70,7 +79,7 @@ def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F, i32imm:$BROPC), "; SELECT_CC PSEUDO!">; def SELECT_CC_FP : Pseudo<(ops FPRC:$dst, CRRC:$cond, FPRC:$T, FPRC:$F, - i32imm:$BROPC), "; SELECT_CC PSEUDO!">; + i32imm:$BROPC), "; SELECT_CC PSEUDO!">; } @@ -364,35 +373,47 @@ // XO-Form instructions. Arithmetic instructions that can set overflow bit // def ADD : XOForm_1<31, 266, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "add $rT, $rA, $rB">; + "add $rT, $rA, $rB", + [(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>; def ADDC : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "addc $rT, $rA, $rB">; + "addc $rT, $rA, $rB", + []>; def ADDE : XOForm_1<31, 138, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "adde $rT, $rA, $rB">; + "adde $rT, $rA, $rB", + []>; def DIVD : XOForm_1<31, 489, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divd $rT, $rA, $rB">, isPPC64; + "divd $rT, $rA, $rB", + []>, isPPC64; def DIVDU : XOForm_1<31, 457, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divdu $rT, $rA, $rB">, isPPC64; + "divdu $rT, $rA, $rB", + []>, isPPC64; def DIVW : XOForm_1<31, 491, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divw $rT, $rA, $rB">; + "divw $rT, $rA, $rB", + [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>; def DIVWU : XOForm_1<31, 459, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divwu $rT, $rA, $rB">; + "divwu $rT, $rA, $rB", + [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>; def MULHW : XOForm_1<31, 75, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mulhw $rT, $rA, $rB">; + "mulhw $rT, $rA, $rB", + [(set GPRC:$rT, (mulhs GPRC:$rA, GPRC:$rB))]>; def MULHWU : XOForm_1<31, 11, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mulhwu $rT, $rA, $rB">; + "mulhwu $rT, $rA, $rB", + [(set GPRC:$rT, (mulhu GPRC:$rA, GPRC:$rB))]>; def MULLD : XOForm_1<31, 233, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mulld $rT, $rA, $rB">, isPPC64; + "mulld $rT, $rA, $rB", + []>, isPPC64; def MULLW : XOForm_1<31, 235, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mullw $rT, $rA, $rB">; + "mullw $rT, $rA, $rB", + [(set GPRC:$rT, (mul GPRC:$rA, GPRC:$rB))]>; def SUBF : XOForm_1<31, 40, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "subf $rT, $rA, $rB">; + "subf $rT, $rA, $rB", + [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>; def SUBFC : XOForm_1<31, 8, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "subfc $rT, $rA, $rB">; + "subfc $rT, $rA, $rB", + []>; def SUBFE : XOForm_1<31, 136, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "subfe $rT, $rA, $rB">; -def SUB : XOForm_1r<31, 40, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "sub $rT, $rA, $rB">; + "subfe $rT, $rA, $rB", + []>; def ADDME : XOForm_3<31, 234, 0, (ops GPRC:$rT, GPRC:$rA), "addme $rT, $rA">; def ADDZE : XOForm_3<31, 202, 0, (ops GPRC:$rT, GPRC:$rA), From natebegeman at mac.com Fri Sep 2 16:18:51 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 2 Sep 2005 16:18:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200509022118.QAA28299@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.3 -> 1.4 --- Log message: Next round of DAG Combiner changes. Just need to support multiple return values, and then we should be able to hook it up. --- Diffs of the changes: (+325 -302) DAGCombiner.cpp | 627 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 325 insertions(+), 302 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.3 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.4 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.3 Thu Sep 1 18:24:04 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Sep 2 16:18:40 2005 @@ -28,9 +28,13 @@ // EVT != MVT::i1 can drop the sext. // FIXME: (or x, c) -> c iff maskedValueIsZero(x, ~c) // FIXME: MaskedValueIsZero can see through SRL, so it should be sufficient to: -//if (N2C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) +//if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) // return DAG.getConstant(0, VT).Val; // FIXME: (sra (sra x, c1), c2) -> (sra x, c1+c2) +// FIXME: verify that getNode can't return extends with an operand whose type +// is >= to that of the extend. +// FIXME: divide by zero is currently left unfolded. do we want to turn this +// into an undef? // //===----------------------------------------------------------------------===// @@ -80,54 +84,47 @@ // otherwise - Node N should be replaced by the returned node. // SDNode *visitTokenFactor(SDNode *N); - SDNode *visitAdd(SDNode *N); - SDNode *visitSub(SDNode *N); - SDNode *visitMul(SDNode *N); - SDNode *visitSdiv(SDNode *N); - SDNode *visitUdiv(SDNode *N); - SDNode *visitSrem(SDNode *N); - SDNode *visitUrem(SDNode *N); - SDNode *visitMulHiU(SDNode *N); - SDNode *visitMulHiS(SDNode *N); - SDNode *visitAnd(SDNode *N); - SDNode *visitOr(SDNode *N); - SDNode *visitXor(SDNode *N); - SDNode *visitShl(SDNode *N); - SDNode *visitSra(SDNode *N); - SDNode *visitSrl(SDNode *N); - SDNode *visitCtlz(SDNode *N); - SDNode *visitCttz(SDNode *N); - SDNode *visitCtpop(SDNode *N); + SDNode *visitADD(SDNode *N); + SDNode *visitSUB(SDNode *N); + SDNode *visitMUL(SDNode *N); + SDNode *visitSDIV(SDNode *N); + SDNode *visitUDIV(SDNode *N); + SDNode *visitSREM(SDNode *N); + SDNode *visitUREM(SDNode *N); + SDNode *visitMULHU(SDNode *N); + SDNode *visitMULHS(SDNode *N); + SDNode *visitAND(SDNode *N); + SDNode *visitOR(SDNode *N); + SDNode *visitXOR(SDNode *N); + SDNode *visitSHL(SDNode *N); + SDNode *visitSRA(SDNode *N); + SDNode *visitSRL(SDNode *N); + SDNode *visitCTLZ(SDNode *N); + SDNode *visitCTTZ(SDNode *N); + SDNode *visitCTPOP(SDNode *N); // select // select_cc // setcc - SDNode *visitSignExtend(SDNode *N); - SDNode *visitZeroExtend(SDNode *N); - SDNode *visitSignExtendInReg(SDNode *N); - SDNode *visitTruncate(SDNode *N); - SDNode *visitSintToFP(SDNode *N); - SDNode *visitUintToFP(SDNode *N); - SDNode *visitFPToSint(SDNode *N); - SDNode *visitFPToUint(SDNode *N); - SDNode *visitFPRound(SDNode *N); - SDNode *visitFPRoundInReg(SDNode *N); - SDNode *visitFPExtend(SDNode *N); - SDNode *visitFneg(SDNode *N); - SDNode *visitFabs(SDNode *N); - SDNode *visitExtLoad(SDNode *N); - SDNode *visitSextLoad(SDNode *N); - SDNode *visitZextLoad(SDNode *N); - SDNode *visitTruncStore(SDNode *N); + SDNode *visitSIGN_EXTEND(SDNode *N); + SDNode *visitZERO_EXTEND(SDNode *N); + SDNode *visitSIGN_EXTEND_INREG(SDNode *N); + SDNode *visitTRUNCATE(SDNode *N); + SDNode *visitSINT_TO_FP(SDNode *N); + SDNode *visitUINT_TO_FP(SDNode *N); + SDNode *visitFP_TO_SINT(SDNode *N); + SDNode *visitFP_TO_UINT(SDNode *N); + SDNode *visitFP_ROUND(SDNode *N); + SDNode *visitFP_ROUND_INREG(SDNode *N); + SDNode *visitFP_EXTEND(SDNode *N); + SDNode *visitFNEG(SDNode *N); + SDNode *visitFABS(SDNode *N); // brcond // brcondtwoway // br_cc // brtwoway_cc public: DAGCombiner(SelectionDAG &D) - : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) { - // Add all the dag nodes to the worklist. - WorkList.insert(WorkList.end(), D.allnodes_begin(), D.allnodes_end()); - } + : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) {} /// Run - runs the dag combiner on all nodes in the work list void Run(bool RunningAfterLegalize); @@ -147,6 +144,7 @@ case ISD::Constant: return (cast(Op)->getValue() & Mask) == 0; case ISD::SETCC: + // FIXME: teach this about non ZeroOrOne values, such as 0 or -1 return ((Mask & 1) == 0) && TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; case ISD::ZEXTLOAD: @@ -204,23 +202,36 @@ // isSetCCEquivalent - Return true if this node is a setcc, or is a select_cc // that selects between the values 1 and 0, making it equivalent to a setcc. -static bool isSetCCEquivalent(SDOperand N) { - if (N.getOpcode() == ISD::SETCC) +// Also, set the incoming LHS, RHS, and CC references to the appropriate +// nodes based on the type of node we are checking. This simplifies life a +// bit for the callers. +static bool isSetCCEquivalent(SDOperand N, SDOperand &LHS, SDOperand &RHS, + SDOperand &CC) { + if (N.getOpcode() == ISD::SETCC) { + LHS = N.getOperand(0); + RHS = N.getOperand(1); + CC = N.getOperand(2); return true; + } if (N.getOpcode() == ISD::SELECT_CC && N.getOperand(2).getOpcode() == ISD::Constant && N.getOperand(3).getOpcode() == ISD::Constant && cast(N.getOperand(2))->getValue() == 1 && - cast(N.getOperand(3))->isNullValue()) + cast(N.getOperand(3))->isNullValue()) { + LHS = N.getOperand(0); + RHS = N.getOperand(1); + CC = N.getOperand(4); return true; + } return false; } // isInvertibleForFree - Return true if there is no cost to emitting the logical // inverse of this node. static bool isInvertibleForFree(SDOperand N) { + SDOperand N0, N1, N2; if (isa(N.Val)) return true; - if (isSetCCEquivalent(N) && N.Val->hasOneUse()) + if (isSetCCEquivalent(N, N0, N1, N2) && N.Val->hasOneUse()) return true; return false; } @@ -229,6 +240,9 @@ // set the instance variable, so that the various visit routines may use it. AfterLegalize = RunningAfterLegalize; + // Add all the dag nodes to the worklist. + WorkList.insert(WorkList.end(), DAG.allnodes_begin(), DAG.allnodes_end()); + // while the worklist isn't empty, inspect the node on the end of it and // try and combine it. while (!WorkList.empty()) { @@ -248,20 +262,21 @@ if (SDNode *Result = visit(N)) { ++NodesCombined; - assert(Result != N && "Modifying DAG nodes in place is illegal!"); - - std::cerr << "DC: Old = "; N->dump(); - std::cerr << " New = "; Result->dump(); - std::cerr << '\n'; - DAG.ReplaceAllUsesWith(N, Result); - - // Push the new node and any users onto the worklist - WorkList.push_back(Result); - AddUsersToWorkList(Result); - - // Nodes can end up on the worklist more than once. Make sure we do - // not process a node that has been replaced. - removeFromWorkList(N); + // If we get back the same node we passed in, rather than a new node or + // zero, we know that the node must have defined multiple values and + // CombineTo was used. Since CombineTo takes care of the worklist + // mechanics for us, we have no work to do in this case. + if (Result != N) { + DAG.ReplaceAllUsesWith(N, Result); + + // Push the new node and any users onto the worklist + WorkList.push_back(Result); + AddUsersToWorkList(Result); + + // Nodes can end up on the worklist more than once. Make sure we do + // not process a node that has been replaced. + removeFromWorkList(N); + } } } } @@ -270,37 +285,37 @@ switch(N->getOpcode()) { default: break; case ISD::TokenFactor: return visitTokenFactor(N); - case ISD::ADD: return visitAdd(N); - case ISD::SUB: return visitSub(N); - case ISD::MUL: return visitMul(N); - case ISD::SDIV: return visitSdiv(N); - case ISD::UDIV: return visitUdiv(N); - case ISD::SREM: return visitSrem(N); - case ISD::UREM: return visitUrem(N); - case ISD::MULHU: return visitMulHiU(N); - case ISD::MULHS: return visitMulHiS(N); - case ISD::AND: return visitAnd(N); - case ISD::OR: return visitOr(N); - case ISD::XOR: return visitXor(N); - case ISD::SHL: return visitShl(N); - case ISD::SRA: return visitSra(N); - case ISD::SRL: return visitSrl(N); - case ISD::CTLZ: return visitCtlz(N); - case ISD::CTTZ: return visitCttz(N); - case ISD::CTPOP: return visitCtpop(N); - case ISD::SIGN_EXTEND: return visitSignExtend(N); - case ISD::ZERO_EXTEND: return visitZeroExtend(N); - case ISD::SIGN_EXTEND_INREG: return visitSignExtendInReg(N); - case ISD::TRUNCATE: return visitTruncate(N); - case ISD::SINT_TO_FP: return visitSintToFP(N); - case ISD::UINT_TO_FP: return visitUintToFP(N); - case ISD::FP_TO_SINT: return visitFPToSint(N); - case ISD::FP_TO_UINT: return visitFPToUint(N); - case ISD::FP_ROUND: return visitFPRound(N); - case ISD::FP_ROUND_INREG: return visitFPRoundInReg(N); - case ISD::FP_EXTEND: return visitFPExtend(N); - case ISD::FNEG: return visitFneg(N); - case ISD::FABS: return visitFabs(N); + case ISD::ADD: return visitADD(N); + case ISD::SUB: return visitSUB(N); + case ISD::MUL: return visitMUL(N); + case ISD::SDIV: return visitSDIV(N); + case ISD::UDIV: return visitUDIV(N); + case ISD::SREM: return visitSREM(N); + case ISD::UREM: return visitUREM(N); + case ISD::MULHU: return visitMULHU(N); + case ISD::MULHS: return visitMULHS(N); + case ISD::AND: return visitAND(N); + case ISD::OR: return visitOR(N); + case ISD::XOR: return visitXOR(N); + case ISD::SHL: return visitSHL(N); + case ISD::SRA: return visitSRA(N); + case ISD::SRL: return visitSRL(N); + case ISD::CTLZ: return visitCTLZ(N); + case ISD::CTTZ: return visitCTTZ(N); + case ISD::CTPOP: return visitCTPOP(N); + case ISD::SIGN_EXTEND: return visitSIGN_EXTEND(N); + case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N); + case ISD::SIGN_EXTEND_INREG: return visitSIGN_EXTEND_INREG(N); + case ISD::TRUNCATE: return visitTRUNCATE(N); + case ISD::SINT_TO_FP: return visitSINT_TO_FP(N); + case ISD::UINT_TO_FP: return visitUINT_TO_FP(N); + case ISD::FP_TO_SINT: return visitFP_TO_SINT(N); + case ISD::FP_TO_UINT: return visitFP_TO_UINT(N); + case ISD::FP_ROUND: return visitFP_ROUND(N); + case ISD::FP_ROUND_INREG: return visitFP_ROUND_INREG(N); + case ISD::FP_EXTEND: return visitFP_EXTEND(N); + case ISD::FNEG: return visitFNEG(N); + case ISD::FABS: return visitFABS(N); } return 0; } @@ -321,24 +336,24 @@ return 0; } -SDNode *DAGCombiner::visitAdd(SDNode *N) { +SDNode *DAGCombiner::visitADD(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); - ConstantFPSDNode *N1CFP = dyn_cast(N0); - ConstantFPSDNode *N2CFP = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); + ConstantFPSDNode *N0CFP = dyn_cast(N0); + ConstantFPSDNode *N1CFP = dyn_cast(N1); // fold (add c1, c2) -> c1+c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() + N2C->getValue(), + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() + N1C->getValue(), N->getValueType(0)).Val; // fold (add x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // fold floating point (add c1, c2) -> c1+c2 - if (N1CFP && N2CFP) - return DAG.getConstantFP(N1CFP->getValue() + N2CFP->getValue(), + if (N0CFP && N1CFP) + return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), N->getValueType(0)).Val; // fold (A + (-B)) -> A-B if (N1.getOpcode() == ISD::FNEG) @@ -361,24 +376,24 @@ return 0; } -SDNode *DAGCombiner::visitSub(SDNode *N) { +SDNode *DAGCombiner::visitSUB(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + ConstantSDNode *N0C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N1.Val); + ConstantFPSDNode *N0CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); // fold (sub c1, c2) -> c1-c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() - N2C->getValue(), + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() - N1C->getValue(), N->getValueType(0)).Val; // fold (sub x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // fold floating point (sub c1, c2) -> c1-c2 - if (N1CFP && N2CFP) - return DAG.getConstantFP(N1CFP->getValue() - N2CFP->getValue(), + if (N0CFP && N1CFP) + return DAG.getConstantFP(N0CFP->getValue() - N1CFP->getValue(), N->getValueType(0)).Val; // fold (A+B)-A -> B if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1 && @@ -394,157 +409,158 @@ return 0; } -SDNode *DAGCombiner::visitMul(SDNode *N) { +SDNode *DAGCombiner::visitMUL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); - ConstantFPSDNode *N1CFP = dyn_cast(N0); - ConstantFPSDNode *N2CFP = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); + ConstantFPSDNode *N0CFP = dyn_cast(N0); + ConstantFPSDNode *N1CFP = dyn_cast(N1); // fold (mul c1, c2) -> c1*c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() * N2C->getValue(), + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() * N1C->getValue(), N->getValueType(0)).Val; // fold (mul x, 0) -> 0 - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N1.Val; // fold (mul x, -1) -> 0-x - if (N2C && N2C->isAllOnesValue()) + if (N1C && N1C->isAllOnesValue()) return DAG.getNode(ISD::SUB, N->getValueType(0), DAG.getConstant(0, N->getValueType(0)), N0).Val; // fold (mul x, (1 << c)) -> x << c - if (N2C && isPowerOf2_64(N2C->getValue())) + if (N1C && isPowerOf2_64(N1C->getValue())) return DAG.getNode(ISD::SHL, N->getValueType(0), N0, - DAG.getConstant(Log2_64(N2C->getValue()), + DAG.getConstant(Log2_64(N1C->getValue()), TLI.getShiftAmountTy())).Val; // fold floating point (mul c1, c2) -> c1*c2 - if (N1CFP && N2CFP) - return DAG.getConstantFP(N1CFP->getValue() * N2CFP->getValue(), + if (N0CFP && N1CFP) + return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitSdiv(SDNode *N) { +SDNode *DAGCombiner::visitSDIV(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); - ConstantFPSDNode *N1CFP = dyn_cast(N0.Val); - ConstantFPSDNode *N2CFP = dyn_cast(N1.Val); + ConstantSDNode *N0C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N1.Val); + ConstantFPSDNode *N0CFP = dyn_cast(N0.Val); + ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); // fold (sdiv c1, c2) -> c1/c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getSignExtended() / N2C->getSignExtended(), + if (N0C && N1C && !N1C->isNullValue()) + return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(), N->getValueType(0)).Val; // fold floating point (sdiv c1, c2) -> c1/c2 - if (N1CFP && N2CFP) - return DAG.getConstantFP(N1CFP->getValue() / N2CFP->getValue(), + if (N0CFP && N1CFP) + return DAG.getConstantFP(N0CFP->getValue() / N1CFP->getValue(), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitUdiv(SDNode *N) { +SDNode *DAGCombiner::visitUDIV(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0.Val); - ConstantSDNode *N2C = dyn_cast(N1.Val); + ConstantSDNode *N0C = dyn_cast(N0.Val); + ConstantSDNode *N1C = dyn_cast(N1.Val); // fold (udiv c1, c2) -> c1/c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() / N2C->getValue(), + if (N0C && N1C && !N1C->isNullValue()) + return DAG.getConstant(N0C->getValue() / N1C->getValue(), N->getValueType(0)).Val; // fold (udiv x, (1 << c)) -> x >>u c - if (N2C && isPowerOf2_64(N2C->getValue())) + if (N1C && isPowerOf2_64(N1C->getValue())) return DAG.getNode(ISD::SRL, N->getValueType(0), N0, - DAG.getConstant(Log2_64(N2C->getValue()), + DAG.getConstant(Log2_64(N1C->getValue()), TLI.getShiftAmountTy())).Val; return 0; } -SDNode *DAGCombiner::visitSrem(SDNode *N) { +SDNode *DAGCombiner::visitSREM(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); - ConstantFPSDNode *N1CFP = dyn_cast(N0); - ConstantFPSDNode *N2CFP = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); + ConstantFPSDNode *N0CFP = dyn_cast(N0); + ConstantFPSDNode *N1CFP = dyn_cast(N1); // fold (srem c1, c2) -> c1%c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getSignExtended() % N2C->getSignExtended(), + if (N0C && N1C && !N1C->isNullValue()) + return DAG.getConstant(N0C->getSignExtended() % N1C->getSignExtended(), N->getValueType(0)).Val; // fold floating point (srem c1, c2) -> fmod(c1, c2) - if (N1CFP && N2CFP) - return DAG.getConstantFP(fmod(N1CFP->getValue(),N2CFP->getValue()), + if (N0CFP && N1CFP) + return DAG.getConstantFP(fmod(N0CFP->getValue(),N1CFP->getValue()), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitUrem(SDNode *N) { +SDNode *DAGCombiner::visitUREM(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); // fold (urem c1, c2) -> c1%c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() % N2C->getValue(), + if (N0C && N1C && !N1C->isNullValue()) + return DAG.getConstant(N0C->getValue() % N1C->getValue(), N->getValueType(0)).Val; + // FIXME: c2 power of 2 -> mask? return 0; } -SDNode *DAGCombiner::visitMulHiS(SDNode *N) { +SDNode *DAGCombiner::visitMULHS(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N1C = dyn_cast(N1); // fold (mulhs x, 0) -> 0 - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N1.Val; // fold (mulhs x, 1) -> (sra x, size(x)-1) - if (N2C && N2C->getValue() == 1) + if (N1C && N1C->getValue() == 1) return DAG.getNode(ISD::SRA, N0.getValueType(), N0, DAG.getConstant(MVT::getSizeInBits(N0.getValueType())-1, TLI.getShiftAmountTy())).Val; return 0; } -SDNode *DAGCombiner::visitMulHiU(SDNode *N) { +SDNode *DAGCombiner::visitMULHU(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N1C = dyn_cast(N1); // fold (mulhu x, 0) -> 0 - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N1.Val; // fold (mulhu x, 1) -> 0 - if (N2C && N2C->getValue() == 1) + if (N1C && N1C->getValue() == 1) return DAG.getConstant(0, N0.getValueType()).Val; return 0; } -SDNode *DAGCombiner::visitAnd(SDNode *N) { +SDNode *DAGCombiner::visitAND(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); // fold (and c1, c2) -> c1&c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() & N2C->getValue(), VT).Val; + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() & N1C->getValue(), VT).Val; // fold (and x, -1) -> x - if (N2C && N2C->isAllOnesValue()) + if (N1C && N1C->isAllOnesValue()) return N0.Val; // fold (and x, 0) -> 0 - if (N2C && MaskedValueIsZero(N0, N2C->getValue(), TLI)) + if (N1C && MaskedValueIsZero(N0, N1C->getValue(), TLI)) return DAG.getConstant(0, VT).Val; // fold (and x, mask containing x) -> x - if (N2C) { - uint64_t NotC2 = ~N2C->getValue(); + if (N1C) { + uint64_t NotC2 = ~N1C->getValue(); NotC2 &= ~0ULL >> (64-MVT::getSizeInBits(VT)); if (MaskedValueIsZero(N0, NotC2, TLI)) return N0.Val; @@ -553,66 +569,65 @@ if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned ExtendBits = MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); - if ((N2C->getValue() & (~0ULL << ExtendBits)) == 0) + if ((N1C->getValue() & (~0ULL << ExtendBits)) == 0) return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1).Val; } // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF if (N0.getOpcode() == ISD::OR) if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) - if ((ORI->getValue() & N2C->getValue()) == N2C->getValue()) + if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1.Val; return 0; } -SDNode *DAGCombiner::visitOr(SDNode *N) { +SDNode *DAGCombiner::visitOR(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); // fold (or c1, c2) -> c1|c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() | N2C->getValue(), + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() | N1C->getValue(), N->getValueType(0)).Val; // fold (or x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // fold (or x, -1) -> -1 - if (N2C && N2C->isAllOnesValue()) + if (N1C && N1C->isAllOnesValue()) return N1.Val; return 0; } -SDNode *DAGCombiner::visitXor(SDNode *N) { +SDNode *DAGCombiner::visitXOR(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + SDOperand LHS, RHS, CC; + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); // fold (xor c1, c2) -> c1^c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() ^ N2C->getValue(), VT).Val; + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() ^ N1C->getValue(), VT).Val; // fold (xor x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // fold !(x cc y) -> (x !cc y) - if (N2C && N2C->getValue() == 1 && N0.getOpcode() == ISD::SETCC) { - bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); - ISD::CondCode CC = cast(N0.getOperand(2))->get(); - return DAG.getSetCC(VT, N0.getOperand(0), N0.getOperand(1), - ISD::getSetCCInverse(CC, isInt)).Val; - } - // fold !(x cc y) -> (x !cc y) - if (N2C && N2C->getValue() == 1 && isSetCCEquivalent(N0)) { - bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); - ISD::CondCode CC = cast(N0.getOperand(4))->get(); - return DAG.getSelectCC(N0.getOperand(0), N0.getOperand(1), - N0.getOperand(2), N0.getOperand(3), - ISD::getSetCCInverse(CC, isInt)).Val; + if (N1C && N1C->getValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) { + bool isInt = MVT::isInteger(LHS.getValueType()); + ISD::CondCode NotCC = ISD::getSetCCInverse(cast(CC)->get(), + isInt); + if (N0.getOpcode() == ISD::SETCC) + return DAG.getSetCC(VT, LHS, RHS, NotCC).Val; + if (N0.getOpcode() == ISD::SELECT_CC) + return DAG.getSelectCC(LHS, RHS, N0.getOperand(2), N0.getOperand(3), + NotCC).Val; + assert(0 && "Unhandled SetCC Equivalent!"); + abort(); } // fold !(x or y) -> (!x and !y) iff x or y are freely invertible - if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::OR) { + if (N1C && N1C->isAllOnesValue() && N0.getOpcode() == ISD::OR) { SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS @@ -621,7 +636,7 @@ } } // fold !(x and y) -> (!x or !y) iff x or y are freely invertible - if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::AND) { + if (N1C && N1C->isAllOnesValue() && N0.getOpcode() == ISD::AND) { SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS @@ -632,35 +647,35 @@ return 0; } -SDNode *DAGCombiner::visitShl(SDNode *N) { +SDNode *DAGCombiner::visitSHL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); unsigned OpSizeInBits = MVT::getSizeInBits(VT); // fold (shl c1, c2) -> c1<getValue() << N2C->getValue(), VT).Val; + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() << N1C->getValue(), VT).Val; // fold (shl 0, x) -> 0 - if (N1C && N1C->isNullValue()) + if (N0C && N0C->isNullValue()) return N0.Val; // fold (shl x, c >= size(x)) -> undef - if (N2C && N2C->getValue() >= OpSizeInBits) + if (N1C && N1C->getValue() >= OpSizeInBits) return DAG.getNode(ISD::UNDEF, VT).Val; // fold (shl x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // if (shl x, c) is known to be zero, return 0 - if (N2C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))>>N2C->getValue(), + if (N1C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))>>N1C->getValue(), TLI)) return DAG.getConstant(0, VT).Val; // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2) - if (N2C && N0.getOpcode() == ISD::SHL && + if (N1C && N0.getOpcode() == ISD::SHL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getValue(); - uint64_t c2 = N2C->getValue(); + uint64_t c2 = N1C->getValue(); if (c1 + c2 > OpSizeInBits) return DAG.getConstant(0, VT).Val; return DAG.getNode(ISD::SHL, VT, N0.getOperand(0), @@ -668,10 +683,10 @@ } // fold (shl (srl x, c1), c2) -> (shl (and x, -1 << c1), c2-c1) or // (srl (and x, -1 << c1), c1-c2) - if (N2C && N0.getOpcode() == ISD::SRL && + if (N1C && N0.getOpcode() == ISD::SRL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getValue(); - uint64_t c2 = N2C->getValue(); + uint64_t c2 = N1C->getValue(); SDOperand Mask = DAG.getNode(ISD::AND, VT, N0.getOperand(0), DAG.getConstant(~0ULL << c1, VT)); if (c2 > c1) @@ -682,70 +697,70 @@ DAG.getConstant(c1-c2, N1.getValueType())).Val; } // fold (shl (sra x, c1), c1) -> (and x, -1 << c1) - if (N2C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) + if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) return DAG.getNode(ISD::AND, VT, N0.getOperand(0), - DAG.getConstant(~0ULL << N2C->getValue(), VT)).Val; + DAG.getConstant(~0ULL << N1C->getValue(), VT)).Val; return 0; } -SDNode *DAGCombiner::visitSra(SDNode *N) { +SDNode *DAGCombiner::visitSRA(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); unsigned OpSizeInBits = MVT::getSizeInBits(VT); // fold (sra c1, c2) -> c1>>c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getSignExtended() >> N2C->getValue(), VT).Val; + if (N0C && N1C) + return DAG.getConstant(N0C->getSignExtended() >> N1C->getValue(), VT).Val; // fold (sra 0, x) -> 0 - if (N1C && N1C->isNullValue()) + if (N0C && N0C->isNullValue()) return N0.Val; // fold (sra -1, x) -> -1 - if (N1C && N1C->isAllOnesValue()) + if (N0C && N0C->isAllOnesValue()) return N0.Val; // fold (sra x, c >= size(x)) -> undef - if (N2C && N2C->getValue() >= OpSizeInBits) + if (N1C && N1C->getValue() >= OpSizeInBits) return DAG.getNode(ISD::UNDEF, VT).Val; // fold (sra x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // If the sign bit is known to be zero, switch this to a SRL. - if (N2C && MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) + if (N1C && MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) return DAG.getNode(ISD::SRL, VT, N0, N1).Val; return 0; } -SDNode *DAGCombiner::visitSrl(SDNode *N) { +SDNode *DAGCombiner::visitSRL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - ConstantSDNode *N1C = dyn_cast(N0); - ConstantSDNode *N2C = dyn_cast(N1); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); unsigned OpSizeInBits = MVT::getSizeInBits(VT); // fold (srl c1, c2) -> c1 >>u c2 - if (N1C && N2C) - return DAG.getConstant(N1C->getValue() >> N2C->getValue(), VT).Val; + if (N0C && N1C) + return DAG.getConstant(N0C->getValue() >> N1C->getValue(), VT).Val; // fold (srl 0, x) -> 0 - if (N1C && N1C->isNullValue()) + if (N0C && N0C->isNullValue()) return N0.Val; // fold (srl x, c >= size(x)) -> undef - if (N2C && N2C->getValue() >= OpSizeInBits) + if (N1C && N1C->getValue() >= OpSizeInBits) return DAG.getNode(ISD::UNDEF, VT).Val; // fold (srl x, 0) -> x - if (N2C && N2C->isNullValue()) + if (N1C && N1C->isNullValue()) return N0.Val; // if (srl x, c) is known to be zero, return 0 - if (N2C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))<getValue(), + if (N1C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))<getValue(), TLI)) return DAG.getConstant(0, VT).Val; // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2) - if (N2C && N0.getOpcode() == ISD::SRL && + if (N1C && N0.getOpcode() == ISD::SRL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getValue(); - uint64_t c2 = N2C->getValue(); + uint64_t c2 = N1C->getValue(); if (c1 + c2 > OpSizeInBits) return DAG.getConstant(0, VT).Val; return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), @@ -754,83 +769,90 @@ return 0; } -SDNode *DAGCombiner::visitCtlz(SDNode *N) { +SDNode *DAGCombiner::visitCTLZ(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); // fold (ctlz c1) -> c2 - if (N1C) - return DAG.getConstant(CountLeadingZeros_64(N1C->getValue()), + if (N0C) + return DAG.getConstant(CountLeadingZeros_64(N0C->getValue()), N0.getValueType()).Val; return 0; } -SDNode *DAGCombiner::visitCttz(SDNode *N) { +SDNode *DAGCombiner::visitCTTZ(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); // fold (cttz c1) -> c2 - if (N1C) - return DAG.getConstant(CountTrailingZeros_64(N1C->getValue()), + if (N0C) + return DAG.getConstant(CountTrailingZeros_64(N0C->getValue()), N0.getValueType()).Val; return 0; } -SDNode *DAGCombiner::visitCtpop(SDNode *N) { +SDNode *DAGCombiner::visitCTPOP(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); // fold (ctpop c1) -> c2 - if (N1C) - return DAG.getConstant(CountPopulation_64(N1C->getValue()), + if (N0C) + return DAG.getConstant(CountPopulation_64(N0C->getValue()), N0.getValueType()).Val; return 0; } -SDNode *DAGCombiner::visitSignExtend(SDNode *N) { +SDNode *DAGCombiner::visitSIGN_EXTEND(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (sext c1) -> c1 - if (N1C) - return DAG.getConstant(N1C->getSignExtended(), VT).Val; + if (N0C) + return DAG.getConstant(N0C->getSignExtended(), VT).Val; // fold (sext (sext x)) -> (sext x) if (N0.getOpcode() == ISD::SIGN_EXTEND) return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)).Val; return 0; } -SDNode *DAGCombiner::visitZeroExtend(SDNode *N) { +SDNode *DAGCombiner::visitZERO_EXTEND(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (zext c1) -> c1 - if (N1C) - return DAG.getConstant(N1C->getValue(), VT).Val; + if (N0C) + return DAG.getConstant(N0C->getValue(), VT).Val; // fold (zext (zext x)) -> (zext x) if (N0.getOpcode() == ISD::ZERO_EXTEND) return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0)).Val; return 0; } -SDNode *DAGCombiner::visitSignExtendInReg(SDNode *N) { +SDNode *DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + SDOperand N1 = N->getOperand(1); + SDOperand LHS, RHS, CC; + ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); - MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); + MVT::ValueType EVT = cast(N1)->getVT(); // fold (sext_in_reg c1) -> c1 - if (N1C) { - SDOperand Truncate = DAG.getConstant(N1C->getValue(), EVT); + if (N0C) { + SDOperand Truncate = DAG.getConstant(N0C->getValue(), EVT); return DAG.getNode(ISD::SIGN_EXTEND, VT, Truncate).Val; } - // fold (sext_in_reg (sext_in_reg x)) -> (sext_in_reg x) + // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt1 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && - cast(N0.getOperand(1))->getVT() <= EVT) { + cast(N0.getOperand(1))->getVT() < EVT) { return N0.Val; } + // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2 + if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && + EVT < cast(N0.getOperand(1))->getVT()) { + return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1).Val; + } // fold (sext_in_reg (assert_sext x)) -> (assert_sext x) if (N0.getOpcode() == ISD::AssertSext && cast(N0.getOperand(1))->getVT() <= EVT) { @@ -842,6 +864,7 @@ return N0.Val; } // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1 + // FIXME: teach isSetCCEquivalent about 0, -1 and then use it here if (N0.getOpcode() == ISD::SETCC && TLI.getSetCCResultContents() == TargetLowering::ZeroOrNegativeOneSetCCResult) @@ -862,17 +885,17 @@ return 0; } -SDNode *DAGCombiner::visitTruncate(SDNode *N) { +SDNode *DAGCombiner::visitTRUNCATE(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // noop truncate if (N0.getValueType() == N->getValueType(0)) return N0.Val; // fold (truncate c1) -> c1 - if (N1C) - return DAG.getConstant(N1C->getValue(), VT).Val; + if (N0C) + return DAG.getConstant(N0C->getValue(), VT).Val; // fold (truncate (truncate x)) -> (truncate x) if (N0.getOpcode() == ISD::TRUNCATE) return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; @@ -892,86 +915,86 @@ return 0; } -SDNode *DAGCombiner::visitSintToFP(SDNode *N) { +SDNode *DAGCombiner::visitSINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (sint_to_fp c1) -> c1fp - if (N1C) - return DAG.getConstantFP(N1C->getSignExtended(), VT).Val; + if (N0C) + return DAG.getConstantFP(N0C->getSignExtended(), VT).Val; return 0; } -SDNode *DAGCombiner::visitUintToFP(SDNode *N) { +SDNode *DAGCombiner::visitUINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); - ConstantSDNode *N1C = dyn_cast(N0); + ConstantSDNode *N0C = dyn_cast(N0); MVT::ValueType VT = N->getValueType(0); // fold (uint_to_fp c1) -> c1fp - if (N1C) - return DAG.getConstantFP(N1C->getValue(), VT).Val; + if (N0C) + return DAG.getConstantFP(N0C->getValue(), VT).Val; return 0; } -SDNode *DAGCombiner::visitFPToSint(SDNode *N) { - ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); +SDNode *DAGCombiner::visitFP_TO_SINT(SDNode *N) { + ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_to_sint c1fp) -> c1 - if (N1CFP) - return DAG.getConstant((int64_t)N1CFP->getValue(), N->getValueType(0)).Val; + if (N0CFP) + return DAG.getConstant((int64_t)N0CFP->getValue(), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitFPToUint(SDNode *N) { - ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); +SDNode *DAGCombiner::visitFP_TO_UINT(SDNode *N) { + ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_to_uint c1fp) -> c1 - if (N1CFP) - return DAG.getConstant((uint64_t)N1CFP->getValue(), N->getValueType(0)).Val; + if (N0CFP) + return DAG.getConstant((uint64_t)N0CFP->getValue(), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitFPRound(SDNode *N) { - ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); +SDNode *DAGCombiner::visitFP_ROUND(SDNode *N) { + ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_round c1fp) -> c1fp - if (N1CFP) - return DAG.getConstantFP(N1CFP->getValue(), N->getValueType(0)).Val; + if (N0CFP) + return DAG.getConstantFP(N0CFP->getValue(), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitFPRoundInReg(SDNode *N) { +SDNode *DAGCombiner::visitFP_ROUND_INREG(SDNode *N) { SDOperand N0 = N->getOperand(0); MVT::ValueType VT = N->getValueType(0); MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); - ConstantFPSDNode *N1CFP = dyn_cast(N0); + ConstantFPSDNode *N0CFP = dyn_cast(N0); // noop fp_round_inreg if (EVT == VT) return N0.Val; // fold (fp_round_inreg c1fp) -> c1fp - if (N1CFP) { - SDOperand Round = DAG.getConstantFP(N1CFP->getValue(), EVT); + if (N0CFP) { + SDOperand Round = DAG.getConstantFP(N0CFP->getValue(), EVT); return DAG.getNode(ISD::FP_EXTEND, VT, Round).Val; } return 0; } -SDNode *DAGCombiner::visitFPExtend(SDNode *N) { - ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); +SDNode *DAGCombiner::visitFP_EXTEND(SDNode *N) { + ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fp_extend c1fp) -> c1fp - if (N1CFP) - return DAG.getConstantFP(N1CFP->getValue(), N->getValueType(0)).Val; + if (N0CFP) + return DAG.getConstantFP(N0CFP->getValue(), N->getValueType(0)).Val; return 0; } -SDNode *DAGCombiner::visitFneg(SDNode *N) { - ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); +SDNode *DAGCombiner::visitFNEG(SDNode *N) { + ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (neg c1) -> -c1 - if (N1CFP) - return DAG.getConstantFP(-N1CFP->getValue(), N->getValueType(0)).Val; + if (N0CFP) + return DAG.getConstantFP(-N0CFP->getValue(), N->getValueType(0)).Val; // fold (neg (sub x, y)) -> (sub y, x) if (N->getOperand(0).getOpcode() == ISD::SUB) return DAG.getNode(ISD::SUB, N->getValueType(0), N->getOperand(1), @@ -982,11 +1005,11 @@ return 0; } -SDNode *DAGCombiner::visitFabs(SDNode *N) { - ConstantFPSDNode *N1CFP = dyn_cast(N->getOperand(0)); +SDNode *DAGCombiner::visitFABS(SDNode *N) { + ConstantFPSDNode *N0CFP = dyn_cast(N->getOperand(0)); // fold (fabs c1) -> fabs(c1) - if (N1CFP) - return DAG.getConstantFP(fabs(N1CFP->getValue()), N->getValueType(0)).Val; + if (N0CFP) + return DAG.getConstantFP(fabs(N0CFP->getValue()), N->getValueType(0)).Val; // fold (fabs (fabs x)) -> (fabs x) if (N->getOperand(0).getOpcode() == ISD::FABS) return N->getOperand(0).Val; From lattner at cs.uiuc.edu Fri Sep 2 17:36:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 17:36:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td PowerPCInstrInfo.td Message-ID: <200509022236.RAA29259@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrFormats.td updated: 1.46 -> 1.47 PowerPCInstrInfo.td updated: 1.87 -> 1.88 --- Log message: Add AND/OR/XOR --- Diffs of the changes: (+65 -31) PowerPCInstrFormats.td | 11 ++++-- PowerPCInstrInfo.td | 85 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 65 insertions(+), 31 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.46 llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.47 --- llvm/lib/Target/PowerPC/PowerPCInstrFormats.td:1.46 Fri Sep 2 16:18:00 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrFormats.td Fri Sep 2 17:35:53 2005 @@ -223,8 +223,11 @@ class XForm_1 opcode, bits<10> xo, dag OL, string asmstr> : XForm_base_r3xo; -class XForm_6 opcode, bits<10> xo, dag OL, string asmstr> - : XForm_base_r3xo_swapped; +class XForm_6 opcode, bits<10> xo, dag OL, string asmstr, + list pattern> + : XForm_base_r3xo_swapped { + let Pattern = pattern; +} class XForm_8 opcode, bits<10> xo, dag OL, string asmstr> : XForm_base_r3xo; @@ -233,9 +236,11 @@ : XForm_base_r3xo_swapped { } -class XForm_11 opcode, bits<10> xo, dag OL, string asmstr> +class XForm_11 opcode, bits<10> xo, dag OL, string asmstr, + list pattern> : XForm_base_r3xo_swapped { let B = 0; + let Pattern = pattern; } class XForm_16 opcode, bits<10> xo, dag OL, string asmstr> Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.87 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.88 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.87 Fri Sep 2 16:18:00 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Fri Sep 2 17:35:53 2005 @@ -14,14 +14,24 @@ include "PowerPCInstrFormats.td" +class SDNode { + string Opcode = Opc; +} + def set; -def mul; -def udiv; -def sdiv; -def sub; -def add; -def mulhs; -def mulhu; +def and : SDNode<"ISD::AND">; +def or : SDNode<"ISD::OR">; +def xor : SDNode<"ISD::XOR">; +def add : SDNode<"ISD::ADD">; +def sub : SDNode<"ISD::SUB">; +def mul : SDNode<"ISD::MUL">; +def sdiv : SDNode<"ISD::SDIV">; +def udiv : SDNode<"ISD::UDIV">; +def mulhs : SDNode<"ISD::MULHS">; +def mulhu : SDNode<"ISD::MULHU">; +def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG">; +def ctlz : SDNode<"ISD::CTLZ">; + class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } @@ -240,37 +250,53 @@ "ldx $dst, $base, $index">, isPPC64; } def AND : XForm_6<31, 28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "and $rA, $rS, $rB">; + "and $rA, $rS, $rB", + [(set GPRC:$rT, (and GPRC:$rA, GPRC:$rB))]>; def ANDo : XForm_6<31, 28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "and. $rA, $rS, $rB">, isDOT; + "and. $rA, $rS, $rB", + []>, isDOT; def ANDC : XForm_6<31, 60, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "andc $rA, $rS, $rB">; + "andc $rA, $rS, $rB", + []>; def EQV : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "eqv $rA, $rS, $rB">; + "eqv $rA, $rS, $rB", + []>; def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "nand $rA, $rS, $rB">; + "nand $rA, $rS, $rB", + []>; def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "nor $rA, $rS, $rB">; + "nor $rA, $rS, $rB", + []>; def OR : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "or $rA, $rS, $rB">; + "or $rA, $rS, $rB", + [(set GPRC:$rT, (or GPRC:$rA, GPRC:$rB))]>; def ORo : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "or. $rA, $rS, $rB">, isDOT; + "or. $rA, $rS, $rB", + []>, isDOT; def ORC : XForm_6<31, 412, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "orc $rA, $rS, $rB">; + "orc $rA, $rS, $rB", + []>; def SLD : XForm_6<31, 27, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "sld $rA, $rS, $rB">, isPPC64; + "sld $rA, $rS, $rB", + []>, isPPC64; def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "slw $rA, $rS, $rB">; + "slw $rA, $rS, $rB", + []>; def SRD : XForm_6<31, 539, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "srd $rA, $rS, $rB">, isPPC64; + "srd $rA, $rS, $rB", + []>, isPPC64; def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "srw $rA, $rS, $rB">; + "srw $rA, $rS, $rB", + []>; def SRAD : XForm_6<31, 794, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "srad $rA, $rS, $rB">, isPPC64; + "srad $rA, $rS, $rB", + []>, isPPC64; def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "sraw $rA, $rS, $rB">; + "sraw $rA, $rS, $rB", + []>; def XOR : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "xor $rA, $rS, $rB">; + "xor $rA, $rS, $rB", + [(set GPRC:$rT, (xor GPRC:$rA, GPRC:$rB))]>; let isStore = 1 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stbx $rS, $rA, $rB">; @@ -288,13 +314,17 @@ def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), "srawi $rA, $rS, $SH">; def CNTLZW : XForm_11<31, 26, (ops GPRC:$rA, GPRC:$rS), - "cntlzw $rA, $rS">; + "cntlzw $rA, $rS", + [(set GPRC:$rA, (ctlz GPRC:$rS))]>; def EXTSB : XForm_11<31, 954, (ops GPRC:$rA, GPRC:$rS), - "extsb $rA, $rS">; + "extsb $rA, $rS", + [(set GPRC:$rA, (sext_inreg GPRC:$rS, i8))]>; def EXTSH : XForm_11<31, 922, (ops GPRC:$rA, GPRC:$rS), - "extsh $rA, $rS">; + "extsh $rA, $rS", + [(set GPRC:$rA, (sext_inreg GPRC:$rS, i16))]>; def EXTSW : XForm_11<31, 986, (ops GPRC:$rA, GPRC:$rS), - "extsw $rA, $rS">, isPPC64; + "extsw $rA, $rS", + []>, isPPC64; def CMP : XForm_16<31, 0, (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB), "cmp $crD, $long, $rA, $rB">; def CMPL : XForm_16<31, 32, (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB), @@ -512,4 +542,3 @@ let isLittleEndianEncoding = 1; } - From lattner at cs.uiuc.edu Fri Sep 2 19:22:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 19:22:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509030022.TAA29796@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.88 -> 1.89 --- Log message: rearrange logical ops to group them together more consistently. Define the PatFrag class which can be used to define subpatterns to match things with. Define 'not', and use it to define the patterns for andc, nand, etc. --- Diffs of the changes: (+42 -16) PowerPCInstrInfo.td | 58 +++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 42 insertions(+), 16 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.88 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.89 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.88 Fri Sep 2 17:35:53 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Fri Sep 2 19:21:51 2005 @@ -14,11 +14,16 @@ include "PowerPCInstrFormats.td" -class SDNode { - string Opcode = Opc; +class SDNode { + string Opcode = opcode; + string SDClass = sdclass; } def set; +def input; + +def imm : SDNode<"ISD::Constant", "ConstantSDNode">; +def vt : SDNode<"ISD::VALUETYPE", "VTSDNode">; def and : SDNode<"ISD::AND">; def or : SDNode<"ISD::OR">; def xor : SDNode<"ISD::XOR">; @@ -32,6 +37,27 @@ def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG">; def ctlz : SDNode<"ISD::CTLZ">; +/// PatFrag - Represents a pattern fragment. This can match something on the +/// DAG, frame a single node to multiply nested other fragments. +/// +class PatFrag { + dag Fragment = frag; + code Predicate = pred; +} + +// Leaf fragments. + +def immAllOnes : PatFrag<(imm), [{ return N->isAllOnesValue(); }]>; +def immZero : PatFrag<(imm), [{ return N->isNullValue(); }]>; + +def vtInt : PatFrag<(vt), [{ return MVT::isInteger(N->getVT()); }]>; +def vtFP : PatFrag<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; + +// Other helper fragments. + +def not : PatFrag<(xor input:$in, immAllOnes)>; +def ineg : PatFrag<(sub immZero, input:$in)>; + class isPPC64 { bit PPC64 = 1; } class isVMX { bit VMX = 1; } @@ -249,6 +275,9 @@ def LDX : XForm_1<31, 21, (ops GPRC:$dst, GPRC:$base, GPRC:$index), "ldx $dst, $base, $index">, isPPC64; } +def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), + "nand $rA, $rS, $rB", + [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>; def AND : XForm_6<31, 28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "and $rA, $rS, $rB", [(set GPRC:$rT, (and GPRC:$rA, GPRC:$rB))]>; @@ -257,25 +286,25 @@ []>, isDOT; def ANDC : XForm_6<31, 60, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "andc $rA, $rS, $rB", - []>; -def EQV : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "eqv $rA, $rS, $rB", - []>; -def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "nand $rA, $rS, $rB", - []>; -def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "nor $rA, $rS, $rB", - []>; + [(set GPRC:$rA, (and GPRC:$rS, (not GPRC:$rB)))]>; def OR : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "or $rA, $rS, $rB", [(set GPRC:$rT, (or GPRC:$rA, GPRC:$rB))]>; +def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), + "nor $rA, $rS, $rB", + [(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>; def ORo : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "or. $rA, $rS, $rB", []>, isDOT; def ORC : XForm_6<31, 412, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "orc $rA, $rS, $rB", - []>; + [(set GPRC:$rA, (or GPRC:$rS, (not GPRC:$rB)))]>; +def EQV : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), + "eqv $rA, $rS, $rB", + [(set GPRC:$rT, (not (xor GPRC:$rA, GPRC:$rB)))]>; +def XOR : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), + "xor $rA, $rS, $rB", + [(set GPRC:$rT, (xor GPRC:$rA, GPRC:$rB))]>; def SLD : XForm_6<31, 27, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sld $rA, $rS, $rB", []>, isPPC64; @@ -294,9 +323,6 @@ def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", []>; -def XOR : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "xor $rA, $rS, $rB", - [(set GPRC:$rT, (xor GPRC:$rA, GPRC:$rB))]>; let isStore = 1 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stbx $rS, $rA, $rB">; From lattner at cs.uiuc.edu Fri Sep 2 19:53:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 19:53:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509030053.TAA29991@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.70 -> 1.71 --- Log message: Change the isel to not break out of the big giant switch. Instead, the switch should never be exited, so its bottom is now unreachable. --- Diffs of the changes: (+61 -59) PPC32ISelDAGToDAG.cpp | 120 +++++++++++++++++++++++++------------------------- 1 files changed, 61 insertions(+), 59 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.70 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.71 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.70 Thu Sep 1 16:31:30 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Sep 2 19:53:47 2005 @@ -661,7 +661,7 @@ CurDAG->ReplaceAllUsesWith(Op, New); N = New.Val; } - break; + return SDOperand(N, 0); } case ISD::CopyFromReg: { SDOperand Chain = Select(N->getOperand(0)); @@ -680,7 +680,7 @@ CurDAG->ReplaceAllUsesWith(Op, New); N = New.Val; } - break; + return SDOperand(N, 0); } case ISD::Constant: { assert(N->getValueType(0) == MVT::i32); @@ -706,13 +706,13 @@ CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32); else CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_FP, N->getValueType(0)); - break; + return SDOperand(N, 0); case ISD::FrameIndex: { int FI = cast(N)->getIndex(); CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32, CurDAG->getTargetFrameIndex(FI, MVT::i32), getI32Imm(0)); - break; + return SDOperand(N, 0); } case ISD::ConstantPool: { Constant *C = cast(N)->get(); @@ -722,7 +722,7 @@ else Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI); CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); - break; + return SDOperand(N, 0); } case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); @@ -737,7 +737,7 @@ CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, GA, Tmp); else CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA); - break; + return SDOperand(N, 0); } case ISD::DYNAMIC_STACKALLOC: { // FIXME: We are currently ignoring the requested alignment for handling @@ -770,8 +770,7 @@ // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg. CurDAG->ReplaceAllUsesWith(N, Result.Val); - N = Result.Val; - break; + return SDOperand(Result.Val, Op.ResNo); } case ISD::SIGN_EXTEND_INREG: switch(cast(N->getOperand(1))->getVT()) { @@ -783,21 +782,21 @@ CurDAG->SelectNodeTo(N, PPC::EXTSB, MVT::i32, Select(N->getOperand(0))); break; } - break; + return SDOperand(N, 0); case ISD::CTLZ: assert(N->getValueType(0) == MVT::i32); CurDAG->SelectNodeTo(N, PPC::CNTLZW, MVT::i32, Select(N->getOperand(0))); - break; + return SDOperand(N, 0); case PPCISD::FSEL: CurDAG->SelectNodeTo(N, PPC::FSEL, N->getValueType(0), Select(N->getOperand(0)), Select(N->getOperand(1)), Select(N->getOperand(2))); - break; + return SDOperand(N, 0); case PPCISD::FCTIWZ: CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), Select(N->getOperand(0))); - break; + return SDOperand(N, 0); case ISD::ADD: { MVT::ValueType Ty = N->getValueType(0); if (Ty == MVT::i32) { @@ -809,7 +808,7 @@ CurDAG->SelectNodeTo(N, PPC::ADD, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); } - break; + return SDOperand(N, 0); } if (!NoExcessFPPrecision) { // Match FMA ops @@ -820,7 +819,7 @@ Select(N->getOperand(0).getOperand(0)), Select(N->getOperand(0).getOperand(1)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } else if (N->getOperand(1).getOpcode() == ISD::MUL && N->getOperand(1).hasOneUse()) { ++FusedFP; // Statistic @@ -828,13 +827,13 @@ Select(N->getOperand(1).getOperand(0)), Select(N->getOperand(1).getOperand(1)), Select(N->getOperand(0))); - break; + return SDOperand(N, 0); } } CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FADD : PPC::FADDS, Ty, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::SUB: { MVT::ValueType Ty = N->getValueType(0); @@ -846,7 +845,7 @@ else CurDAG->SelectNodeTo(N, PPC::SUBFIC, Ty, Select(N->getOperand(1)), getI32Imm(Lo16(Imm))); - break; + return SDOperand(N, 0); } if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), PPC::ADDIS, PPC::ADDI, true, true)) { @@ -856,7 +855,7 @@ CurDAG->SelectNodeTo(N, PPC::SUBF, Ty, Select(N->getOperand(1)), Select(N->getOperand(0))); } - break; + return SDOperand(N, 0); } if (!NoExcessFPPrecision) { // Match FMA ops @@ -867,7 +866,7 @@ Select(N->getOperand(0).getOperand(0)), Select(N->getOperand(0).getOperand(1)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } else if (N->getOperand(1).getOpcode() == ISD::MUL && N->getOperand(1).Val->hasOneUse()) { ++FusedFP; // Statistic @@ -875,20 +874,20 @@ Select(N->getOperand(1).getOperand(0)), Select(N->getOperand(1).getOperand(1)), Select(N->getOperand(0))); - break; + return SDOperand(N, 0); } } CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FSUB : PPC::FSUBS, Ty, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::MUL: { unsigned Imm, Opc; if (isIntImmediate(N->getOperand(1), Imm) && isInt16(Imm)) { CurDAG->SelectNodeTo(N, PPC::MULLI, MVT::i32, Select(N->getOperand(0)), getI32Imm(Lo16(Imm))); - break; + return SDOperand(N, 0); } switch (N->getValueType(0)) { default: assert(0 && "Unhandled multiply type!"); @@ -898,7 +897,7 @@ } CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::SDIV: { unsigned Imm; @@ -910,7 +909,7 @@ getI32Imm(Log2_32(Imm))); CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, Op.getValue(0), Op.getValue(1)); - break; + return SDOperand(N, 0); } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { SDOperand Op = CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag, @@ -920,13 +919,13 @@ CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(0), Op.getValue(1)); CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); - break; + return SDOperand(N, 0); } else if (Imm) { SDOperand Result = Select(BuildSDIVSequence(N)); assert(Result.ResNo == 0); CurDAG->ReplaceAllUsesWith(Op, Result); N = Result.Val; - break; + return SDOperand(N, 0); } } @@ -939,7 +938,7 @@ } CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::UDIV: { // If this is a divide by constant, we can emit code using some magic @@ -950,23 +949,23 @@ assert(Result.ResNo == 0); CurDAG->ReplaceAllUsesWith(Op, Result); N = Result.Val; - break; + return SDOperand(N, 0); } CurDAG->SelectNodeTo(N, PPC::DIVWU, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::MULHS: assert(N->getValueType(0) == MVT::i32); CurDAG->SelectNodeTo(N, PPC::MULHW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); case ISD::MULHU: assert(N->getValueType(0) == MVT::i32); CurDAG->SelectNodeTo(N, PPC::MULHWU, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); case ISD::AND: { unsigned Imm; // If this is an and of a value rotated between 0 and 31 bits and then and'd @@ -984,7 +983,7 @@ } CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Val, getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); - break; + return SDOperand(N, 0); } // Finally, check for the case where we are being asked to select // and (not(a), b) or and (a, not(b)) which can be selected as andc. @@ -997,20 +996,20 @@ else CurDAG->SelectNodeTo(N, PPC::AND, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::OR: if (SDNode *I = SelectBitfieldInsert(N)) { CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); N = I; - break; + return SDOperand(N, 0); } if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1), PPC::ORIS, PPC::ORI)) { CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); N = I; - break; + return SDOperand(N, 0); } // Finally, check for the case where we are being asked to select // 'or (not(a), b)' or 'or (a, not(b))' which can be selected as orc. @@ -1023,7 +1022,7 @@ else CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); case ISD::XOR: // Check whether or not this node is a logical 'not'. This is represented // by llvm as a xor with the constant value -1 (all bits set). If this is a @@ -1042,7 +1041,7 @@ Val.getOperand(1)); else CurDAG->SelectNodeTo(N, PPC::NOR, MVT::i32, Val, Val); - break; + return SDOperand(N, 0); } // If this is a xor with an immediate other than -1, then codegen it as high // and low 16 bit immediate xors. @@ -1051,7 +1050,7 @@ PPC::XORIS, PPC::XORI)) { CurDAG->ReplaceAllUsesWith(Op, SDOperand(I, 0)); N = I; - break; + return SDOperand(N, 0); } // Finally, check for the case where we are being asked to select // xor (not(a), b) which is equivalent to not(xor a, b), which is eqv @@ -1062,7 +1061,7 @@ else CurDAG->SelectNodeTo(N, PPC::XOR, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); case ISD::SHL: { unsigned Imm, SH, MB, ME; if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && @@ -1076,7 +1075,7 @@ else CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::SRL: { unsigned Imm, SH, MB, ME; @@ -1091,7 +1090,7 @@ else CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::SRA: { unsigned Imm, SH, MB, ME; @@ -1106,24 +1105,24 @@ else CurDAG->SelectNodeTo(N, PPC::SRAW, MVT::i32, Select(N->getOperand(0)), Select(N->getOperand(1))); - break; + return SDOperand(N, 0); } case ISD::FABS: CurDAG->SelectNodeTo(N, PPC::FABS, N->getValueType(0), Select(N->getOperand(0))); - break; + return SDOperand(N, 0); case ISD::FP_EXTEND: assert(MVT::f64 == N->getValueType(0) && MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND"); // We need to emit an FMR to make sure that the result has the right value // type. CurDAG->SelectNodeTo(N, PPC::FMR, MVT::f64, Select(N->getOperand(0))); - break; + return SDOperand(N, 0); case ISD::FP_ROUND: assert(MVT::f32 == N->getValueType(0) && MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND"); CurDAG->SelectNodeTo(N, PPC::FRSP, MVT::f32, Select(N->getOperand(0))); - break; + return SDOperand(N, 0); case ISD::FNEG: { SDOperand Val = Select(N->getOperand(0)); MVT::ValueType Ty = N->getValueType(0); @@ -1146,17 +1145,17 @@ else CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0), Val.getOperand(1), Val.getOperand(2)); - break; + return SDOperand(N, 0); } } CurDAG->SelectNodeTo(N, PPC::FNEG, Ty, Val); - break; + return SDOperand(N, 0); } case ISD::FSQRT: { MVT::ValueType Ty = N->getValueType(0); CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FSQRT : PPC::FSQRTS, Ty, Select(N->getOperand(0))); - break; + return SDOperand(N, 0); } case ISD::ADD_PARTS: { @@ -1242,7 +1241,7 @@ CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, Op1, Op2, Select(N->getOperand(0))); - break; + return SDOperand(N, Op.ResNo); } case ISD::TRUNCSTORE: @@ -1269,7 +1268,7 @@ CurDAG->SelectNodeTo(N, Opc, MVT::Other, Select(N->getOperand(1)), AddrOp1, AddrOp2, Select(N->getOperand(0))); - break; + return SDOperand(N, 0); } case ISD::SETCC: { @@ -1306,7 +1305,7 @@ break; } } - break; + return SDOperand(N, 0); } else if (Imm == ~0U) { // setcc op, -1 SDOperand Op = Select(N->getOperand(0)); switch (CC) { @@ -1340,7 +1339,7 @@ CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); break; } - break; + return SDOperand(N, 0); } } @@ -1376,7 +1375,7 @@ CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1)); } - break; + return SDOperand(N, 0); } case ISD::SELECT_CC: { @@ -1394,7 +1393,7 @@ LHS, getI32Imm(~0U)); CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, Tmp, LHS, Tmp.getValue(1)); - break; + return SDOperand(N, 0); } SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); @@ -1405,7 +1404,7 @@ CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg, Select(N->getOperand(2)), Select(N->getOperand(3)), getI32Imm(BROpc)); - break; + return SDOperand(N, 0); } case ISD::CALLSEQ_START: @@ -1415,7 +1414,7 @@ PPC::ADJCALLSTACKDOWN : PPC::ADJCALLSTACKUP; CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI32Imm(Amt), Select(N->getOperand(0))); - break; + return SDOperand(N, 0); } case ISD::CALL: case ISD::TAILCALL: { @@ -1543,12 +1542,12 @@ // Finally, select this to a blr (return) instruction. CurDAG->SelectNodeTo(N, PPC::BLR, MVT::Other, Chain); - break; + return SDOperand(N, 0); } case ISD::BR: CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, N->getOperand(1), Select(N->getOperand(0))); - break; + return SDOperand(N, 0); case ISD::BR_CC: case ISD::BRTWOWAY_CC: { SDOperand Chain = Select(N->getOperand(0)); @@ -1584,9 +1583,12 @@ getI32Imm(Opc), N->getOperand(4), CurDAG->getBasicBlock(It), Chain); } - break; + return SDOperand(N, 0); } } + + assert(0 && "Unreachable!"); + abort(); return SDOperand(N, Op.ResNo); } From lattner at cs.uiuc.edu Fri Sep 2 20:04:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 20:04:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200509030104.UAA30095@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.185 -> 1.186 --- Log message: Fix a checking failure in gs --- Diffs of the changes: (+1 -1) SelectionDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.185 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.186 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.185 Fri Sep 2 14:36:17 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 2 20:04:40 2005 @@ -362,7 +362,7 @@ // not subject to CSE. if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag && N->getOpcode() != ISD::CALL && N->getOpcode() != ISD::CALLSEQ_START && - N->getOpcode() != ISD::CALLSEQ_END) { + N->getOpcode() != ISD::CALLSEQ_END && !N->isTargetOpcode()) { N->dump(); assert(0 && "Node is not in map!"); From lattner at cs.uiuc.edu Fri Sep 2 20:14:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 20:14:14 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.h TableGen.cpp Message-ID: <200509030114.UAA30199@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.h added (r1.1) TableGen.cpp updated: 1.38 -> 1.39 --- Log message: Add an option and stuff implementation of a dag isel emitter --- Diffs of the changes: (+45 -0) DAGISelEmitter.h | 38 ++++++++++++++++++++++++++++++++++++++ TableGen.cpp | 7 +++++++ 2 files changed, 45 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.h diff -c /dev/null llvm/utils/TableGen/DAGISelEmitter.h:1.1 *** /dev/null Fri Sep 2 20:14:13 2005 --- llvm/utils/TableGen/DAGISelEmitter.h Fri Sep 2 20:14:03 2005 *************** *** 0 **** --- 1,38 ---- + //===- DAGISelEmitter.h - Generate an instruction selector ------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This tablegen backend emits a DAG instruction selector. + // + //===----------------------------------------------------------------------===// + + #ifndef DAGISEL_EMITTER_H + #define DAGISEL_EMITTER_H + + #include "TableGenBackend.h" + #include "CodeGenTarget.h" + + namespace llvm { + + /// InstrSelectorEmitter - The top-level class which coordinates construction + /// and emission of the instruction selector. + /// + class DAGISelEmitter : public TableGenBackend { + RecordKeeper &Records; + CodeGenTarget Target; + + public: + DAGISelEmitter(RecordKeeper &R) : Records(R) {} + + // run - Output the isel, returning true on failure. + void run(std::ostream &OS) {} + }; + + } // End llvm namespace + + #endif Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.38 llvm/utils/TableGen/TableGen.cpp:1.39 --- llvm/utils/TableGen/TableGen.cpp:1.38 Thu Apr 21 23:13:13 2005 +++ llvm/utils/TableGen/TableGen.cpp Fri Sep 2 20:14:03 2005 @@ -24,6 +24,7 @@ #include "InstrInfoEmitter.h" #include "AsmWriterEmitter.h" #include "InstrSelectorEmitter.h" +#include "DAGISelEmitter.h" #include #include #include @@ -34,6 +35,7 @@ GenEmitter, GenRegisterEnums, GenRegister, GenRegisterHeader, GenInstrEnums, GenInstrs, GenAsmWriter, GenInstrSelector, + GenDAGISel, PrintEnums, Parse }; @@ -59,6 +61,8 @@ "Generate assembly writer"), clEnumValN(GenInstrSelector, "gen-instr-selector", "Generate an instruction selector"), + clEnumValN(GenDAGISel, "gen-dag-isel", + "Generate a DAG instruction selector"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(Parse, "parse", @@ -465,6 +469,9 @@ case GenInstrSelector: InstrSelectorEmitter(Records).run(*Out); break; + case GenDAGISel: + DAGISelEmitter(Records).run(*Out); + break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); From lattner at cs.uiuc.edu Fri Sep 2 20:15:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 20:15:37 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200509030115.UAA30289@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.324 -> 1.325 --- Log message: allow for a target to ask for a dag isel --- Diffs of the changes: (+6 -0) Makefile.rules | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.324 llvm/Makefile.rules:1.325 --- llvm/Makefile.rules:1.324 Sat Aug 27 13:50:38 2005 +++ llvm/Makefile.rules Fri Sep 2 20:15:25 2005 @@ -1140,6 +1140,12 @@ $(Echo) "Building $( Changes in directory llvm/lib/Target/PowerPC: Makefile updated: 1.18 -> 1.19 --- Log message: ask for a dag isel --- Diffs of the changes: (+2 -1) Makefile | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/Makefile diff -u llvm/lib/Target/PowerPC/Makefile:1.18 llvm/lib/Target/PowerPC/Makefile:1.19 --- llvm/lib/Target/PowerPC/Makefile:1.18 Sat Aug 13 00:59:16 2005 +++ llvm/lib/Target/PowerPC/Makefile Fri Sep 2 20:15:41 2005 @@ -13,6 +13,7 @@ # Make sure that tblgen is run, first thing. BUILT_SOURCES = PowerPCGenInstrNames.inc PowerPCGenRegisterNames.inc \ PowerPCGenAsmWriter.inc PPC32GenCodeEmitter.inc \ - PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc PPC32GenInstrInfo.inc + PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc \ + PPC32GenInstrInfo.inc PPC32GenDAGISel.inc include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Fri Sep 2 20:17:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 20:17:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Message-ID: <200509030117.UAA30385@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelDAGToDAG.cpp updated: 1.71 -> 1.72 --- Log message: include the dag isel fragment --- Diffs of the changes: (+2 -0) PPC32ISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.71 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.72 --- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.71 Fri Sep 2 19:53:47 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Fri Sep 2 20:17:22 2005 @@ -99,6 +99,8 @@ }; } +#include "PPC32GenDAGISel.inc" + /// getGlobalBaseReg - Output the instructions required to put the /// base address to use for accessing globals into a register. /// From lattner at cs.uiuc.edu Fri Sep 2 20:28:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 2 Sep 2005 20:28:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200509030128.UAA30456@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.89 -> 1.90 --- Log message: explicitly specify an operands list for patterns with inputs (e.g. neg) --- Diffs of the changes: (+13 -8) PowerPCInstrInfo.td | 21 +++++++++++++-------- 1 files changed, 13 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.89 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.90 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.89 Fri Sep 2 19:21:51 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Fri Sep 2 20:28:40 2005 @@ -20,7 +20,7 @@ } def set; -def input; +def node; def imm : SDNode<"ISD::Constant", "ConstantSDNode">; def vt : SDNode<"ISD::VALUETYPE", "VTSDNode">; @@ -40,23 +40,28 @@ /// PatFrag - Represents a pattern fragment. This can match something on the /// DAG, frame a single node to multiply nested other fragments. /// -class PatFrag { +class PatFrag { + dag Operands = ops; dag Fragment = frag; code Predicate = pred; } +class PatLeaf : PatFrag<(ops), frag, pred>; // Leaf fragments. -def immAllOnes : PatFrag<(imm), [{ return N->isAllOnesValue(); }]>; -def immZero : PatFrag<(imm), [{ return N->isNullValue(); }]>; +def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; +def immZero : PatLeaf<(imm), [{ return N->isNullValue(); }]>; -def vtInt : PatFrag<(vt), [{ return MVT::isInteger(N->getVT()); }]>; -def vtFP : PatFrag<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; +def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>; +def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; // Other helper fragments. -def not : PatFrag<(xor input:$in, immAllOnes)>; -def ineg : PatFrag<(sub immZero, input:$in)>; +def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; +def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; + + + class isPPC64 { bit PPC64 = 1; } From alenhar2 at cs.uiuc.edu Sun Sep 4 01:12:31 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sun, 4 Sep 2005 01:12:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp AlphaISelPattern.cpp Message-ID: <200509040612.BAA14786@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.1 -> 1.2 AlphaISelPattern.cpp updated: 1.167 -> 1.168 --- Log message: revert part of the last change, should fix regressions --- Diffs of the changes: (+11 -6) AlphaISelLowering.cpp | 12 ++++++------ AlphaISelPattern.cpp | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.1 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.2 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.1 Fri Sep 2 13:46:02 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Sun Sep 4 01:12:19 2005 @@ -131,9 +131,9 @@ MachineBasicBlock& BB = MF.front(); std::vector ArgValues; - static const unsigned args_int[] = { + unsigned args_int[] = { Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; - static const unsigned args_float[] = { + unsigned args_float[] = { Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; unsigned added_int = 0; unsigned added_fp = 0; @@ -155,7 +155,7 @@ abort(); case MVT::f64: case MVT::f32: - MF.addLiveIn(args_float[count]); + args_float[count] = AddLiveIn(MF, args_float[count], getRegClassFor(VT)); added_fp |= (1 << count); argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[count], VT); DAG.setRoot(argt.getValue(1)); @@ -165,7 +165,7 @@ case MVT::i16: case MVT::i32: case MVT::i64: - MF.addLiveIn(args_int[count]); + args_int[count] = AddLiveIn(MF, args_int[count], getRegClassFor(MVT::i64)); added_int |= (1 << count); argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[count], MVT::i64); DAG.setRoot(argt.getValue(1)); @@ -198,7 +198,7 @@ std::vector LS; for (int i = 0; i < 6; ++i) { if (!(added_int & (1 << i))) - MF.addLiveIn(args_int[i]); + args_int[i] = AddLiveIn(MF, args_int[i], getRegClassFor(MVT::i64)); SDOperand argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[i], MVT::i64); int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); if (i == 0) VarArgsBase = FI; @@ -207,7 +207,7 @@ SDFI, DAG.getSrcValue(NULL))); if (!(added_fp & (1 << i))) - MF.addLiveIn(args_float[i]); + args_float[i] = AddLiveIn(MF, args_float[i], getRegClassFor(MVT::f64)); argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[i], MVT::f64); FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); SDFI = DAG.getFrameIndex(FI, MVT::i64); Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.167 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.168 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.167 Fri Sep 2 13:46:02 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Sun Sep 4 01:12:19 2005 @@ -1733,6 +1733,11 @@ BuildMI(BB, Opc, 1, Result).addReg(Alpha::F31).addReg(Tmp2); return Result; } + + case ISD::AssertSext: + case ISD::AssertZext: + return SelectExpr(N.getOperand(0)); + } return 0;