From clattner at apple.com Mon Jan 7 00:20:04 2008 From: clattner at apple.com (Chris Lattner) Date: Sun, 6 Jan 2008 22:20:04 -0800 Subject: [llvm-commits] [llvm] r45626 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp In-Reply-To: <2F488CC7-9FBA-4E00-ACA4-6FA6DFF373A6@apple.com> References: <200801050918.m059I5GB021020@zion.cs.uiuc.edu> <6BBC27A8-F4C2-48C7-B24A-4A617B2DEFD8@apple.com> <7068D27E-5A5C-4F3E-B24E-C798657727A4@gmail.com> <2F488CC7-9FBA-4E00-ACA4-6FA6DFF373A6@apple.com> Message-ID: <0D0AED77-736C-422C-AB56-69007988EBF1@apple.com> On Jan 6, 2008, at 6:45 PM, Evan Cheng wrote: > By the way. This check is still not quite right. > > // Loads from stubs of global addresses are side effect free. > if (Reg != 0 && MRegisterInfo::isVirtualRegister(Reg) && > > In dynamic-no-pic mode, Reg can be 0. So it should be Reg == 0 || ... Why is this code even looking at that operand? -Chris From sabre at nondot.org Mon Jan 7 00:21:53 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 06:21:53 -0000 Subject: [llvm-commits] [llvm] r45690 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/TwoAddressInstructionPass.cpp Message-ID: <200801070621.m076Lr7p000762@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 00:21:53 2008 New Revision: 45690 URL: http://llvm.org/viewvc/llvm-project?rev=45690&view=rev Log: add more and significantly better comments to the rest of the machineinstr flags that can be set. Add predicates for the ones lacking it, and switch some clients over to using the predicates instead of Flags directly. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45690&r1=45689&r2=45690&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Jan 7 00:21:53 2008 @@ -71,7 +71,7 @@ bool isLookupPtrRegClass() const { return Flags & TOI::LookupPtrRegClass; } /// isPredicate - Set if this is one of the operands that made up of - /// the predicate operand that controls an M_PREDICATED instruction. + /// the predicate operand that controls an isPredicable() instruction. bool isPredicate() const { return Flags & TOI::Predicate; } /// isOptionalDef - Set if this operand is a optional def. @@ -89,70 +89,20 @@ const unsigned M_RET_FLAG = 1 << 2; const unsigned M_BARRIER_FLAG = 1 << 3; const unsigned M_DELAY_SLOT_FLAG = 1 << 4; - -/// M_SIMPLE_LOAD_FLAG - This flag is set for instructions that are simple loads -/// from memory. This should only be set on instructions that load a value from -/// memory and return it in their only virtual register definition. const unsigned M_SIMPLE_LOAD_FLAG = 1 << 5; - -/// M_MAY_STORE_FLAG - This flag is set to any instruction that could possibly -/// modify memory. Instructions with this flag set are not necessarily simple -/// store instructions, they may store a modified value based on their operands, -/// or may not actually modify anything, for example. const unsigned M_MAY_STORE_FLAG = 1 << 6; - const unsigned M_INDIRECT_FLAG = 1 << 7; const unsigned M_IMPLICIT_DEF_FLAG = 1 << 8; - -// M_CONVERTIBLE_TO_3_ADDR - This is a 2-address instruction which can be -// changed into a 3-address instruction if the first two operands cannot be -// assigned to the same register. The target must implement the -// TargetInstrInfo::convertToThreeAddress method for this instruction. const unsigned M_CONVERTIBLE_TO_3_ADDR = 1 << 9; - -// This M_COMMUTABLE - is a 2- or 3-address instruction (of the form X = op Y, -// Z), which produces the same result if Y and Z are exchanged. const unsigned M_COMMUTABLE = 1 << 10; - const unsigned M_TERMINATOR_FLAG = 1 << 11; - -// M_USES_CUSTOM_DAG_SCHED_INSERTION - Set if this instruction requires custom -// insertion support when the DAG scheduler is inserting it into a machine basic -// block. const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 12; - -const unsigned M_VARIADIC = 1 << 13; - -// M_PREDICABLE - Set if this instruction has a predicate operand that -// controls execution. It may be set to 'always'. +const unsigned M_VARIADIC = 1 << 13; const unsigned M_PREDICABLE = 1 << 14; - -// M_REMATERIALIZIBLE - Set if this instruction can be trivally re-materialized -// at any time, e.g. constant generation, load from constant pool. const unsigned M_REMATERIALIZIBLE = 1 << 15; - -// M_NOT_DUPLICABLE - Set if this instruction cannot be safely duplicated. -// (e.g. instructions with unique labels attached). const unsigned M_NOT_DUPLICABLE = 1 << 16; - const unsigned M_HAS_OPTIONAL_DEF = 1 << 17; - -// M_NEVER_HAS_SIDE_EFFECTS - Set if this instruction has no side effects that -// are not captured by any operands of the instruction or other flags, and when -// *all* instances of the instruction of that opcode have no side effects. -// -// Note: This and M_MAY_HAVE_SIDE_EFFECTS are mutually exclusive. You can't set -// both! If neither flag is set, then the instruction *always* has side effects. const unsigned M_NEVER_HAS_SIDE_EFFECTS = 1 << 18; - -// M_MAY_HAVE_SIDE_EFFECTS - Set if some instances of this instruction can have -// side effects. The virtual method "isReallySideEffectFree" is called to -// determine this. Load instructions are an example of where this is useful. In -// general, loads always have side effects. However, loads from constant pools -// don't. We let the specific back end make this determination. -// -// Note: This and M_NEVER_HAS_SIDE_EFFECTS are mutually exclusive. You can't set -// both! If neither flag is set, then the instruction *always* has side effects. const unsigned M_MAY_HAVE_SIDE_EFFECTS = 1 << 19; @@ -250,6 +200,15 @@ const unsigned *getImplicitDefs() const { return ImplicitDefs; } + + /// getSchedClass - Return the scheduling class for this instruction. The + /// scheduling class is an index into the InstrItineraryData table. This + /// returns zero if there is no known scheduling information for the + /// instruction. + /// + unsigned getSchedClass() const { + return SchedClass; + } bool isReturn() const { return Flags & M_RET_FLAG; @@ -313,31 +272,27 @@ return isBranch() & isBarrier() & !isIndirectBranch(); } + // isPredicable - Return true if this instruction has a predicate operand that + // controls execution. It may be set to 'always', or may be set to other + /// values. There are various methods in TargetInstrInfo that can be used to + /// control and modify the predicate in this instruction. bool isPredicable() const { return Flags & M_PREDICABLE; } + /// isNotDuplicable - Return true if this instruction cannot be safely + /// duplicated. For example, if the instruction has a unique labels attached + /// to it, duplicating it would cause multiple definition errors. bool isNotDuplicable() const { return Flags & M_NOT_DUPLICABLE; } - bool isCommutableInstr() const { - return Flags & M_COMMUTABLE; - } - /// hasDelaySlot - Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. bool hasDelaySlot() const { return 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() const { - return Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; - } - /// isSimpleLoad - Return true for instructions that are simple loads from /// memory. This should only be set on instructions that load a value from /// memory and return it in their only virtual register definition. @@ -347,6 +302,10 @@ return Flags & M_SIMPLE_LOAD_FLAG; } + //===--------------------------------------------------------------------===// + // Side Effect Analysis + //===--------------------------------------------------------------------===// + /// mayStore - Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or @@ -355,8 +314,95 @@ return Flags & M_MAY_STORE_FLAG; } - unsigned getSchedClass() const { - return SchedClass; + // TODO: mayLoad. + + /// hasNoSideEffects - Return true if all instances of this instruction are + /// guaranteed to have no side effects other than: + /// 1. The register operands that are def/used by the MachineInstr. + /// 2. Registers that are implicitly def/used by the MachineInstr. + /// 3. Memory Accesses captured by mayLoad() or mayStore(). + /// + /// Examples of other side effects would be calling a function, modifying + /// 'invisible' machine state like a control register, etc. + /// + /// If some instances of this instruction are side-effect free but others are + /// not, the hasConditionalSideEffects() property should return true, not this + /// one. + /// + /// Note that you should not call this method directly, instead, call the + /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis + /// of the machine instruction. + bool hasNoSideEffects() const { + return Flags & M_NEVER_HAS_SIDE_EFFECTS; + } + + /// hasConditionalSideEffects - Return true if some instances of this + /// instruction are guaranteed to have no side effects other than those listed + /// for hasNoSideEffects(). To determine whether a specific machineinstr has + /// side effects, the TargetInstrInfo::isReallySideEffectFree virtual method + /// is invoked to decide. + /// + /// Note that you should not call this method directly, instead, call the + /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis + /// of the machine instruction. + bool hasConditionalSideEffects() const { + return Flags & M_MAY_HAVE_SIDE_EFFECTS; + } + + //===--------------------------------------------------------------------===// + // Flags that indicate whether an instruction can be modified by a method. + //===--------------------------------------------------------------------===// + + /// isCommutableInstr - Return true if this may be a 2- or 3-address + /// instruction (of the form "X = op Y, Z, ..."), which produces the same + /// result if Y and Z are exchanged. If this flag is set, then the + /// TargetInstrInfo::commuteInstruction method may be used to hack on the + /// instruction. + /// + /// Note that this flag may be set on instructions that are only commutable + /// sometimes. In these cases, the call to commuteInstruction will fail. + /// Also note that some instructions require non-trivial modification to + /// commute them. + bool isCommutableInstr() const { + return Flags & M_COMMUTABLE; + } + + /// isConvertibleTo3Addr - Return true if this is a 2-address instruction + /// which can be changed into a 3-address instruction if needed. Doing this + /// transformation can be profitable in the register allocator, because it + /// means that the instruction can use a 2-address form if possible, but + /// degrade into a less efficient form if the source and dest register cannot + /// be assigned to the same register. For example, this allows the x86 + /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which + /// is the same speed as the shift but has bigger code size. + /// + /// If this returns true, then the target must implement the + /// TargetInstrInfo::convertToThreeAddress method for this instruction, which + /// is allowed to fail if the transformation isn't valid for this specific + /// instruction (e.g. shl reg, 4 on x86). + /// + bool isConvertibleTo3Addr() const { + return Flags & M_CONVERTIBLE_TO_3_ADDR; + } + + /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires + /// custom insertion support when the DAG scheduler is inserting it into a + /// machine basic block. If this is true for the instruction, it basically + /// means that it is a pseudo instruction used at SelectionDAG time that is + /// expanded out into magic code by the target when MachineInstrs are formed. + /// + /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method + /// is used to insert this into the MachineBasicBlock. + bool usesCustomDAGSchedInsertionHook() const { + return Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; + } + + /// isRematerializable - Returns true if this instruction is a candidate for + /// remat. This flag is deprecated, please don't use it anymore. If this + /// flag is set, the isReallyTriviallyReMaterializable() method is called to + /// verify the instruction is really rematable. + bool isRematerializable() const { + return Flags & M_REMATERIALIZIBLE; } }; @@ -399,7 +445,7 @@ /// rematerializable, meaning it has no side effects and requires no operands /// that aren't always available. bool isTriviallyReMaterializable(MachineInstr *MI) const { - return (MI->getDesc()->Flags & M_REMATERIALIZIBLE) && + return MI->getDesc()->isRematerializable() && isReallyTriviallyReMaterializable(MI); } @@ -408,8 +454,8 @@ /// flags. bool hasUnmodelledSideEffects(MachineInstr *MI) const { const TargetInstrDescriptor *TID = MI->getDesc(); - if (TID->Flags & M_NEVER_HAS_SIDE_EFFECTS) return false; - if (!(TID->Flags & M_MAY_HAVE_SIDE_EFFECTS)) return true; + if (TID->hasNoSideEffects()) return false; + if (!TID->hasConditionalSideEffects()) return true; return !isReallySideEffectFree(MI); // May have side effects } protected: Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=45690&r1=45689&r2=45690&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Jan 7 00:21:53 2008 @@ -710,7 +710,7 @@ } // Now that we have emitted all operands, emit this instruction itself. - if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { + if (!II.usesCustomDAGSchedInsertionHook()) { BB->insert(BB->end(), MI); } else { // Insert this instruction into the end of the basic block, potentially Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=45690&r1=45689&r2=45690&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Jan 7 00:21:53 2008 @@ -172,7 +172,7 @@ // If this instruction is potentially convertible to a true // three-address instruction, - if (TID->Flags & M_CONVERTIBLE_TO_3_ADDR) { + if (TID->isConvertibleTo3Addr()) { // FIXME: This assumes there are no more operands which are tied // to another register. #ifndef NDEBUG From sabre at nondot.org Mon Jan 7 00:37:29 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 06:37:29 -0000 Subject: [llvm-commits] [llvm] r45691 - /llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Message-ID: <200801070637.m076bT4o001405@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 00:37:29 2008 New Revision: 45691 URL: http://llvm.org/viewvc/llvm-project?rev=45691&view=rev Log: use predicate. Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=45691&r1=45690&r2=45691&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Mon Jan 7 00:37:29 2008 @@ -73,7 +73,7 @@ const TargetInstrDescriptor &TID = TII.get(Opcode); isLoad = TID.isSimpleLoad(); - isStore = TID.Flags & M_MAY_STORE_FLAG; + isStore = TID.mayStore(); unsigned TSFlags = TID.TSFlags; From sabre at nondot.org Mon Jan 7 00:42:06 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 06:42:06 -0000 Subject: [llvm-commits] [llvm] r45692 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/CodeGen/TwoAddressInstructionPass.cpp lib/Target/ARM/ARMInstrInfo.cpp utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200801070642.m076g7ve001946@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 00:42:05 2008 New Revision: 45692 URL: http://llvm.org/viewvc/llvm-project?rev=45692&view=rev Log: Rename all the M_* flags to be namespace qualified enums, and switch all clients over to using predicates instead of these flags directly. These are now private values which are only to be used to statically initialize the tables. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45692&r1=45691&r2=45692&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Jan 7 00:42:05 2008 @@ -22,8 +22,6 @@ namespace llvm { -class MachineInstr; -class TargetMachine; class TargetRegisterClass; class LiveVariables; class CalleeSavedInfo; @@ -46,9 +44,9 @@ /// private, all access should go through the TargetOperandInfo accessors. /// See the accessors for a description of what these are. enum OperandFlags { - LookupPtrRegClass = 1 << 0, - Predicate = 1 << 1, - OptionalDef = 1 << 2 + LookupPtrRegClass = 0, + Predicate, + OptionalDef }; } @@ -68,15 +66,15 @@ /// isLookupPtrRegClass - Set if this operand is a pointer value and it /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags & TOI::LookupPtrRegClass; } + bool isLookupPtrRegClass() const { return Flags&(1 <isCommutable = true; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=45692&r1=45691&r2=45692&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Jan 7 00:42:05 2008 @@ -437,7 +437,7 @@ break; } } - if (TID->Flags & M_COMMUTABLE) + if (TID->isCommutable()) NewSU->isCommutable = true; // FIXME: Calculate height / depth and propagate the changes? NewSU->Depth = SU->Depth; Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=45692&r1=45691&r2=45692&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Jan 7 00:42:05 2008 @@ -144,7 +144,7 @@ // so, swap the B and C operands. This makes the live ranges of A // and C joinable. // FIXME: This code also works for A := B op C instructions. - if ((TID->Flags & M_COMMUTABLE) && mi->getNumOperands() >= 3) { + if (TID->isCommutable() && mi->getNumOperands() >= 3) { assert(mi->getOperand(3-si).isRegister() && "Not a proper commutative instruction!"); unsigned regC = mi->getOperand(3-si).getReg(); Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=45692&r1=45691&r2=45692&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Mon Jan 7 00:42:05 2008 @@ -838,7 +838,7 @@ bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI, std::vector &Pred) const { const TargetInstrDescriptor *TID = MI->getDesc(); - if (!TID->ImplicitDefs && (TID->Flags & M_HAS_OPTIONAL_DEF) == 0) + if (!TID->getImplicitDefs() && !TID->hasOptionalDef()) return false; bool Found = false; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45692&r1=45691&r2=45692&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Mon Jan 7 00:42:05 2008 @@ -94,17 +94,17 @@ // Ptr value whose register class is resolved via callback. if (OpR->getName() == "ptr_rc") - Res += "|TOI::LookupPtrRegClass"; + Res += "|(1<isSubClassOf("PredicateOperand")) - Res += "|TOI::Predicate"; + Res += "|(1<isSubClassOf("OptionalDefOperand")) - Res += "|TOI::OptionalDef"; + Res += "|(1<getName() @@ -302,27 +302,27 @@ << ",\t\"" << Inst.TheDef->getName() << "\", 0"; // Emit all of the target indepedent flags... - if (Inst.isReturn) OS << "|M_RET_FLAG"; - if (Inst.isBranch) OS << "|M_BRANCH_FLAG"; - if (Inst.isIndirectBranch) OS << "|M_INDIRECT_FLAG"; - if (Inst.isBarrier) OS << "|M_BARRIER_FLAG"; - if (Inst.hasDelaySlot) OS << "|M_DELAY_SLOT_FLAG"; - if (Inst.isCall) OS << "|M_CALL_FLAG"; - if (isLoad) OS << "|M_SIMPLE_LOAD_FLAG"; - if (mayStore) OS << "|M_MAY_STORE_FLAG"; - if (Inst.isImplicitDef)OS << "|M_IMPLICIT_DEF_FLAG"; - if (Inst.isPredicable) OS << "|M_PREDICABLE"; - if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR"; - if (Inst.isCommutable) OS << "|M_COMMUTABLE"; - if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG"; - if (Inst.isReMaterializable) OS << "|M_REMATERIALIZIBLE"; - if (Inst.isNotDuplicable) OS << "|M_NOT_DUPLICABLE"; - if (Inst.hasOptionalDef) OS << "|M_HAS_OPTIONAL_DEF"; + if (Inst.isReturn) OS << "|(1< Author: lattner Date: Mon Jan 7 00:47:00 2008 New Revision: 45693 URL: http://llvm.org/viewvc/llvm-project?rev=45693&view=rev Log: simplify some code. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=45693&r1=45692&r2=45693&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Jan 7 00:47:00 2008 @@ -148,10 +148,11 @@ if (!SU || !SU->Node) continue; if (SU->isCommutable) { unsigned Opc = SU->Node->getTargetOpcode(); - unsigned NumRes = TII->get(Opc).getNumDefs(); + const TargetInstrDescriptor &TID = TII->get(Opc); + unsigned NumRes = TID.getNumDefs(); unsigned NumOps = CountOperands(SU->Node); for (unsigned j = 0; j != NumOps; ++j) { - if (TII->getOperandConstraint(Opc, j+NumRes, TOI::TIED_TO) == -1) + if (TID.getOperandConstraint(j+NumRes, TOI::TIED_TO) == -1) continue; SDNode *OpN = SU->Node->getOperand(j).Val; @@ -430,14 +431,14 @@ SUnit *NewSU = NewSUnit(N); SUnitMap[N].push_back(NewSU); - const TargetInstrDescriptor *TID = &TII->get(N->getTargetOpcode()); - for (unsigned i = 0; i != TID->getNumOperands(); ++i) { - if (TID->getOperandConstraint(i, TOI::TIED_TO) != -1) { + const TargetInstrDescriptor &TID = TII->get(N->getTargetOpcode()); + for (unsigned i = 0; i != TID.getNumOperands(); ++i) { + if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { NewSU->isTwoAddress = true; break; } } - if (TID->isCommutable()) + if (TID.isCommutable()) NewSU->isCommutable = true; // FIXME: Calculate height / depth and propagate the changes? NewSU->Depth = SU->Depth; @@ -1287,10 +1288,11 @@ bool BURegReductionPriorityQueue::canClobber(SUnit *SU, SUnit *Op) { if (SU->isTwoAddress) { unsigned Opc = SU->Node->getTargetOpcode(); - unsigned NumRes = TII->get(Opc).getNumDefs(); + const TargetInstrDescriptor &TID = TII->get(Opc); + unsigned NumRes = TID.getNumDefs(); unsigned NumOps = ScheduleDAG::CountOperands(SU->Node); for (unsigned i = 0; i != NumOps; ++i) { - if (TII->getOperandConstraint(Opc, i+NumRes, TOI::TIED_TO) != -1) { + if (TID.getOperandConstraint(i+NumRes, TOI::TIED_TO) != -1) { SDNode *DU = SU->Node->getOperand(i).Val; if ((*SUnitMap).find(DU) != (*SUnitMap).end() && Op == (*SUnitMap)[DU][SU->InstanceNo]) @@ -1362,10 +1364,11 @@ continue; unsigned Opc = Node->getTargetOpcode(); - unsigned NumRes = TII->get(Opc).getNumDefs(); + const TargetInstrDescriptor &TID = TII->get(Opc); + unsigned NumRes = TID.getNumDefs(); unsigned NumOps = ScheduleDAG::CountOperands(Node); for (unsigned j = 0; j != NumOps; ++j) { - if (TII->getOperandConstraint(Opc, j+NumRes, TOI::TIED_TO) != -1) { + if (TID.getOperandConstraint(j+NumRes, TOI::TIED_TO) != -1) { SDNode *DU = SU->Node->getOperand(j).Val; if ((*SUnitMap).find(DU) == (*SUnitMap).end()) continue; From sabre at nondot.org Mon Jan 7 00:47:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 06:47:10 -0000 Subject: [llvm-commits] [llvm] r45694 - /llvm/trunk/include/llvm/Target/TargetInstrInfo.h Message-ID: <200801070647.m076lAOn002139@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 00:47:10 2008 New Revision: 45694 URL: http://llvm.org/viewvc/llvm-project?rev=45694&view=rev Log: remove a dead method. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45694&r1=45693&r2=45694&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Jan 7 00:47:10 2008 @@ -490,13 +490,6 @@ return false; } public: - /// getOperandConstraint - Returns the value of the specific constraint if - /// it is set. Returns -1 if it is not set. - int getOperandConstraint(unsigned Opcode, unsigned OpNum, - TOI::OperandConstraint Constraint) const { - return get(Opcode).getOperandConstraint(OpNum, Constraint); - } - /// Return true if the instruction is a register to register move /// and leave the source and dest operands in the passed parameters. virtual bool isMoveInstr(const MachineInstr& MI, From sabre at nondot.org Mon Jan 7 01:27:39 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 07:27:39 -0000 Subject: [llvm-commits] [llvm] r45695 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/ARM/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ utils/TableGen/ Message-ID: <200801070727.m077ReL0004336@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 01:27:27 2008 New Revision: 45695 URL: http://llvm.org/viewvc/llvm-project?rev=45695&view=rev Log: rename TargetInstrDescriptor -> TargetInstrDesc. Make MachineInstr::getDesc return a reference instead of a pointer, since it can never be null. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/include/llvm/Target/TargetMachine.h llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/Collector.cpp llvm/trunk/lib/CodeGen/DwarfWriter.cpp llvm/trunk/lib/CodeGen/IfConversion.cpp llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/LiveVariables.cpp llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp llvm/trunk/lib/CodeGen/RegAllocLocal.cpp llvm/trunk/lib/CodeGen/RegAllocSimple.cpp llvm/trunk/lib/CodeGen/RegisterScavenging.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/Sparc/DelaySlotFiller.cpp llvm/trunk/lib/Target/TargetInstrInfo.cpp llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Mon Jan 7 01:27:27 2008 @@ -20,7 +20,7 @@ namespace llvm { -class TargetInstrDescriptor; +class TargetInstrDesc; template struct ilist_traits; template struct ilist; @@ -29,7 +29,7 @@ /// MachineInstr - Representation of each machine instruction. /// class MachineInstr { - const TargetInstrDescriptor *TID; // Instruction descriptor. + const TargetInstrDesc *TID; // Instruction descriptor. unsigned short NumImplicitOps; // Number of implicit operands (which // are determined at construction time). @@ -54,14 +54,14 @@ /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by - /// TargetInstrDescriptor. - explicit MachineInstr(const TargetInstrDescriptor &TID, bool NoImp = false); + /// TargetInstrDesc. + explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false); /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic /// block. /// - MachineInstr(MachineBasicBlock *MBB, const TargetInstrDescriptor &TID); + MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID); ~MachineInstr(); @@ -70,7 +70,7 @@ /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. - const TargetInstrDescriptor *getDesc() const { return TID; } + const TargetInstrDesc &getDesc() const { return *TID; } /// getOpcode - Returns the opcode of this MachineInstr. /// @@ -166,7 +166,7 @@ /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of /// the current instruction with a new one. /// - void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; } + void setInstrDescriptor(const TargetInstrDesc &tid) { TID = &tid; } /// RemoveOperand - Erase an operand from an instruction, leaving it with one /// fewer operand than it started with. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h Mon Jan 7 01:27:27 2008 @@ -22,7 +22,7 @@ namespace llvm { -class TargetInstrDescriptor; +class TargetInstrDesc; class MachineInstrBuilder { MachineInstr *MI; @@ -88,14 +88,14 @@ /// BuildMI - Builder interface. Specify how to create the initial instruction /// itself. /// -inline MachineInstrBuilder BuildMI(const TargetInstrDescriptor &TID) { +inline MachineInstrBuilder BuildMI(const TargetInstrDesc &TID) { return MachineInstrBuilder(new MachineInstr(TID)); } /// BuildMI - This version of the builder sets up the first operand as a /// destination virtual register. /// -inline MachineInstrBuilder BuildMI(const TargetInstrDescriptor &TID, +inline MachineInstrBuilder BuildMI(const TargetInstrDesc &TID, unsigned DestReg) { return MachineInstrBuilder(new MachineInstr(TID)).addReg(DestReg, true); } @@ -106,7 +106,7 @@ /// inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, - const TargetInstrDescriptor &TID, + const TargetInstrDesc &TID, unsigned DestReg) { MachineInstr *MI = new MachineInstr(TID); BB.insert(I, MI); @@ -119,7 +119,7 @@ /// inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, - const TargetInstrDescriptor &TID) { + const TargetInstrDesc &TID) { MachineInstr *MI = new MachineInstr(TID); BB.insert(I, MI); return MachineInstrBuilder(MI); @@ -130,7 +130,7 @@ /// destination register. /// inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, - const TargetInstrDescriptor &TID) { + const TargetInstrDesc &TID) { return BuildMI(*BB, BB->end(), TID); } @@ -139,7 +139,7 @@ /// operand as a destination virtual register. /// inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, - const TargetInstrDescriptor &TID, + const TargetInstrDesc &TID, unsigned DestReg) { return BuildMI(*BB, BB->end(), TID, DestReg); } Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Jan 7 01:27:27 2008 @@ -31,7 +31,7 @@ class SelectionDAG; class SelectionDAGISel; class TargetInstrInfo; - class TargetInstrDescriptor; + class TargetInstrDesc; class TargetMachine; class TargetRegisterClass; @@ -335,7 +335,7 @@ DenseMap &VRBaseMap); void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, - const TargetInstrDescriptor &II, + const TargetInstrDesc &II, DenseMap &VRBaseMap); void EmitSchedule(); @@ -353,7 +353,7 @@ DenseMap &VRBaseMap); void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, - const TargetInstrDescriptor *II, + const TargetInstrDesc *II, DenseMap &VRBaseMap); }; Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Jan 7 01:27:27 2008 @@ -82,10 +82,10 @@ // Machine Instruction Flags and Description //===----------------------------------------------------------------------===// -/// TargetInstrDescriptor flags - These should be considered private to the -/// implementation of the TargetInstrDescriptor class. Clients should use the -/// predicate methods on TargetInstrDescriptor, not use these directly. These -/// all correspond to bitfields in the TargetInstrDescriptor::Flags field. +/// TargetInstrDesc flags - These should be considered private to the +/// implementation of the TargetInstrDesc class. Clients should use the +/// predicate methods on TargetInstrDesc, not use these directly. These +/// all correspond to bitfields in the TargetInstrDesc::Flags field. namespace TID { enum { Variadic = 0, @@ -111,12 +111,12 @@ }; } -/// TargetInstrDescriptor - Describe properties that are true of each +/// TargetInstrDesc - Describe properties that are true of each /// instruction in the target description file. This captures information about /// side effects, register use and many other things. There is one instance of /// this struct for each target instruction class, and the MachineInstr class /// points to this struct directly to describe itself. -class TargetInstrDescriptor { +class TargetInstrDesc { public: unsigned short Opcode; // The opcode number. unsigned short NumOperands; // Num of args (may be more if variable_ops) @@ -147,6 +147,11 @@ /// dest operand. Returns -1 if there isn't one. int findTiedToSrcOperand(unsigned OpNum) const; + /// getOpcode - Return the opcode number for this descriptor. + unsigned getOpcode() const { + return Opcode; + } + /// getName - Return the name of the record in the .td file for this /// instruction, for example "ADD8ri". const char *getName() const { @@ -421,14 +426,13 @@ /// TargetInstrInfo - Interface to description of machine instructions /// class TargetInstrInfo { - const TargetInstrDescriptor* desc; // raw array to allow static init'n - unsigned NumOpcodes; // number of entries in the desc array - unsigned numRealOpCodes; // number of non-dummy op codes + const TargetInstrDesc *Descriptors; // Raw array to allow static init'n + unsigned NumOpcodes; // Number of entries in the desc array TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT public: - TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes); + TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes); virtual ~TargetInstrInfo(); // Invariant opcodes: All instruction sets have these as their low opcodes. @@ -445,16 +449,16 @@ /// get - Return the machine instruction descriptor that corresponds to the /// specified instruction opcode. /// - const TargetInstrDescriptor& get(unsigned Opcode) const { - assert(Opcode < NumOpcodes); - return desc[Opcode]; + const TargetInstrDesc &get(unsigned Opcode) const { + assert(Opcode < NumOpcodes && "Invalid opcode!"); + return Descriptors[Opcode]; } /// isTriviallyReMaterializable - Return true if the instruction is trivially /// rematerializable, meaning it has no side effects and requires no operands /// that aren't always available. bool isTriviallyReMaterializable(MachineInstr *MI) const { - return MI->getDesc()->isRematerializable() && + return MI->getDesc().isRematerializable() && isReallyTriviallyReMaterializable(MI); } @@ -462,9 +466,9 @@ /// effects that are not captured by any operands of the instruction or other /// flags. bool hasUnmodelledSideEffects(MachineInstr *MI) const { - const TargetInstrDescriptor *TID = MI->getDesc(); - if (TID->hasNoSideEffects()) return false; - if (!TID->hasConditionalSideEffects()) return true; + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.hasNoSideEffects()) return false; + if (!TID.hasConditionalSideEffects()) return true; return !isReallySideEffectFree(MI); // May have side effects } protected: @@ -773,7 +777,7 @@ /// libcodegen, not in libtarget. class TargetInstrInfoImpl : public TargetInstrInfo { protected: - TargetInstrInfoImpl(const TargetInstrDescriptor *desc, unsigned NumOpcodes) + TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) : TargetInstrInfo(desc, NumOpcodes) {} public: virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; Modified: llvm/trunk/include/llvm/Target/TargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetMachine.h (original) +++ llvm/trunk/include/llvm/Target/TargetMachine.h Mon Jan 7 01:27:27 2008 @@ -24,7 +24,6 @@ class TargetData; class TargetSubtarget; class TargetInstrInfo; -class TargetInstrDescriptor; class TargetJITInfo; class TargetLowering; class TargetFrameInfo; Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Mon Jan 7 01:27:27 2008 @@ -349,10 +349,10 @@ MachineBasicBlock::iterator E) { unsigned Time = 0; for (; I != E; ++I) { - const TargetInstrDescriptor *TID = I->getDesc(); - if (TID->isCall()) + const TargetInstrDesc &TID = I->getDesc(); + if (TID.isCall()) Time += 10; - else if (TID->isSimpleLoad() || TID->mayStore()) + else if (TID.isSimpleLoad() || TID.mayStore()) Time += 2; else ++Time; @@ -778,7 +778,7 @@ MachineInstr *MBB1I = --MBB1->end(); MachineInstr *MBB2I = --MBB2->end(); - return MBB2I->getDesc()->isCall() && !MBB1I->getDesc()->isCall(); + return MBB2I->getDesc().isCall() && !MBB1I->getDesc().isCall(); } /// OptimizeBlock - Analyze and optimize control flow related to the specified @@ -958,7 +958,7 @@ // If this branch is the only thing in its block, see if we can forward // other blocks across it. if (CurTBB && CurCond.empty() && CurFBB == 0 && - MBB->begin()->getDesc()->isBranch() && CurTBB != MBB) { + MBB->begin()->getDesc().isBranch() && CurTBB != MBB) { // This block may contain just an unconditional branch. Because there can // be 'non-branch terminators' in the block, try removing the branch and // then seeing if the block is empty. Modified: llvm/trunk/lib/CodeGen/Collector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Collector.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Collector.cpp (original) +++ llvm/trunk/lib/CodeGen/Collector.cpp Mon Jan 7 01:27:27 2008 @@ -359,7 +359,7 @@ BBE = MF.end(); BBI != BBE; ++BBI) for (MachineBasicBlock::iterator MI = BBI->begin(), ME = BBI->end(); MI != ME; ++MI) - if (MI->getDesc()->isCall()) + if (MI->getDesc().isCall()) VisitCallPoint(*MI); } Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Mon Jan 7 01:27:27 2008 @@ -3153,7 +3153,7 @@ for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); MI != E; ++MI) { if (MI->getOpcode() != TargetInstrInfo::LABEL) { - SawPotentiallyThrowing |= MI->getDesc()->isCall(); + SawPotentiallyThrowing |= MI->getDesc().isCall(); continue; } Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original) +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Mon Jan 7 01:27:27 2008 @@ -460,7 +460,7 @@ MachineBasicBlock::iterator I = BB->end(); while (I != BB->begin()) { --I; - if (!I->getDesc()->isBranch()) + if (!I->getDesc().isBranch()) break; } return I; @@ -548,12 +548,12 @@ bool SeenCondBr = false; for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end(); I != E; ++I) { - const TargetInstrDescriptor *TID = I->getDesc(); - if (TID->isNotDuplicable()) + const TargetInstrDesc &TID = I->getDesc(); + if (TID.isNotDuplicable()) BBI.CannotBeCopied = true; bool isPredicated = TII->isPredicated(I); - bool isCondBr = BBI.IsBrAnalyzable && TID->isConditionalBranch(); + bool isCondBr = BBI.IsBrAnalyzable && TID.isConditionalBranch(); if (!isCondBr) { if (!isPredicated) @@ -590,7 +590,7 @@ if (TII->DefinesPredicate(I, PredDefs)) BBI.ClobbersPred = true; - if (!TID->isPredicable()) { + if (!TID.isPredicable()) { BBI.IsUnpredicable = true; return; } @@ -1132,10 +1132,10 @@ bool IgnoreBr) { for (MachineBasicBlock::iterator I = FromBBI.BB->begin(), E = FromBBI.BB->end(); I != E; ++I) { - const TargetInstrDescriptor *TID = I->getDesc(); + const TargetInstrDesc &TID = I->getDesc(); bool isPredicated = TII->isPredicated(I); // Do not copy the end of the block branches. - if (IgnoreBr && !isPredicated && TID->isBranch()) + if (IgnoreBr && !isPredicated && TID.isBranch()) break; MachineInstr *MI = I->clone(); Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Jan 7 01:27:27 2008 @@ -615,9 +615,9 @@ return false; isLoad = false; - const TargetInstrDescriptor *TID = MI->getDesc(); - if (TID->isImplicitDef() || tii_->isTriviallyReMaterializable(MI)) { - isLoad = TID->isSimpleLoad(); + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.isImplicitDef() || tii_->isTriviallyReMaterializable(MI)) { + isLoad = TID.isSimpleLoad(); return true; } @@ -679,9 +679,9 @@ SmallVector &Ops, bool isSS, int Slot, unsigned Reg) { unsigned MRInfo = 0; - const TargetInstrDescriptor *TID = MI->getDesc(); + const TargetInstrDesc &TID = MI->getDesc(); // If it is an implicit def instruction, just delete it. - if (TID->isImplicitDef()) { + if (TID.isImplicitDef()) { RemoveMachineInstrFromMaps(MI); vrm.RemoveMachineInstrFromMaps(MI); MI->eraseFromParent(); @@ -699,7 +699,7 @@ MRInfo |= (unsigned)VirtRegMap::isMod; else { // Filter out two-address use operand(s). - if (TID->getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) { + if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) { MRInfo = VirtRegMap::isModRef; continue; } @@ -1225,7 +1225,7 @@ int LdSlot = 0; bool isLoadSS = DefIsReMat && tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot); bool isLoad = isLoadSS || - (DefIsReMat && (ReMatDefMI->getDesc()->isSimpleLoad())); + (DefIsReMat && (ReMatDefMI->getDesc().isSimpleLoad())); bool IsFirstRange = true; for (LiveInterval::Ranges::const_iterator I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { @@ -1307,7 +1307,7 @@ int LdSlot = 0; bool isLoadSS = DefIsReMat && tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot); bool isLoad = isLoadSS || - (DefIsReMat && ReMatDefMI->getDesc()->isSimpleLoad()); + (DefIsReMat && ReMatDefMI->getDesc().isSimpleLoad()); rewriteInstructionsForSpills(li, TrySplit, I, ReMatOrigDefMI, ReMatDefMI, Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, CanDelete, vrm, RegInfo, rc, ReMatIds, loopInfo, @@ -1422,7 +1422,7 @@ int LdSlot = 0; bool isLoadSS = tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot); // If the rematerializable def is a load, also try to fold it. - if (isLoadSS || ReMatDefMI->getDesc()->isSimpleLoad()) + if (isLoadSS || ReMatDefMI->getDesc().isSimpleLoad()) Folded = tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index, Ops, isLoadSS, LdSlot, VReg); } @@ -1450,7 +1450,7 @@ MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx); int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg); assert(UseIdx != -1); - if (LastUse->getDesc()->getOperandConstraint(UseIdx, TOI::TIED_TO) == + if (LastUse->getDesc().getOperandConstraint(UseIdx, TOI::TIED_TO) == -1) { LastUse->getOperand(UseIdx).setIsKill(); vrm.addKillPoint(LI->reg, LastUseIdx); Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Mon Jan 7 01:27:27 2008 @@ -535,7 +535,7 @@ // Finally, if the last instruction in the block is a return, make sure to mark // it as using all of the live-out values in the function. - if (!MBB->empty() && MBB->back().getDesc()->isReturn()) { + if (!MBB->empty() && MBB->back().getDesc().isReturn()) { MachineInstr *Ret = &MBB->back(); for (MachineRegisterInfo::liveout_iterator I = MF->getRegInfo().liveout_begin(), Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Mon Jan 7 01:27:27 2008 @@ -132,9 +132,9 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() { iterator I = end(); - while (I != begin() && (--I)->getDesc()->isTerminator()) + while (I != begin() && (--I)->getDesc().isTerminator()) ; /*noop */ - if (I != end() && !I->getDesc()->isTerminator()) ++I; + if (I != end() && !I->getDesc().isTerminator()) ++I; return I; } @@ -261,7 +261,7 @@ MachineBasicBlock::iterator I = end(); while (I != begin()) { --I; - if (!I->getDesc()->isTerminator()) break; + if (!I->getDesc().isTerminator()) break; // Scan the operands of this machine instruction, replacing any uses of Old // with New. Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Mon Jan 7 01:27:27 2008 @@ -248,9 +248,9 @@ /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by -/// TargetInstrDescriptor or the numOperands if it is not zero. (for +/// TargetInstrDesc or the numOperands if it is not zero. (for /// instructions with variable number of operands). -MachineInstr::MachineInstr(const TargetInstrDescriptor &tid, bool NoImp) +MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) : TID(&tid), NumImplicitOps(0), Parent(0) { if (!NoImp && TID->getImplicitDefs()) for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) @@ -269,7 +269,7 @@ /// MachineInstr is created and added to the end of the specified basic block. /// MachineInstr::MachineInstr(MachineBasicBlock *MBB, - const TargetInstrDescriptor &tid) + const TargetInstrDesc &tid) : TID(&tid), NumImplicitOps(0), Parent(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); if (TID->ImplicitDefs) @@ -288,7 +288,7 @@ /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(const MachineInstr &MI) { - TID = MI.getDesc(); + TID = &MI.getDesc(); NumImplicitOps = MI.NumImplicitOps; Operands.reserve(MI.getNumOperands()); @@ -537,10 +537,10 @@ /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int MachineInstr::findFirstPredOperandIdx() const { - const TargetInstrDescriptor *TID = getDesc(); - if (TID->isPredicable()) { + const TargetInstrDesc &TID = getDesc(); + if (TID.isPredicable()) { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (TID->OpInfo[i].isPredicate()) + if (TID.OpInfo[i].isPredicate()) return i; } @@ -550,14 +550,14 @@ /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due /// to two addr elimination. bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg) const { - const TargetInstrDescriptor *TID = getDesc(); + const TargetInstrDesc &TID = getDesc(); for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { const MachineOperand &MO1 = getOperand(i); if (MO1.isRegister() && MO1.isDef() && MO1.getReg() == Reg) { for (unsigned j = i+1; j < e; ++j) { const MachineOperand &MO2 = getOperand(j); if (MO2.isRegister() && MO2.isUse() && MO2.getReg() == Reg && - TID->getOperandConstraint(j, TOI::TIED_TO) == (int)i) + TID.getOperandConstraint(j, TOI::TIED_TO) == (int)i) return true; } } @@ -587,10 +587,10 @@ /// copyPredicates - Copies predicate operand(s) from MI. void MachineInstr::copyPredicates(const MachineInstr *MI) { - const TargetInstrDescriptor *TID = MI->getDesc(); - if (TID->isPredicable()) { + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.isPredicable()) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - if (TID->OpInfo[i].isPredicate()) { + if (TID.OpInfo[i].isPredicate()) { // Predicated operands must be last operands. addOperand(MI->getOperand(i)); } @@ -611,7 +611,7 @@ ++StartOp; // Don't print this operand again! } - OS << getDesc()->Name; + OS << getDesc().getName(); for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { if (i != StartOp) Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Mon Jan 7 01:27:27 2008 @@ -225,20 +225,20 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { DEBUG({ DOUT << "--- Checking if we can hoist " << I; - if (I.getDesc()->ImplicitUses) { + if (I.getDesc().getImplicitUses()) { DOUT << " * Instruction has implicit uses:\n"; const MRegisterInfo *MRI = TM->getRegisterInfo(); - for (const unsigned *ImpUses = I.getDesc()->ImplicitUses; + for (const unsigned *ImpUses = I.getDesc().getImplicitUses(); *ImpUses; ++ImpUses) DOUT << " -> " << MRI->getName(*ImpUses) << "\n"; } - if (I.getDesc()->ImplicitDefs) { + if (I.getDesc().getImplicitDefs()) { DOUT << " * Instruction has implicit defines:\n"; const MRegisterInfo *MRI = TM->getRegisterInfo(); - for (const unsigned *ImpDefs = I.getDesc()->ImplicitDefs; + for (const unsigned *ImpDefs = I.getDesc().getImplicitDefs(); *ImpDefs; ++ImpDefs) DOUT << " -> " << MRI->getName(*ImpDefs) << "\n"; } Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Mon Jan 7 01:27:27 2008 @@ -262,14 +262,14 @@ // Add code to restore the callee-save registers in each exiting block. for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) // If last instruction is a return instruction, add an epilogue. - if (!FI->empty() && FI->back().getDesc()->isReturn()) { + if (!FI->empty() && FI->back().getDesc().isReturn()) { MBB = FI; I = MBB->end(); --I; // Skip over all terminator instructions, which are part of the return // sequence. MachineBasicBlock::iterator I2 = I; - while (I2 != MBB->begin() && (--I2)->getDesc()->isTerminator()) + while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) I = I2; bool AtStart = I == MBB->begin(); @@ -485,7 +485,7 @@ // Add epilogue to restore the callee-save registers in each exiting block for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { // If last instruction is a return instruction, add an epilogue - if (!I->empty() && I->back().getDesc()->isReturn()) + if (!I->empty() && I->back().getDesc().isReturn()) Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); } } Modified: llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp Mon Jan 7 01:27:27 2008 @@ -649,7 +649,7 @@ while (MII != MBB.end()) { MachineInstr *MI = MII++; MBBCurTime++; - const TargetInstrDescriptor &TID = TII.get(MI->getOpcode()); + const TargetInstrDesc &TID = MI->getDesc(); DEBUG(DOUT << "\nTime=" << MBBCurTime << " Starting RegAlloc of: " << *MI; DOUT << " Regs have values: "; for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i) @@ -750,8 +750,8 @@ } // Loop over the implicit defs, spilling them as well. - if (TID.ImplicitDefs) { - for (const unsigned *ImplicitDefs = TID.ImplicitDefs; + if (TID.getImplicitDefs()) { + for (const unsigned *ImplicitDefs = TID.getImplicitDefs(); *ImplicitDefs; ++ImplicitDefs) { unsigned Reg = *ImplicitDefs; if (PhysRegsUsed[Reg] != -2) { Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Mon Jan 7 01:27:27 2008 @@ -563,7 +563,7 @@ // Otherwise, sequentially allocate each instruction in the MBB. while (MII != MBB.end()) { MachineInstr *MI = MII++; - const TargetInstrDescriptor &TID = TII.get(MI->getOpcode()); + const TargetInstrDesc &TID = MI->getDesc(); DEBUG(DOUT << "\nStarting RegAlloc of: " << *MI; DOUT << " Regs have values: "; for (unsigned i = 0; i != MRI->getNumRegs(); ++i) Modified: llvm/trunk/lib/CodeGen/RegAllocSimple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocSimple.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocSimple.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocSimple.cpp Mon Jan 7 01:27:27 2008 @@ -173,7 +173,7 @@ // This is a preliminary pass that will invalidate any registers that are // used by the instruction (including implicit uses). - const TargetInstrDescriptor &Desc = *MI->getDesc(); + const TargetInstrDesc &Desc = MI->getDesc(); const unsigned *Regs; if (Desc.ImplicitUses) { for (Regs = Desc.ImplicitUses; *Regs; ++Regs) @@ -203,7 +203,7 @@ unsigned physReg = Virt2PhysRegMap[virtualReg]; if (physReg == 0) { if (op.isDef()) { - int TiedOp = MI->getDesc()->findTiedToSrcOperand(i); + int TiedOp = Desc.findTiedToSrcOperand(i); if (TiedOp == -1) { physReg = getFreeReg(virtualReg); } else { Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Mon Jan 7 01:27:27 2008 @@ -92,10 +92,11 @@ } MachineInstr *MI = MBBI; + const TargetInstrDesc &TID = MI->getDesc(); // Reaching a terminator instruction. Restore a scavenged register (which // must be life out. - if (MI->getDesc()->isTerminator()) + if (TID.isTerminator()) restoreScavengedReg(); // Process uses first. @@ -122,7 +123,6 @@ setUnused(ChangedRegs); // Process defs. - const TargetInstrDescriptor *TID = MI->getDesc(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isRegister() || !MO.isDef()) @@ -134,7 +134,7 @@ continue; } // Skip two-address destination operand. - if (TID->findTiedToSrcOperand(i) != -1) { + if (TID.findTiedToSrcOperand(i) != -1) { assert(isUsed(Reg) && "Using an undefined register!"); continue; } @@ -152,13 +152,13 @@ MachineInstr *MI = MBBI; // Process defs first. - const TargetInstrDescriptor *TID = MI->getDesc(); + const TargetInstrDesc &TID = MI->getDesc(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isRegister() || !MO.isDef()) continue; // Skip two-address destination operand. - if (TID->findTiedToSrcOperand(i) != -1) + if (TID.findTiedToSrcOperand(i) != -1) continue; unsigned Reg = MO.getReg(); assert(isUsed(Reg)); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Jan 7 01:27:27 2008 @@ -51,7 +51,7 @@ unsigned ResNo = Use->getOperand(2).ResNo; if (Def->isTargetOpcode()) { - const TargetInstrDescriptor &II = TII->get(Def->getTargetOpcode()); + const TargetInstrDesc &II = TII->get(Def->getTargetOpcode()); if (ResNo >= II.getNumDefs() && II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) { PhysReg = Reg; @@ -148,7 +148,7 @@ if (MainNode->isTargetOpcode()) { unsigned Opc = MainNode->getTargetOpcode(); - const TargetInstrDescriptor &TID = TII->get(Opc); + const TargetInstrDesc &TID = TII->get(Opc); for (unsigned i = 0; i != TID.getNumOperands(); ++i) { if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { SU->isTwoAddress = true; @@ -291,15 +291,15 @@ static const TargetRegisterClass *getInstrOperandRegClass( const MRegisterInfo *MRI, const TargetInstrInfo *TII, - const TargetInstrDescriptor *II, + const TargetInstrDesc &II, unsigned Op) { - if (Op >= II->getNumOperands()) { - assert(II->isVariadic() && "Invalid operand # of instruction"); + if (Op >= II.getNumOperands()) { + assert(II.isVariadic() && "Invalid operand # of instruction"); return NULL; } - if (II->OpInfo[Op].isLookupPtrRegClass()) + if (II.OpInfo[Op].isLookupPtrRegClass()) return TII->getPointerRegClass(); - return MRI->getRegClass(II->OpInfo[Op].RegClass); + return MRI->getRegClass(II.OpInfo[Op].RegClass); } void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, @@ -371,7 +371,7 @@ void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, - const TargetInstrDescriptor &II, + const TargetInstrDesc &II, DenseMap &VRBaseMap) { for (unsigned i = 0; i < II.getNumDefs(); ++i) { // If the specific node value is only used by a CopyToReg and the dest reg @@ -396,7 +396,7 @@ // Create the result registers for this node and add the result regs to // the machine instruction. if (VRBase == 0) { - const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, &II, i); + const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, II, i); assert(RC && "Isn't a register operand!"); VRBase = RegInfo.createVirtualRegister(RC); MI->addOperand(MachineOperand::CreateReg(VRBase, true)); @@ -422,7 +422,7 @@ /// assertions only. void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, - const TargetInstrDescriptor *II, + const TargetInstrDesc *II, DenseMap &VRBaseMap) { if (Op.isTargetOpcode()) { // Note that this case is redundant with the final else block, but we @@ -434,16 +434,16 @@ // Get/emit the operand. unsigned VReg = getVR(Op, VRBaseMap); - const TargetInstrDescriptor *TID = MI->getDesc(); - bool isOptDef = (IIOpNum < TID->getNumOperands()) - ? (TID->OpInfo[IIOpNum].isOptionalDef()) : false; + const TargetInstrDesc &TID = MI->getDesc(); + bool isOptDef = (IIOpNum < TID.getNumOperands()) + ? (TID.OpInfo[IIOpNum].isOptionalDef()) : false; MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef)); // Verify that it is right. assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); if (II) { const TargetRegisterClass *RC = - getInstrOperandRegClass(MRI, TII, II, IIOpNum); + getInstrOperandRegClass(MRI, TII, *II, IIOpNum); assert(RC && "Don't have operand info for this instruction!"); const TargetRegisterClass *VRC = RegInfo.getRegClass(VReg); if (VRC != RC) { @@ -507,7 +507,7 @@ assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); if (II) { const TargetRegisterClass *RC = - getInstrOperandRegClass(MRI, TII, II, IIOpNum); + getInstrOperandRegClass(MRI, TII, *II, IIOpNum); assert(RC && "Don't have operand info for this instruction!"); assert(RegInfo.getRegClass(VReg) == RC && "Register class of operand and regclass of use don't agree!"); @@ -669,7 +669,7 @@ return; } - const TargetInstrDescriptor &II = TII->get(Opc); + const TargetInstrDesc &II = TII->get(Opc); unsigned NumResults = CountResults(Node); unsigned NodeOperands = CountOperands(Node); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Jan 7 01:27:27 2008 @@ -148,7 +148,7 @@ if (!SU || !SU->Node) continue; if (SU->isCommutable) { unsigned Opc = SU->Node->getTargetOpcode(); - const TargetInstrDescriptor &TID = TII->get(Opc); + const TargetInstrDesc &TID = TII->get(Opc); unsigned NumRes = TID.getNumDefs(); unsigned NumOps = CountOperands(SU->Node); for (unsigned j = 0; j != NumOps; ++j) { @@ -431,7 +431,7 @@ SUnit *NewSU = NewSUnit(N); SUnitMap[N].push_back(NewSU); - const TargetInstrDescriptor &TID = TII->get(N->getTargetOpcode()); + const TargetInstrDesc &TID = TII->get(N->getTargetOpcode()); for (unsigned i = 0; i != TID.getNumOperands(); ++i) { if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { NewSU->isTwoAddress = true; @@ -622,7 +622,7 @@ /// FIXME: Move to SelectionDAG? static MVT::ValueType getPhysicalRegisterVT(SDNode *N, unsigned Reg, const TargetInstrInfo *TII) { - const TargetInstrDescriptor &TID = TII->get(N->getTargetOpcode()); + const TargetInstrDesc &TID = TII->get(N->getTargetOpcode()); assert(TID.ImplicitDefs && "Physical reg def must be in implicit def list!"); unsigned NumRes = TID.getNumDefs(); for (const unsigned *ImpDef = TID.getImplicitDefs(); *ImpDef; ++ImpDef) { @@ -665,7 +665,7 @@ SDNode *Node = (i == 0) ? SU->Node : SU->FlaggedNodes[i-1]; if (!Node || !Node->isTargetOpcode()) continue; - const TargetInstrDescriptor &TID = TII->get(Node->getTargetOpcode()); + const TargetInstrDesc &TID = TII->get(Node->getTargetOpcode()); if (!TID.ImplicitDefs) continue; for (const unsigned *Reg = TID.ImplicitDefs; *Reg; ++Reg) { @@ -1288,7 +1288,7 @@ bool BURegReductionPriorityQueue::canClobber(SUnit *SU, SUnit *Op) { if (SU->isTwoAddress) { unsigned Opc = SU->Node->getTargetOpcode(); - const TargetInstrDescriptor &TID = TII->get(Opc); + const TargetInstrDesc &TID = TII->get(Opc); unsigned NumRes = TID.getNumDefs(); unsigned NumOps = ScheduleDAG::CountOperands(SU->Node); for (unsigned i = 0; i != NumOps; ++i) { @@ -1364,7 +1364,7 @@ continue; unsigned Opc = Node->getTargetOpcode(); - const TargetInstrDescriptor &TID = TII->get(Opc); + const TargetInstrDesc &TID = TII->get(Opc); unsigned NumRes = TID.getNumDefs(); unsigned NumOps = ScheduleDAG::CountOperands(Node); for (unsigned j = 0; j != NumOps; ++j) { Modified: llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp Mon Jan 7 01:27:27 2008 @@ -35,23 +35,24 @@ bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI, const std::vector &Pred) const { bool MadeChange = false; - const TargetInstrDescriptor *TID = MI->getDesc(); - if (TID->isPredicable()) { - for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) { - if (TID->OpInfo[i].isPredicate()) { - MachineOperand &MO = MI->getOperand(i); - if (MO.isReg()) { - MO.setReg(Pred[j].getReg()); - MadeChange = true; - } else if (MO.isImm()) { - MO.setImm(Pred[j].getImm()); - MadeChange = true; - } else if (MO.isMBB()) { - MO.setMBB(Pred[j].getMBB()); - MadeChange = true; - } - ++j; + const TargetInstrDesc &TID = MI->getDesc(); + if (!TID.isPredicable()) + return false; + + for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) { + if (TID.OpInfo[i].isPredicate()) { + MachineOperand &MO = MI->getOperand(i); + if (MO.isReg()) { + MO.setReg(Pred[j].getReg()); + MadeChange = true; + } else if (MO.isImm()) { + MO.setImm(Pred[j].getImm()); + MadeChange = true; + } else if (MO.isMBB()) { + MO.setMBB(Pred[j].getMBB()); + MadeChange = true; } + ++j; } } return MadeChange; Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Jan 7 01:27:27 2008 @@ -93,11 +93,11 @@ mbbi != mbbe; ++mbbi) { for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); mi != me; ++mi) { - const TargetInstrDescriptor *TID = mi->getDesc(); + const TargetInstrDesc &TID = mi->getDesc(); bool FirstTied = true; - for (unsigned si = 1, e = TID->getNumOperands(); si < e; ++si) { - int ti = TID->getOperandConstraint(si, TOI::TIED_TO); + for (unsigned si = 1, e = TID.getNumOperands(); si < e; ++si) { + int ti = TID.getOperandConstraint(si, TOI::TIED_TO); if (ti == -1) continue; @@ -144,7 +144,7 @@ // so, swap the B and C operands. This makes the live ranges of A // and C joinable. // FIXME: This code also works for A := B op C instructions. - if (TID->isCommutable() && mi->getNumOperands() >= 3) { + if (TID.isCommutable() && mi->getNumOperands() >= 3) { assert(mi->getOperand(3-si).isRegister() && "Not a proper commutative instruction!"); unsigned regC = mi->getOperand(3-si).getReg(); @@ -172,12 +172,12 @@ // If this instruction is potentially convertible to a true // three-address instruction, - if (TID->isConvertibleTo3Addr()) { + if (TID.isConvertibleTo3Addr()) { // FIXME: This assumes there are no more operands which are tied // to another register. #ifndef NDEBUG - for (unsigned i = si+1, e = TID->getNumOperands(); i < e; ++i) - assert(TID->getOperandConstraint(i, TOI::TIED_TO) == -1); + for (unsigned i = si+1, e = TID.getNumOperands(); i < e; ++i) + assert(TID.getOperandConstraint(i, TOI::TIED_TO) == -1); #endif if (MachineInstr *New = TII.convertToThreeAddress(mbbi, mi, LV)) { Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Mon Jan 7 01:27:27 2008 @@ -537,7 +537,7 @@ /// over. static void UpdateKills(MachineInstr &MI, BitVector &RegKills, std::vector &KillOps) { - const TargetInstrDescriptor *TID = MI.getDesc(); + const TargetInstrDesc &TID = MI.getDesc(); for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); if (!MO.isRegister() || !MO.isUse()) @@ -552,8 +552,8 @@ KillOps[Reg]->setIsKill(false); KillOps[Reg] = NULL; RegKills.reset(Reg); - if (i < TID->getNumOperands() && - TID->getOperandConstraint(i, TOI::TIED_TO) == -1) + if (i < TID.getNumOperands() && + TID.getOperandConstraint(i, TOI::TIED_TO) == -1) // Unless it's a two-address operand, this is the new kill. MO.setIsKill(); } @@ -966,7 +966,7 @@ NextMII = next(MII); MachineInstr &MI = *MII; - const TargetInstrDescriptor *TID = MI.getDesc(); + const TargetInstrDesc &TID = MI.getDesc(); // Insert restores here if asked to. if (VRM.isRestorePt(&MI)) { @@ -1082,7 +1082,7 @@ // aren't allowed to modify the reused register. If none of these cases // apply, reuse it. bool CanReuse = true; - int ti = TID->getOperandConstraint(i, TOI::TIED_TO); + int ti = TID.getOperandConstraint(i, TOI::TIED_TO); if (ti != -1 && MI.getOperand(ti).isRegister() && MI.getOperand(ti).getReg() == VirtReg) { @@ -1234,7 +1234,7 @@ Spills.addAvailable(SSorRMId, &MI, PhysReg); // Assumes this is the last use. IsKill will be unset if reg is reused // unless it's a two-address operand. - if (TID->getOperandConstraint(i, TOI::TIED_TO) == -1) + if (TID.getOperandConstraint(i, TOI::TIED_TO) == -1) MI.getOperand(i).setIsKill(); unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg; MI.getOperand(i).setReg(RReg); @@ -1436,7 +1436,7 @@ // If this def is part of a two-address operand, make sure to execute // the store from the correct physical register. unsigned PhysReg; - int TiedOp = MI.getDesc()->findTiedToSrcOperand(i); + int TiedOp = MI.getDesc().findTiedToSrcOperand(i); if (TiedOp != -1) { PhysReg = MI.getOperand(TiedOp).getReg(); if (SubIdx) { Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Jan 7 01:27:27 2008 @@ -55,7 +55,7 @@ void emitInstruction(const MachineInstr &MI); int getMachineOpValue(const MachineInstr &MI, unsigned OpIndex); - unsigned getBaseOpcodeFor(const TargetInstrDescriptor *TID); + unsigned getBaseOpcodeFor(const TargetInstrDesc &TID); unsigned getBinaryCodeForInstr(const MachineInstr &MI); void emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub); @@ -103,8 +103,8 @@ } /// getBaseOpcodeFor - Return the opcode value -unsigned Emitter::getBaseOpcodeFor(const TargetInstrDescriptor *TID) { - return (TID->TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift; +unsigned Emitter::getBaseOpcodeFor(const TargetInstrDesc &TID) { + return (TID.TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift; } /// getShiftOp - Verify which is the shift opcode (bit[6:5]) of the @@ -201,15 +201,15 @@ } unsigned Emitter::getBinaryCodeForInstr(const MachineInstr &MI) { - const TargetInstrDescriptor *Desc = MI.getDesc(); - unsigned opcode = Desc->Opcode; + const TargetInstrDesc &Desc = MI.getDesc(); + unsigned opcode = Desc.Opcode; // initial instruction mask unsigned Value = 0xE0000000; unsigned op; - switch (Desc->TSFlags & ARMII::AddrModeMask) { + switch (Desc.TSFlags & ARMII::AddrModeMask) { case ARMII::AddrModeNone: { - switch(Desc->TSFlags & ARMII::FormMask) { + switch(Desc.TSFlags & ARMII::FormMask) { default: { assert(0 && "Unknown instruction subtype!"); // treat special instruction CLZ @@ -241,7 +241,7 @@ unsigned char BaseOpcode = getBaseOpcodeFor(Desc); Value |= BaseOpcode << 4; - unsigned Format = (Desc->TSFlags & ARMII::FormMask); + unsigned Format = (Desc.TSFlags & ARMII::FormMask); if (Format == ARMII::MulSMUL) Value |= 1 << 22; @@ -342,7 +342,7 @@ // treat 3 special instructions: MOVsra_flag, MOVsrl_flag and // MOVrx. - unsigned Format = (Desc->TSFlags & ARMII::FormMask); + unsigned Format = Desc.TSFlags & ARMII::FormMask; if (Format == ARMII::DPRdMisc) { Value |= getMachineOpValue(MI,0) << ARMII::RegRdShift; Value |= getMachineOpValue(MI,1); @@ -499,7 +499,7 @@ // bit 26 is always 1 Value |= 1 << 26; - unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask); + unsigned Index = Desc.TSFlags & ARMII::IndexModeMask; // if the instruction uses offset addressing or pre-indexed addressing, // set bit P(24) to 1 if (Index == ARMII::IndexModePre || Index == 0) @@ -508,7 +508,7 @@ if (Index == ARMII::IndexModePre) Value |= 1 << 21; - unsigned Format = (Desc->TSFlags & ARMII::FormMask); + unsigned Format = Desc.TSFlags & ARMII::FormMask; // If it is a load instruction (except LDRD), set bit L(20) to 1 if (Format == ARMII::LdFrm) Value |= 1 << ARMII::L_BitShift; @@ -555,14 +555,13 @@ break; } case ARMII::AddrMode3: { - - unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask); + unsigned Index = Desc.TSFlags & ARMII::IndexModeMask; // if the instruction uses offset addressing or pre-indexed addressing, // set bit P(24) to 1 if (Index == ARMII::IndexModePre || Index == 0) Value |= 1 << ARMII::IndexShift; - unsigned Format = (Desc->TSFlags & ARMII::FormMask); + unsigned Format = Desc.TSFlags & ARMII::FormMask; // If it is a load instruction (except LDRD), set bit L(20) to 1 if (Format == ARMII::LdFrm && opcode != ARM::LDRD) Value |= 1 << ARMII::L_BitShift; @@ -607,7 +606,7 @@ // bit 27 is always 1 Value |= 1 << 27; - unsigned Format = (Desc->TSFlags & ARMII::FormMask); + unsigned Format = Desc.TSFlags & ARMII::FormMask; // if it is a load instr, set bit L(20) to 1 if (Format == ARMII::LdFrm) Value |= 1 << ARMII::L_BitShift; Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Jan 7 01:27:27 2008 @@ -371,7 +371,7 @@ MBBSize += ARM::GetInstSize(I); int Opc = I->getOpcode(); - if (I->getDesc()->isBranch()) { + if (I->getDesc().isBranch()) { bool isCond = false; unsigned Bits = 0; unsigned Scale = 1; @@ -423,7 +423,7 @@ // Basic size info comes from the TSFlags field. unsigned Bits = 0; unsigned Scale = 1; - unsigned TSFlags = I->getDesc()->TSFlags; + unsigned TSFlags = I->getDesc().TSFlags; switch (TSFlags & ARMII::AddrModeMask) { default: // Constant pool entries can reach anything. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Mon Jan 7 01:27:27 2008 @@ -63,7 +63,7 @@ return true; case ARM::MOVr: case ARM::tMOVr: - assert(MI.getDesc()->getNumOperands() >= 2 && + assert(MI.getDesc().getNumOperands() >= 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && "Invalid ARM MOV instruction"); @@ -180,7 +180,7 @@ return NULL; MachineInstr *MI = MBBI; - unsigned TSFlags = MI->getDesc()->TSFlags; + unsigned TSFlags = MI->getDesc().TSFlags; bool isPre = false; switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) { default: return NULL; @@ -200,9 +200,9 @@ MachineInstr *UpdateMI = NULL; MachineInstr *MemMI = NULL; unsigned AddrMode = (TSFlags & ARMII::AddrModeMask); - const TargetInstrDescriptor *TID = MI->getDesc(); - unsigned NumOps = TID->getNumOperands(); - bool isLoad = TID->isSimpleLoad(); + const TargetInstrDesc &TID = MI->getDesc(); + unsigned NumOps = TID.getNumOperands(); + bool isLoad = TID.isSimpleLoad(); const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0); const MachineOperand &Base = MI->getOperand(2); const MachineOperand &Offset = MI->getOperand(NumOps-3); @@ -837,8 +837,8 @@ bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI, std::vector &Pred) const { - const TargetInstrDescriptor *TID = MI->getDesc(); - if (!TID->getImplicitDefs() && !TID->hasOptionalDef()) + const TargetInstrDesc &TID = MI->getDesc(); + if (!TID.getImplicitDefs() && !TID.hasOptionalDef()) return false; bool Found = false; @@ -870,8 +870,8 @@ const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo(); // Basic size info comes from the TSFlags field. - const TargetInstrDescriptor *TID = MI->getDesc(); - unsigned TSFlags = TID->TSFlags; + const TargetInstrDesc &TID = MI->getDesc(); + unsigned TSFlags = TID.TSFlags; switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) { default: @@ -897,9 +897,9 @@ case ARM::tBR_JTr: { // These are jumptable branches, i.e. a branch followed by an inlined // jumptable. The size is 4 + 4 * number of entries. - unsigned NumOps = TID->getNumOperands(); + unsigned NumOps = TID.getNumOperands(); MachineOperand JTOP = - MI->getOperand(NumOps - (TID->isPredicable() ? 3 : 2)); + MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2)); unsigned JTI = JTOP.getIndex(); MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); const std::vector &JT = MJTI->getJumpTables(); Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Mon Jan 7 01:27:27 2008 @@ -599,8 +599,8 @@ unsigned Base = MBBI->getOperand(1).getReg(); unsigned PredReg = 0; ARMCC::CondCodes Pred = getInstrPredicate(MBBI, PredReg); - const TargetInstrDescriptor *TID = MBBI->getDesc(); - unsigned OffField = MBBI->getOperand(TID->getNumOperands()-3).getImm(); + unsigned NumOperands = MBBI->getDesc().getNumOperands(); + unsigned OffField = MBBI->getOperand(NumOperands-3).getImm(); int Offset = isAM2 ? ARM_AM::getAM2Offset(OffField) : ARM_AM::getAM5Offset(OffField) * 4; if (isAM2) { Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Mon Jan 7 01:27:27 2008 @@ -581,7 +581,7 @@ } unsigned Opcode = MI.getOpcode(); - const TargetInstrDescriptor &Desc = *MI.getDesc(); + const TargetInstrDesc &Desc = MI.getDesc(); unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); bool isSub = false; @@ -1036,7 +1036,7 @@ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (I->getOperand(i).isFrameIndex()) { unsigned Opcode = I->getOpcode(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); + const TargetInstrDesc &Desc = TII.get(Opcode); unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); if (AddrMode == ARMII::AddrMode3) { Limit = (1 << 8) - 1; Modified: llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp Mon Jan 7 01:27:27 2008 @@ -59,7 +59,7 @@ { bool Changed = false; for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) - if (I->getDesc()->hasDelaySlot()) { + if (I->getDesc().hasDelaySlot()) { MachineBasicBlock::iterator J = I; ++J; BuildMI(MBB, J, TII->get(Mips::NOP)); Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Mon Jan 7 01:27:27 2008 @@ -175,7 +175,7 @@ // If there is only one terminator instruction, process it. unsigned LastOpc = LastInst->getOpcode(); if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { - if (!LastInst->getDesc()->isBranch()) + if (!LastInst->getDesc().isBranch()) return true; // Unconditional branch @@ -259,7 +259,7 @@ } else { // Conditional branch. unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); - const TargetInstrDescriptor &TID = get(Opc); + const TargetInstrDesc &TID = get(Opc); if (TID.getNumOperands() == 3) BuildMI(&MBB, TID).addReg(Cond[1].getReg()) @@ -275,15 +275,13 @@ // Two-way Conditional branch. unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm()); - const TargetInstrDescriptor &TID = get(Opc); + const TargetInstrDesc &TID = get(Opc); if (TID.getNumOperands() == 3) - BuildMI(&MBB, TID).addReg(Cond[1].getReg()) - .addReg(Cond[2].getReg()) + BuildMI(&MBB, TID).addReg(Cond[1].getReg()).addReg(Cond[2].getReg()) .addMBB(TBB); else - BuildMI(&MBB, TID).addReg(Cond[1].getReg()) - .addMBB(TBB); + BuildMI(&MBB, TID).addReg(Cond[1].getReg()).addMBB(TBB); BuildMI(&MBB, get(Mips::J)).addMBB(FBB); return 2; Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Mon Jan 7 01:27:27 2008 @@ -70,7 +70,7 @@ } Opcode -= ISD::BUILTIN_OP_END; - const TargetInstrDescriptor &TID = TII.get(Opcode); + const TargetInstrDesc &TID = TII.get(Opcode); isLoad = TID.isSimpleLoad(); isStore = TID.mayStore(); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Jan 7 01:27:27 2008 @@ -262,13 +262,13 @@ // Find all return blocks, outputting a restore in each epilog. for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { - if (!BB->empty() && BB->back().getDesc()->isReturn()) { + if (!BB->empty() && BB->back().getDesc().isReturn()) { IP = BB->end(); --IP; // Skip over all terminator instructions, which are part of the return // sequence. MachineBasicBlock::iterator I2 = IP; - while (I2 != BB->begin() && (--I2)->getDesc()->isTerminator()) + while (I2 != BB->begin() && (--I2)->getDesc().isTerminator()) IP = I2; // Emit: MTVRSAVE InVRSave Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Mon Jan 7 01:27:27 2008 @@ -540,7 +540,7 @@ // epilog blocks. for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) { // If last instruction is a return instruction, add an epilogue - if (!I->empty() && I->back().getDesc()->isReturn()) { + if (!I->empty() && I->back().getDesc().isReturn()) { bool FoundIt = false; for (MBBI = I->end(); MBBI != I->begin(); ) { --MBBI; Modified: llvm/trunk/lib/Target/Sparc/DelaySlotFiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/DelaySlotFiller.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/DelaySlotFiller.cpp (original) +++ llvm/trunk/lib/Target/Sparc/DelaySlotFiller.cpp Mon Jan 7 01:27:27 2008 @@ -65,7 +65,7 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) - if (I->getDesc()->hasDelaySlot()) { + if (I->getDesc().hasDelaySlot()) { MachineBasicBlock::iterator J = I; ++J; BuildMI(MBB, J, TII->get(SP::NOP)); Modified: llvm/trunk/lib/Target/TargetInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetInstrInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetInstrInfo.cpp Mon Jan 7 01:27:27 2008 @@ -18,7 +18,7 @@ /// findTiedToSrcOperand - Returns the operand that is tied to the specified /// dest operand. Returns -1 if there isn't one. -int TargetInstrDescriptor::findTiedToSrcOperand(unsigned OpNum) const { +int TargetInstrDesc::findTiedToSrcOperand(unsigned OpNum) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { if (i == OpNum) continue; @@ -29,22 +29,22 @@ } -TargetInstrInfo::TargetInstrInfo(const TargetInstrDescriptor* Desc, +TargetInstrInfo::TargetInstrInfo(const TargetInstrDesc* Desc, unsigned numOpcodes) - : desc(Desc), NumOpcodes(numOpcodes) { + : Descriptors(Desc), NumOpcodes(numOpcodes) { } TargetInstrInfo::~TargetInstrInfo() { } bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { - const TargetInstrDescriptor *TID = MI->getDesc(); - if (!TID->isTerminator()) return false; + const TargetInstrDesc &TID = MI->getDesc(); + if (!TID.isTerminator()) return false; // Conditional branch is a special case. - if (TID->isBranch() && !TID->isBarrier()) + if (TID.isBranch() && !TID.isBarrier()) return true; - if (!TID->isPredicable()) + if (!TID.isPredicable()) return true; return !isPredicated(MI); } Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Mon Jan 7 01:27:27 2008 @@ -60,7 +60,7 @@ } void emitInstruction(const MachineInstr &MI, - const TargetInstrDescriptor *Desc); + const TargetInstrDesc *Desc); private: void emitPCRelativeBlockAddress(MachineBasicBlock *MBB); @@ -115,10 +115,10 @@ MCE.StartMachineBasicBlock(MBB); for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); I != E; ++I) { - const TargetInstrDescriptor *Desc = I->getDesc(); - emitInstruction(*I, Desc); + const TargetInstrDesc &Desc = I->getDesc(); + emitInstruction(*I, &Desc); // MOVPC32r is basically a call plus a pop instruction. - if (Desc->Opcode == X86::MOVPC32r) + if (Desc.getOpcode() == X86::MOVPC32r) emitInstruction(*I, &II->get(X86::POP32r)); NumEmitted++; // Keep track of the # of mi's emitted } @@ -394,7 +394,7 @@ } } -static unsigned sizeOfImm(const TargetInstrDescriptor *Desc) { +static unsigned sizeOfImm(const TargetInstrDesc *Desc) { switch (Desc->TSFlags & X86II::ImmMask) { case X86II::Imm8: return 1; case X86II::Imm16: return 2; @@ -436,18 +436,18 @@ /// size, and 3) use of X86-64 extended registers. unsigned Emitter::determineREX(const MachineInstr &MI) { unsigned REX = 0; - const TargetInstrDescriptor *Desc = MI.getDesc(); + const TargetInstrDesc &Desc = MI.getDesc(); // Pseudo instructions do not need REX prefix byte. - if ((Desc->TSFlags & X86II::FormMask) == X86II::Pseudo) + if ((Desc.TSFlags & X86II::FormMask) == X86II::Pseudo) return 0; - if (Desc->TSFlags & X86II::REX_W) + if (Desc.TSFlags & X86II::REX_W) REX |= 1 << 3; - unsigned NumOps = Desc->getNumOperands(); + unsigned NumOps = Desc.getNumOperands(); if (NumOps) { bool isTwoAddr = NumOps > 1 && - Desc->getOperandConstraint(1, TOI::TIED_TO) != -1; + Desc.getOperandConstraint(1, TOI::TIED_TO) != -1; // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix. unsigned i = isTwoAddr ? 1 : 0; @@ -460,7 +460,7 @@ } } - switch (Desc->TSFlags & X86II::FormMask) { + switch (Desc.TSFlags & X86II::FormMask) { case X86II::MRMInitReg: if (isX86_64ExtendedReg(MI.getOperand(0))) REX |= (1 << 0) | (1 << 2); @@ -528,7 +528,7 @@ } void Emitter::emitInstruction(const MachineInstr &MI, - const TargetInstrDescriptor *Desc) { + const TargetInstrDesc *Desc) { unsigned Opcode = Desc->Opcode; // Emit the repeat opcode prefix as needed. Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Mon Jan 7 01:27:27 2008 @@ -205,7 +205,7 @@ for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) { MachineInstr *MI = I; - unsigned Flags = MI->getDesc()->TSFlags; + unsigned Flags = MI->getDesc().TSFlags; if ((Flags & X86II::FPTypeMask) == X86II::NotFP) continue; // Efficiently ignore non-fp insts! @@ -597,7 +597,7 @@ /// void FPS::handleOneArgFP(MachineBasicBlock::iterator &I) { MachineInstr *MI = I; - unsigned NumOps = MI->getDesc()->getNumOperands(); + unsigned NumOps = MI->getDesc().getNumOperands(); assert((NumOps == 5 || NumOps == 1) && "Can only handle fst* & ftst instructions!"); @@ -657,7 +657,7 @@ /// void FPS::handleOneArgFPRW(MachineBasicBlock::iterator &I) { MachineInstr *MI = I; - unsigned NumOps = MI->getDesc()->getNumOperands(); + unsigned NumOps = MI->getDesc().getNumOperands(); assert(NumOps >= 2 && "FPRW instructions must have 2 ops!!"); // Is this the last use of the source register? @@ -766,7 +766,7 @@ ASSERT_SORTED(ForwardSTiTable); ASSERT_SORTED(ReverseSTiTable); MachineInstr *MI = I; - unsigned NumOperands = MI->getDesc()->getNumOperands(); + unsigned NumOperands = MI->getDesc().getNumOperands(); assert(NumOperands == 3 && "Illegal TwoArgFP instruction!"); unsigned Dest = getFPReg(MI->getOperand(0)); unsigned Op0 = getFPReg(MI->getOperand(NumOperands-2)); @@ -864,7 +864,7 @@ ASSERT_SORTED(ForwardSTiTable); ASSERT_SORTED(ReverseSTiTable); MachineInstr *MI = I; - unsigned NumOperands = MI->getDesc()->getNumOperands(); + unsigned NumOperands = MI->getDesc().getNumOperands(); assert(NumOperands == 2 && "Illegal FUCOM* instruction!"); unsigned Op0 = getFPReg(MI->getOperand(NumOperands-2)); unsigned Op1 = getFPReg(MI->getOperand(NumOperands-1)); Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Jan 7 01:27:27 2008 @@ -1243,13 +1243,13 @@ } bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { - const TargetInstrDescriptor *TID = MI->getDesc(); - if (!TID->isTerminator()) return false; + const TargetInstrDesc &TID = MI->getDesc(); + if (!TID.isTerminator()) return false; // Conditional branch is a special case. - if (TID->isBranch() && !TID->isBarrier()) + if (TID.isBranch() && !TID.isBarrier()) return true; - if (!TID->isPredicable()) + if (!TID.isPredicable()) return true; return !isPredicated(MI); } @@ -1276,7 +1276,7 @@ // If there is only one terminator instruction, process it. if (I == MBB.begin() || !isBrAnalysisUnpredicatedTerminator(--I, *this)) { - if (!LastInst->getDesc()->isBranch()) + if (!LastInst->getDesc().isBranch()) return true; // If the block ends with a branch there are 3 possibilities: @@ -1640,7 +1640,7 @@ MIB.addImm(1).addReg(0).addImm(0); // Loop over the rest of the ri operands, converting them over. - unsigned NumOps = MI->getDesc()->getNumOperands()-2; + unsigned NumOps = MI->getDesc().getNumOperands()-2; for (unsigned i = 0; i != NumOps; ++i) { MachineOperand &MO = MI->getOperand(i+2); MIB = X86InstrAddOperand(MIB, MO); @@ -1692,9 +1692,9 @@ SmallVector &MOs) const { const DenseMap *OpcodeTablePtr = NULL; bool isTwoAddrFold = false; - unsigned NumOps = MI->getDesc()->getNumOperands(); + unsigned NumOps = MI->getDesc().getNumOperands(); bool isTwoAddr = NumOps > 1 && - MI->getDesc()->getOperandConstraint(1, TOI::TIED_TO) != -1; + MI->getDesc().getOperandConstraint(1, TOI::TIED_TO) != -1; MachineInstr *NewMI = NULL; // Folding a memory location into the two-address part of a two-address @@ -1798,7 +1798,7 @@ return NULL; SmallVector MOs; - unsigned NumOps = LoadMI->getDesc()->getNumOperands(); + unsigned NumOps = LoadMI->getDesc().getNumOperands(); for (unsigned i = NumOps - 4; i != NumOps; ++i) MOs.push_back(LoadMI->getOperand(i)); return foldMemoryOperand(MI, Ops[0], MOs); @@ -1826,9 +1826,9 @@ unsigned OpNum = Ops[0]; unsigned Opc = MI->getOpcode(); - unsigned NumOps = MI->getDesc()->getNumOperands(); + unsigned NumOps = MI->getDesc().getNumOperands(); bool isTwoAddr = NumOps > 1 && - MI->getDesc()->getOperandConstraint(1, TOI::TIED_TO) != -1; + MI->getDesc().getOperandConstraint(1, TOI::TIED_TO) != -1; // Folding a memory location into the two-address part of a two-address // instruction is different than folding it other places. It requires @@ -1880,7 +1880,7 @@ return false; UnfoldStore &= FoldedStore; - const TargetInstrDescriptor &TID = get(Opc); + const TargetInstrDesc &TID = get(Opc); const TargetOperandInfo &TOI = TID.OpInfo[Index]; const TargetRegisterClass *RC = TOI.isLookupPtrRegClass() ? getPointerRegClass() : RI.getRegClass(TOI.RegClass); @@ -1979,7 +1979,7 @@ unsigned Index = I->second.second & 0xf; bool FoldedLoad = I->second.second & (1 << 4); bool FoldedStore = I->second.second & (1 << 5); - const TargetInstrDescriptor &TID = get(Opc); + const TargetInstrDesc &TID = get(Opc); const TargetOperandInfo &TOI = TID.OpInfo[Index]; const TargetRegisterClass *RC = TOI.isLookupPtrRegClass() ? getPointerRegClass() : RI.getRegClass(TOI.RegClass); Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Mon Jan 7 01:27:27 2008 @@ -364,7 +364,7 @@ // getBaseOpcodeFor - This function returns the "base" X86 opcode for the // specified machine instruction. // - unsigned char getBaseOpcodeFor(const TargetInstrDescriptor *TID) const { + unsigned char getBaseOpcodeFor(const TargetInstrDesc *TID) const { return TID->TSFlags >> X86II::OpcodeShift; } unsigned char getBaseOpcodeFor(unsigned Opcode) const { Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Mon Jan 7 01:27:27 2008 @@ -729,7 +729,7 @@ MachineBasicBlock::iterator PI = prior(MBBI); unsigned Opc = PI->getOpcode(); if (Opc != X86::POP32r && Opc != X86::POP64r && - !PI->getDesc()->isTerminator()) + !PI->getDesc().isTerminator()) break; --MBBI; } Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45695&r1=45694&r2=45695&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Mon Jan 7 01:27:27 2008 @@ -261,9 +261,9 @@ // Emit all of the operand info records. EmitOperandInfo(OS, OperandInfoIDs); - // Emit all of the TargetInstrDescriptor records in their ENUM ordering. + // Emit all of the TargetInstrDesc records in their ENUM ordering. // - OS << "\nstatic const TargetInstrDescriptor " << TargetName + OS << "\nstatic const TargetInstrDesc " << TargetName << "Insts[] = {\n"; std::vector NumberedInstructions; Target.getInstructionsByEnumValue(NumberedInstructions); From sabre at nondot.org Mon Jan 7 01:33:09 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 07:33:09 -0000 Subject: [llvm-commits] [llvm] r45696 - in /llvm/trunk/include/llvm/Target: TargetInstrDesc.h TargetInstrInfo.h Message-ID: <200801070733.m077X9rS004530@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 01:33:08 2008 New Revision: 45696 URL: http://llvm.org/viewvc/llvm-project?rev=45696&view=rev Log: split TargetInstrDesc out into its own header file. Added: llvm/trunk/include/llvm/Target/TargetInstrDesc.h Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h Added: llvm/trunk/include/llvm/Target/TargetInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=45696&view=auto ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (added) +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Mon Jan 7 01:33:08 2008 @@ -0,0 +1,414 @@ +//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the TargetOperandInfo and TargetInstrDesc classes, which +// are used to describe target instructions and their operands. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETINSTRDESC_H +#define LLVM_TARGET_TARGETINSTRDESC_H + +#include + +namespace llvm { + +//===----------------------------------------------------------------------===// +// Machine Operand Flags and Description +//===----------------------------------------------------------------------===// + +namespace TOI { + // Operand constraints: only "tied_to" for now. + enum OperandConstraint { + TIED_TO = 0 // Must be allocated the same register as. + }; + + /// OperandFlags - These are flags set on operands, but should be considered + /// private, all access should go through the TargetOperandInfo accessors. + /// See the accessors for a description of what these are. + enum OperandFlags { + LookupPtrRegClass = 0, + Predicate, + OptionalDef + }; +} + +/// TargetOperandInfo - This holds information about one operand of a machine +/// instruction, indicating the register class for register operands, etc. +/// +class TargetOperandInfo { +public: + /// RegClass - This specifies the register class enumeration of the operand + /// if the operand is a register. If not, this contains 0. + unsigned short RegClass; + unsigned short Flags; + /// Lower 16 bits are used to specify which constraints are set. The higher 16 + /// bits are used to specify the value of constraints (4 bits each). + unsigned int Constraints; + /// Currently no other information. + + /// isLookupPtrRegClass - Set if this operand is a pointer value and it + /// requires a callback to look up its register class. + bool isLookupPtrRegClass() const { return Flags&(1 <> Pos) & 0xf; + } + return -1; + } + + /// findTiedToSrcOperand - Returns the operand that is tied to the specified + /// dest operand. Returns -1 if there isn't one. + int findTiedToSrcOperand(unsigned OpNum) const; + + /// getOpcode - Return the opcode number for this descriptor. + unsigned getOpcode() const { + return Opcode; + } + + /// getName - Return the name of the record in the .td file for this + /// instruction, for example "ADD8ri". + const char *getName() const { + return Name; + } + + /// getNumOperands - Return the number of declared MachineOperands for this + /// MachineInstruction. Note that variadic (isVariadic() returns true) + /// instructions may have additional operands at the end of the list, and note + /// that the machine instruction may include implicit register def/uses as + /// well. + unsigned getNumOperands() const { + return NumOperands; + } + + /// getNumDefs - Return the number of MachineOperands that are register + /// definitions. Register definitions always occur at the start of the + /// machine operand list. This is the number of "outs" in the .td file. + unsigned getNumDefs() const { + return NumDefs; + } + + /// isVariadic - Return true if this instruction can have a variable number of + /// operands. In this case, the variable operands will be after the normal + /// operands but before the implicit definitions and uses (if any are + /// present). + bool isVariadic() const { + return Flags & (1 << TID::Variadic); + } + + /// hasOptionalDef - Set if this instruction has an optional definition, e.g. + /// ARM instructions which can set condition code if 's' bit is set. + bool hasOptionalDef() const { + return Flags & (1 << TID::HasOptionalDef); + } + + /// getImplicitUses - Return a list of machine operands that are potentially + /// read by any instance of this machine instruction. For example, on X86, + /// the "adc" instruction adds two register operands and adds the carry bit in + /// from the flags register. In this case, the instruction is marked as + /// implicitly reading the flags. Likewise, the variable shift instruction on + /// X86 is marked as implicitly reading the 'CL' register, which it always + /// does. + /// + /// This method returns null if the instruction has no implicit uses. + const unsigned *getImplicitUses() const { + return ImplicitUses; + } + + /// getImplicitDefs - Return a list of machine operands that are potentially + /// written by any instance of this machine instruction. For example, on X86, + /// many instructions implicitly set the flags register. In this case, they + /// are marked as setting the FLAGS. Likewise, many instructions always + /// deposit their result in a physical register. For example, the X86 divide + /// instruction always deposits the quotient and remainder in the EAX/EDX + /// registers. For that instruction, this will return a list containing the + /// EAX/EDX/EFLAGS registers. + /// + /// This method returns null if the instruction has no implicit uses. + const unsigned *getImplicitDefs() const { + return ImplicitDefs; + } + + /// getSchedClass - Return the scheduling class for this instruction. The + /// scheduling class is an index into the InstrItineraryData table. This + /// returns zero if there is no known scheduling information for the + /// instruction. + /// + unsigned getSchedClass() const { + return SchedClass; + } + + bool isReturn() const { + return Flags & (1 << TID::Return); + } + + bool isCall() const { + return Flags & (1 << TID::Call); + } + + /// isImplicitDef - Return true if this is an "IMPLICIT_DEF" instruction, + /// which defines a register to an unspecified value. These basically + /// correspond to x = undef. + bool isImplicitDef() const { + return Flags & (1 << TID::ImplicitDef); + } + + /// 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() const { + return Flags & (1 << TID::Barrier); + } + + /// isTerminator - Returns true if this instruction part of the terminator for + /// a basic block. Typically this is things like return and branch + /// instructions. + /// + /// Various passes use this to insert code into the bottom of a basic block, + /// but before control flow occurs. + bool isTerminator() const { + return Flags & (1 << TID::Terminator); + } + + /// isBranch - Returns true if this is a conditional, unconditional, or + /// indirect branch. Predicates below can be used to discriminate between + /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to + /// get more information. + bool isBranch() const { + return Flags & (1 << TID::Branch); + } + + /// isIndirectBranch - Return true if this is an indirect branch, such as a + /// branch through a register. + bool isIndirectBranch() const { + return Flags & (1 << TID::IndirectBranch); + } + + /// isConditionalBranch - Return true if this is a branch which may fall + /// through to the next instruction or may transfer control flow to some other + /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more + /// information about this branch. + bool isConditionalBranch() const { + return isBranch() & !isBarrier() & !isIndirectBranch(); + } + + /// isUnconditionalBranch - Return true if this is a branch which always + /// transfers control flow to some other block. The + /// TargetInstrInfo::AnalyzeBranch method can be used to get more information + /// about this branch. + bool isUnconditionalBranch() const { + return isBranch() & isBarrier() & !isIndirectBranch(); + } + + // isPredicable - Return true if this instruction has a predicate operand that + // controls execution. It may be set to 'always', or may be set to other + /// values. There are various methods in TargetInstrInfo that can be used to + /// control and modify the predicate in this instruction. + bool isPredicable() const { + return Flags & (1 << TID::Predicable); + } + + /// isNotDuplicable - Return true if this instruction cannot be safely + /// duplicated. For example, if the instruction has a unique labels attached + /// to it, duplicating it would cause multiple definition errors. + bool isNotDuplicable() const { + return Flags & (1 << TID::NotDuplicable); + } + + /// hasDelaySlot - Returns true if the specified instruction has a delay slot + /// which must be filled by the code generator. + bool hasDelaySlot() const { + return Flags & (1 << TID::DelaySlot); + } + + /// isSimpleLoad - Return true for instructions that are simple loads from + /// memory. This should only be set on instructions that load a value from + /// memory and return it in their only virtual register definition. + /// Instructions that return a value loaded from memory and then modified in + /// some way should not return true for this. + bool isSimpleLoad() const { + return Flags & (1 << TID::SimpleLoad); + } + + //===--------------------------------------------------------------------===// + // Side Effect Analysis + //===--------------------------------------------------------------------===// + + /// mayStore - Return true if this instruction could possibly modify memory. + /// Instructions with this flag set are not necessarily simple store + /// instructions, they may store a modified value based on their operands, or + /// may not actually modify anything, for example. + bool mayStore() const { + return Flags & (1 << TID::MayStore); + } + + // TODO: mayLoad. + + /// hasNoSideEffects - Return true if all instances of this instruction are + /// guaranteed to have no side effects other than: + /// 1. The register operands that are def/used by the MachineInstr. + /// 2. Registers that are implicitly def/used by the MachineInstr. + /// 3. Memory Accesses captured by mayLoad() or mayStore(). + /// + /// Examples of other side effects would be calling a function, modifying + /// 'invisible' machine state like a control register, etc. + /// + /// If some instances of this instruction are side-effect free but others are + /// not, the hasConditionalSideEffects() property should return true, not this + /// one. + /// + /// Note that you should not call this method directly, instead, call the + /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis + /// of the machine instruction. + bool hasNoSideEffects() const { + return Flags & (1 << TID::NeverHasSideEffects); + } + + /// hasConditionalSideEffects - Return true if some instances of this + /// instruction are guaranteed to have no side effects other than those listed + /// for hasNoSideEffects(). To determine whether a specific machineinstr has + /// side effects, the TargetInstrInfo::isReallySideEffectFree virtual method + /// is invoked to decide. + /// + /// Note that you should not call this method directly, instead, call the + /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis + /// of the machine instruction. + bool hasConditionalSideEffects() const { + return Flags & (1 << TID::MayHaveSideEffects); + } + + //===--------------------------------------------------------------------===// + // Flags that indicate whether an instruction can be modified by a method. + //===--------------------------------------------------------------------===// + + /// isCommutable - Return true if this may be a 2- or 3-address + /// instruction (of the form "X = op Y, Z, ..."), which produces the same + /// result if Y and Z are exchanged. If this flag is set, then the + /// TargetInstrInfo::commuteInstruction method may be used to hack on the + /// instruction. + /// + /// Note that this flag may be set on instructions that are only commutable + /// sometimes. In these cases, the call to commuteInstruction will fail. + /// Also note that some instructions require non-trivial modification to + /// commute them. + bool isCommutable() const { + return Flags & (1 << TID::Commutable); + } + + /// isConvertibleTo3Addr - Return true if this is a 2-address instruction + /// which can be changed into a 3-address instruction if needed. Doing this + /// transformation can be profitable in the register allocator, because it + /// means that the instruction can use a 2-address form if possible, but + /// degrade into a less efficient form if the source and dest register cannot + /// be assigned to the same register. For example, this allows the x86 + /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which + /// is the same speed as the shift but has bigger code size. + /// + /// If this returns true, then the target must implement the + /// TargetInstrInfo::convertToThreeAddress method for this instruction, which + /// is allowed to fail if the transformation isn't valid for this specific + /// instruction (e.g. shl reg, 4 on x86). + /// + bool isConvertibleTo3Addr() const { + return Flags & (1 << TID::ConvertibleTo3Addr); + } + + /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires + /// custom insertion support when the DAG scheduler is inserting it into a + /// machine basic block. If this is true for the instruction, it basically + /// means that it is a pseudo instruction used at SelectionDAG time that is + /// expanded out into magic code by the target when MachineInstrs are formed. + /// + /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method + /// is used to insert this into the MachineBasicBlock. + bool usesCustomDAGSchedInsertionHook() const { + return Flags & (1 << TID::UsesCustomDAGSchedInserter); + } + + /// isRematerializable - Returns true if this instruction is a candidate for + /// remat. This flag is deprecated, please don't use it anymore. If this + /// flag is set, the isReallyTriviallyReMaterializable() method is called to + /// verify the instruction is really rematable. + bool isRematerializable() const { + return Flags & (1 << TID::Rematerializable); + } +}; + +} // end namespace llvm + +#endif Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45696&r1=45695&r2=45696&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Mon Jan 7 01:33:08 2008 @@ -14,11 +14,8 @@ #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H -#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Target/TargetInstrDesc.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Support/DataTypes.h" -#include -#include namespace llvm { @@ -30,396 +27,6 @@ template class SmallVectorImpl; -//===----------------------------------------------------------------------===// -// Machine Operand Flags and Description -//===----------------------------------------------------------------------===// - -namespace TOI { - // Operand constraints: only "tied_to" for now. - enum OperandConstraint { - TIED_TO = 0 // Must be allocated the same register as. - }; - - /// OperandFlags - These are flags set on operands, but should be considered - /// private, all access should go through the TargetOperandInfo accessors. - /// See the accessors for a description of what these are. - enum OperandFlags { - LookupPtrRegClass = 0, - Predicate, - OptionalDef - }; -} - -/// TargetOperandInfo - This holds information about one operand of a machine -/// instruction, indicating the register class for register operands, etc. -/// -class TargetOperandInfo { -public: - /// RegClass - This specifies the register class enumeration of the operand - /// if the operand is a register. If not, this contains 0. - unsigned short RegClass; - unsigned short Flags; - /// Lower 16 bits are used to specify which constraints are set. The higher 16 - /// bits are used to specify the value of constraints (4 bits each). - unsigned int Constraints; - /// Currently no other information. - - /// isLookupPtrRegClass - Set if this operand is a pointer value and it - /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags&(1 <> Pos) & 0xf; - } - return -1; - } - - /// findTiedToSrcOperand - Returns the operand that is tied to the specified - /// dest operand. Returns -1 if there isn't one. - int findTiedToSrcOperand(unsigned OpNum) const; - - /// getOpcode - Return the opcode number for this descriptor. - unsigned getOpcode() const { - return Opcode; - } - - /// getName - Return the name of the record in the .td file for this - /// instruction, for example "ADD8ri". - const char *getName() const { - return Name; - } - - /// getNumOperands - Return the number of declared MachineOperands for this - /// MachineInstruction. Note that variadic (isVariadic() returns true) - /// instructions may have additional operands at the end of the list, and note - /// that the machine instruction may include implicit register def/uses as - /// well. - unsigned getNumOperands() const { - return NumOperands; - } - - /// getNumDefs - Return the number of MachineOperands that are register - /// definitions. Register definitions always occur at the start of the - /// machine operand list. This is the number of "outs" in the .td file. - unsigned getNumDefs() const { - return NumDefs; - } - - /// isVariadic - Return true if this instruction can have a variable number of - /// operands. In this case, the variable operands will be after the normal - /// operands but before the implicit definitions and uses (if any are - /// present). - bool isVariadic() const { - return Flags & (1 << TID::Variadic); - } - - /// hasOptionalDef - Set if this instruction has an optional definition, e.g. - /// ARM instructions which can set condition code if 's' bit is set. - bool hasOptionalDef() const { - return Flags & (1 << TID::HasOptionalDef); - } - - /// getImplicitUses - Return a list of machine operands that are potentially - /// read by any instance of this machine instruction. For example, on X86, - /// the "adc" instruction adds two register operands and adds the carry bit in - /// from the flags register. In this case, the instruction is marked as - /// implicitly reading the flags. Likewise, the variable shift instruction on - /// X86 is marked as implicitly reading the 'CL' register, which it always - /// does. - /// - /// This method returns null if the instruction has no implicit uses. - const unsigned *getImplicitUses() const { - return ImplicitUses; - } - - /// getImplicitDefs - Return a list of machine operands that are potentially - /// written by any instance of this machine instruction. For example, on X86, - /// many instructions implicitly set the flags register. In this case, they - /// are marked as setting the FLAGS. Likewise, many instructions always - /// deposit their result in a physical register. For example, the X86 divide - /// instruction always deposits the quotient and remainder in the EAX/EDX - /// registers. For that instruction, this will return a list containing the - /// EAX/EDX/EFLAGS registers. - /// - /// This method returns null if the instruction has no implicit uses. - const unsigned *getImplicitDefs() const { - return ImplicitDefs; - } - - /// getSchedClass - Return the scheduling class for this instruction. The - /// scheduling class is an index into the InstrItineraryData table. This - /// returns zero if there is no known scheduling information for the - /// instruction. - /// - unsigned getSchedClass() const { - return SchedClass; - } - - bool isReturn() const { - return Flags & (1 << TID::Return); - } - - bool isCall() const { - return Flags & (1 << TID::Call); - } - - /// isImplicitDef - Return true if this is an "IMPLICIT_DEF" instruction, - /// which defines a register to an unspecified value. These basically - /// correspond to x = undef. - bool isImplicitDef() const { - return Flags & (1 << TID::ImplicitDef); - } - - /// 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() const { - return Flags & (1 << TID::Barrier); - } - - /// isTerminator - Returns true if this instruction part of the terminator for - /// a basic block. Typically this is things like return and branch - /// instructions. - /// - /// Various passes use this to insert code into the bottom of a basic block, - /// but before control flow occurs. - bool isTerminator() const { - return Flags & (1 << TID::Terminator); - } - - /// isBranch - Returns true if this is a conditional, unconditional, or - /// indirect branch. Predicates below can be used to discriminate between - /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to - /// get more information. - bool isBranch() const { - return Flags & (1 << TID::Branch); - } - - /// isIndirectBranch - Return true if this is an indirect branch, such as a - /// branch through a register. - bool isIndirectBranch() const { - return Flags & (1 << TID::IndirectBranch); - } - - /// isConditionalBranch - Return true if this is a branch which may fall - /// through to the next instruction or may transfer control flow to some other - /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more - /// information about this branch. - bool isConditionalBranch() const { - return isBranch() & !isBarrier() & !isIndirectBranch(); - } - - /// isUnconditionalBranch - Return true if this is a branch which always - /// transfers control flow to some other block. The - /// TargetInstrInfo::AnalyzeBranch method can be used to get more information - /// about this branch. - bool isUnconditionalBranch() const { - return isBranch() & isBarrier() & !isIndirectBranch(); - } - - // isPredicable - Return true if this instruction has a predicate operand that - // controls execution. It may be set to 'always', or may be set to other - /// values. There are various methods in TargetInstrInfo that can be used to - /// control and modify the predicate in this instruction. - bool isPredicable() const { - return Flags & (1 << TID::Predicable); - } - - /// isNotDuplicable - Return true if this instruction cannot be safely - /// duplicated. For example, if the instruction has a unique labels attached - /// to it, duplicating it would cause multiple definition errors. - bool isNotDuplicable() const { - return Flags & (1 << TID::NotDuplicable); - } - - /// hasDelaySlot - Returns true if the specified instruction has a delay slot - /// which must be filled by the code generator. - bool hasDelaySlot() const { - return Flags & (1 << TID::DelaySlot); - } - - /// isSimpleLoad - Return true for instructions that are simple loads from - /// memory. This should only be set on instructions that load a value from - /// memory and return it in their only virtual register definition. - /// Instructions that return a value loaded from memory and then modified in - /// some way should not return true for this. - bool isSimpleLoad() const { - return Flags & (1 << TID::SimpleLoad); - } - - //===--------------------------------------------------------------------===// - // Side Effect Analysis - //===--------------------------------------------------------------------===// - - /// mayStore - Return true if this instruction could possibly modify memory. - /// Instructions with this flag set are not necessarily simple store - /// instructions, they may store a modified value based on their operands, or - /// may not actually modify anything, for example. - bool mayStore() const { - return Flags & (1 << TID::MayStore); - } - - // TODO: mayLoad. - - /// hasNoSideEffects - Return true if all instances of this instruction are - /// guaranteed to have no side effects other than: - /// 1. The register operands that are def/used by the MachineInstr. - /// 2. Registers that are implicitly def/used by the MachineInstr. - /// 3. Memory Accesses captured by mayLoad() or mayStore(). - /// - /// Examples of other side effects would be calling a function, modifying - /// 'invisible' machine state like a control register, etc. - /// - /// If some instances of this instruction are side-effect free but others are - /// not, the hasConditionalSideEffects() property should return true, not this - /// one. - /// - /// Note that you should not call this method directly, instead, call the - /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis - /// of the machine instruction. - bool hasNoSideEffects() const { - return Flags & (1 << TID::NeverHasSideEffects); - } - - /// hasConditionalSideEffects - Return true if some instances of this - /// instruction are guaranteed to have no side effects other than those listed - /// for hasNoSideEffects(). To determine whether a specific machineinstr has - /// side effects, the TargetInstrInfo::isReallySideEffectFree virtual method - /// is invoked to decide. - /// - /// Note that you should not call this method directly, instead, call the - /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis - /// of the machine instruction. - bool hasConditionalSideEffects() const { - return Flags & (1 << TID::MayHaveSideEffects); - } - - //===--------------------------------------------------------------------===// - // Flags that indicate whether an instruction can be modified by a method. - //===--------------------------------------------------------------------===// - - /// isCommutable - Return true if this may be a 2- or 3-address - /// instruction (of the form "X = op Y, Z, ..."), which produces the same - /// result if Y and Z are exchanged. If this flag is set, then the - /// TargetInstrInfo::commuteInstruction method may be used to hack on the - /// instruction. - /// - /// Note that this flag may be set on instructions that are only commutable - /// sometimes. In these cases, the call to commuteInstruction will fail. - /// Also note that some instructions require non-trivial modification to - /// commute them. - bool isCommutable() const { - return Flags & (1 << TID::Commutable); - } - - /// isConvertibleTo3Addr - Return true if this is a 2-address instruction - /// which can be changed into a 3-address instruction if needed. Doing this - /// transformation can be profitable in the register allocator, because it - /// means that the instruction can use a 2-address form if possible, but - /// degrade into a less efficient form if the source and dest register cannot - /// be assigned to the same register. For example, this allows the x86 - /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which - /// is the same speed as the shift but has bigger code size. - /// - /// If this returns true, then the target must implement the - /// TargetInstrInfo::convertToThreeAddress method for this instruction, which - /// is allowed to fail if the transformation isn't valid for this specific - /// instruction (e.g. shl reg, 4 on x86). - /// - bool isConvertibleTo3Addr() const { - return Flags & (1 << TID::ConvertibleTo3Addr); - } - - /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires - /// custom insertion support when the DAG scheduler is inserting it into a - /// machine basic block. If this is true for the instruction, it basically - /// means that it is a pseudo instruction used at SelectionDAG time that is - /// expanded out into magic code by the target when MachineInstrs are formed. - /// - /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method - /// is used to insert this into the MachineBasicBlock. - bool usesCustomDAGSchedInsertionHook() const { - return Flags & (1 << TID::UsesCustomDAGSchedInserter); - } - - /// isRematerializable - Returns true if this instruction is a candidate for - /// remat. This flag is deprecated, please don't use it anymore. If this - /// flag is set, the isReallyTriviallyReMaterializable() method is called to - /// verify the instruction is really rematable. - bool isRematerializable() const { - return Flags & (1 << TID::Rematerializable); - } -}; - //--------------------------------------------------------------------------- /// From sabre at nondot.org Mon Jan 7 01:42:25 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 07:42:25 -0000 Subject: [llvm-commits] [llvm] r45697 - in /llvm/trunk/lib/CodeGen: MachineBasicBlock.cpp MachineInstr.cpp MachineModuleInfo.cpp Message-ID: <200801070742.m077gPhh004898@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 01:42:25 2008 New Revision: 45697 URL: http://llvm.org/viewvc/llvm-project?rev=45697&view=rev Log: remove #includage Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=45697&r1=45696&r2=45697&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Mon Jan 7 01:42:25 2008 @@ -16,7 +16,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetInstrDesc.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/LeakDetector.h" #include Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=45697&r1=45696&r2=45697&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Mon Jan 7 01:42:25 2008 @@ -16,7 +16,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetInstrDesc.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/Streams.h" Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=45697&r1=45696&r2=45697&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Mon Jan 7 01:42:25 2008 @@ -1875,9 +1875,6 @@ // Get machine module info. MachineModuleInfo *MMI = getAnalysisToUpdate(); if (!MMI) return false; - // Get target instruction info. - const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); - if (!TII) return false; // Track if change is made. bool MadeChange = false; From sabre at nondot.org Mon Jan 7 01:46:23 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 07:46:23 -0000 Subject: [llvm-commits] [llvm] r45698 - /llvm/trunk/lib/Target/README.txt Message-ID: <200801070746.m077kNlV005058@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 01:46:23 2008 New Revision: 45698 URL: http://llvm.org/viewvc/llvm-project?rev=45698&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=45698&r1=45697&r2=45698&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Mon Jan 7 01:46:23 2008 @@ -2,6 +2,13 @@ //===---------------------------------------------------------------------===// +We should make the various target's "IMPLICIT_DEF" instructions be a single +target-independent opcode like TargetInstrInfo::INLINEASM. This would allow +us to eliminate the TargetInstrDesc::isImplicitDef() method, and would allow +us to avoid having to define this for every target for every register class. + +//===---------------------------------------------------------------------===// + With the recent changes to make the implicit def/use set explicit in machineinstrs, we should change the target descriptions for 'call' instructions so that the .td files don't list all the call-clobbered registers as implicit From isanbard at gmail.com Mon Jan 7 02:04:29 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 7 Jan 2008 00:04:29 -0800 Subject: [llvm-commits] [llvm] r45626 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp In-Reply-To: <0D0AED77-736C-422C-AB56-69007988EBF1@apple.com> References: <200801050918.m059I5GB021020@zion.cs.uiuc.edu> <6BBC27A8-F4C2-48C7-B24A-4A617B2DEFD8@apple.com> <7068D27E-5A5C-4F3E-B24E-C798657727A4@gmail.com> <2F488CC7-9FBA-4E00-ACA4-6FA6DFF373A6@apple.com> <0D0AED77-736C-422C-AB56-69007988EBF1@apple.com> Message-ID: <888B5131-AA7F-4956-838D-90FC6ABA74B2@gmail.com> On Jan 6, 2008, at 10:20 PM, Chris Lattner wrote: > On Jan 6, 2008, at 6:45 PM, Evan Cheng wrote: > >> By the way. This check is still not quite right. >> >> // Loads from stubs of global addresses are side effect free. >> if (Reg != 0 && MRegisterInfo::isVirtualRegister(Reg) && >> >> In dynamic-no-pic mode, Reg can be 0. So it should be Reg == 0 || ... > > Why is this code even looking at that operand? > Um...because it was given to me in the feedback for my patch. :-) Actually on thinking about it now, it shouldn't matter. I'll remove it. -bw From isanbard at gmail.com Mon Jan 7 02:05:30 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 07 Jan 2008 08:05:30 -0000 Subject: [llvm-commits] [llvm] r45699 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200801070805.m0785UjO006042@zion.cs.uiuc.edu> Author: void Date: Mon Jan 7 02:05:29 2008 New Revision: 45699 URL: http://llvm.org/viewvc/llvm-project?rev=45699&view=rev Log: Operand 1 should be a register. We don't care if it's a preg, vreg, or 0. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45699&r1=45698&r2=45699&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Jan 7 02:05:29 2008 @@ -771,19 +771,15 @@ switch (MI->getOpcode()) { default: break; case X86::MOV32rm: - if (MI->getOperand(1).isRegister()) { - unsigned Reg = MI->getOperand(1).getReg(); - const X86Subtarget &ST = TM.getSubtarget(); - - // Loads from stubs of global addresses are side effect free. - if (Reg != 0 && MRegisterInfo::isVirtualRegister(Reg) && - MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && - MI->getOperand(4).isGlobal() && - ST.GVRequiresExtraLoad(MI->getOperand(4).getGlobal(), TM, false) && - MI->getOperand(2).getImm() == 1 && - MI->getOperand(3).getReg() == 0) - return true; - } + // Loads from stubs of global addresses are side effect free. + if (MI->getOperand(1).isReg() && + MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && + MI->getOperand(4).isGlobal() && + TM.getSubtarget().GVRequiresExtraLoad + (MI->getOperand(4).getGlobal(), TM, false) && + MI->getOperand(2).getImm() == 1 && + MI->getOperand(3).getReg() == 0) + return true; // FALLTHROUGH case X86::MOV8rm: case X86::MOV16rm: From gordonhenriksen at mac.com Mon Jan 7 07:21:35 2008 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 7 Jan 2008 08:21:35 -0500 Subject: [llvm-commits] [llvm] r45676 - in /llvm/trunk: include/llvm/CallingConv.h include/llvm/CodeGen/LinkAllCodegenComponents.h lib/CodeGen/OcamlCollector.cpp test/CodeGen/Generic/GC/frame_size.ll test/CodeGen/Generic/GC/simple_ocaml.ll In-Reply-To: <200801070231.m072VClj021199@zion.cs.uiuc.edu> References: <200801070231.m072VClj021199@zion.cs.uiuc.edu> Message-ID: <12B6E4A5-0022-46B9-8A59-224EFD4A4CC5@mac.com> On 2008-01-06, at 21:31, Gordon Henriksen wrote: > Author: gordon > Date: Sun Jan 6 20:31:11 2008 > New Revision: 45676 > > URL: http://llvm.org/viewvc/llvm-project?rev=45676&view=rev > Log: > Setting GlobalDirective in TargetAsmInfo by default rather than > providing a misleading facility. It's used once in the MIPS backend > and hardcoded as "\t.globl\t" everywhere else. > > Added: > llvm/trunk/lib/CodeGen/OcamlCollector.cpp > llvm/trunk/test/CodeGen/Generic/GC/frame_size.ll > llvm/trunk/test/CodeGen/Generic/GC/simple_ocaml.ll > Modified: > llvm/trunk/include/llvm/CallingConv.h > llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Oops. Here's the correct message for this commit: The new OcamlCollector emits the Ocaml frametable data structure and related symbols. Example output: $ llvm-as -o simple_ocaml.bc simple_ocaml.ll $ llc -gc=ocaml -asm-verbose -o - simple_ocaml.bc .text _camlSimple_ocaml__code_begin: .data _camlSimple_ocaml__data_begin: .text .align 4,0x90 .globl _fun _fun: subl $12, %esp movl $0, 4(%esp) movl $0, 8(%esp) movl 16(%esp), %eax movl %eax, 4(%esp) LBB1_1: # bb.loop movl 4(%esp), %eax movl 4(%eax), %eax testl %eax, %eax je LBB1_1 # bb.loop LBB1_2: # bb.end movl $8, (%esp) call L_malloc$stub Llabel1: movl %eax, 8(%esp) movl 4(%esp), %ecx movl %ecx, 4(%ecx) addl $12, %esp ret .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code +pure_instructions,5 L_malloc$stub: .indirect_symbol _malloc hlt ; hlt ; hlt ; hlt ; hlt .subsections_via_symbols .text _camlSimple_ocaml__code_end: .data _camlSimple_ocaml__data_end: .long 0 _camlSimple_ocaml__frametable: # live roots for fun .long Llabel1 # call return address .short 0xc # stack frame size .short 0x2 # live root count .word 4 # stack offset .word 8 # stack offset .align 2 ? Gordon > Modified: llvm/trunk/include/llvm/CallingConv.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CallingConv.h?rev=45676&r1=45675&r2=45676&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CallingConv.h (original) > +++ llvm/trunk/include/llvm/CallingConv.h Sun Jan 6 20:31:11 2008 > @@ -57,7 +57,12 @@ > /// X86_FastCall - 'fast' analog of X86_StdCall. Passes first > two arguments > /// in ECX:EDX registers, others - via stack. Callee is > responsible for > /// stack cleaning. > - X86_FastCall = 65 > + X86_FastCall = 65, > + > + /// X86_Ocaml - This is a weird ABI used by Objective Caml. > Formally, it > + /// supports only one to six integer/address arguments, all in- > reg. It also > + /// supports tail call emission. > + X86_Ocaml = 66 > }; > } // End CallingConv namespace > > > Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h?rev=45676&r1=45675&r2=45676&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h > (original) > +++ llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Sun > Jan 6 20:31:11 2008 > @@ -36,6 +36,7 @@ > > (void) llvm::createSimpleRegisterCoalescer(); > > + (void) llvm::createOcamlCollector(); > (void) llvm::createShadowStackCollector(); > > (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL); > > Added: llvm/trunk/lib/CodeGen/OcamlCollector.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/OcamlCollector.cpp?rev=45676&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/OcamlCollector.cpp (added) > +++ llvm/trunk/lib/CodeGen/OcamlCollector.cpp Sun Jan 6 20:31:11 2008 > @@ -0,0 +1,177 @@ > +//===-- OcamlCollector.cpp - Ocaml frametable emitter > ---------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open > Source > +// License. See LICENSE.TXT for details. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// This file implements lowering for the llvm.gc* intrinsics > compatible with > +// Objective Caml 3.10.0, which uses a liveness-accurate static > stack map. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > + > +#include "llvm/CodeGen/Collectors.h" > +#include "llvm/ADT/DenseMap.h" > +#include "llvm/CodeGen/AsmPrinter.h" > +#include "llvm/CodeGen/Collector.h" > +#include "llvm/CodeGen/CollectorMetadata.h" > +#include "llvm/Function.h" > +#include "llvm/Module.h" > +#include "llvm/PassManager.h" > +#include "llvm/Support/Compiler.h" > +#include "llvm/Target/TargetAsmInfo.h" > +#include "llvm/Target/TargetData.h" > +#include "llvm/Target/TargetMachine.h" > +#include > + > +using namespace llvm; > + > +namespace { > + > + class VISIBILITY_HIDDEN OcamlCollector : public Collector { > + public: > + OcamlCollector(); > + > + void beginAssembly(std::ostream &OS, AsmPrinter &AP, > + const TargetAsmInfo &TAI); > + > + void finishAssembly(std::ostream &OS, AsmPrinter &AP, > + const TargetAsmInfo &TAI); > + }; > + > + CollectorRegistry::Add > + X("ocaml", "ocaml 3.10-compatible collector"); > + > +} > + > +// > ----------------------------------------------------------------------------- > + > +static void EmitCamlGlobal(const Module &M, std::ostream &OS, > AsmPrinter &AP, > + const TargetAsmInfo &TAI, const char > *Id) { > + const std::string &MId = M.getModuleIdentifier(); > + > + std::string Mangled; > + Mangled += TAI.getGlobalPrefix(); > + Mangled += "caml"; > + size_t Letter = Mangled.size(); > + Mangled.append(MId.begin(), std::find(MId.begin(), MId.end(), > '.')); > + Mangled += "__"; > + Mangled += Id; > + > + // Capitalize the first letter of the module name. > + Mangled[Letter] = toupper(Mangled[Letter]); > + > + if (const char *GlobalDirective = TAI.getGlobalDirective()) > + OS << GlobalDirective << Mangled << "\n"; > + OS << Mangled << ":\n"; > +} > + > +Collector *llvm::createOcamlCollector() { > + return new OcamlCollector(); > +} > + > +OcamlCollector::OcamlCollector() { > + NeededSafePoints = 1 << GC::PostCall; > +} > + > +void OcamlCollector::beginAssembly(std::ostream &OS, AsmPrinter &AP, > + const TargetAsmInfo &TAI) { > + AP.SwitchToTextSection(TAI.getTextSection()); > + EmitCamlGlobal(getModule(), OS, AP, TAI, "code_begin"); > + > + AP.SwitchToDataSection(TAI.getDataSection()); > + EmitCamlGlobal(getModule(), OS, AP, TAI, "data_begin"); > +} > + > +/// emitAssembly - Print the frametable. The ocaml frametable > format is thus: > +/// > +/// extern "C" struct align(sizeof(intptr_t)) { > +/// uint16_t NumDescriptors; > +/// struct align(sizeof(intptr_t)) { > +/// void *ReturnAddress; > +/// uint16_t FrameSize; > +/// uint16_t NumLiveOffsets; > +/// uint16_t LiveOffsets[NumLiveOffsets]; > +/// } Descriptors[NumDescriptors]; > +/// } caml${module}__frametable; > +/// > +/// Note that this precludes programs from stack frames larger than > 64K > +/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter > will abort if > +/// either condition is detected in a function which uses the > collector. > +/// > +void OcamlCollector::finishAssembly(std::ostream &OS, AsmPrinter &AP, > + const TargetAsmInfo &TAI) { > + const char *AddressDirective; > + int AddressAlignLog; > + if (AP.TM.getTargetData()->getPointerSize() == sizeof(int32_t)) { > + AddressDirective = TAI.getData32bitsDirective(); > + AddressAlignLog = 2; > + } else { > + AddressDirective = TAI.getData64bitsDirective(); > + AddressAlignLog = 3; > + } > + > + AP.SwitchToTextSection(TAI.getTextSection()); > + EmitCamlGlobal(getModule(), OS, AP, TAI, "code_end"); > + > + AP.SwitchToDataSection(TAI.getDataSection()); > + EmitCamlGlobal(getModule(), OS, AP, TAI, "data_end"); > + > + OS << AddressDirective << 0; // FIXME: Why does ocaml emit this?? > + AP.EOL(); > + > + AP.SwitchToDataSection(TAI.getDataSection()); > + EmitCamlGlobal(getModule(), OS, AP, TAI, "frametable"); > + > + for (iterator FI = begin(), FE = end(); FI != FE; ++FI) { > + CollectorMetadata &MD = **FI; > + > + OS << "\t" << TAI.getCommentString() << " live roots for " > + << MD.getFunction().getNameStart() << "\n"; > + > + for (CollectorMetadata::iterator PI = MD.begin(), > + PE = MD.end(); PI != PE; ++PI) { > + > + uint64_t FrameSize = MD.getFrameSize(); > + if (FrameSize >= 2<<16) { > + cerr << "Function '" << MD.getFunction().getNameStart() > + << "' is too large for the ocaml collector! " > + << "Frame size " << FrameSize << " >= 65536.\n"; > + abort(); // Very rude! > + } > + > + size_t LiveCount = MD.live_size(PI); > + if (LiveCount >= 2<<16) { > + cerr << "Function '" << MD.getFunction().getNameStart() > + << "' is too large for the ocaml collector! " > + << "Live root count " << LiveCount << " >= 65536.\n"; > + abort(); // Very rude! > + } > + > + OS << AddressDirective > + << TAI.getPrivateGlobalPrefix() << "label" << PI->Num; > + AP.EOL("call return address"); > + > + AP.EmitInt16(FrameSize); > + AP.EOL("stack frame size"); > + > + AP.EmitInt16(LiveCount); > + AP.EOL("live root count"); > + > + for (CollectorMetadata::live_iterator LI = MD.live_begin(PI), > + LE = MD.live_end(PI); > + LI != LE; ++LI) { > + assert(LI->StackOffset < 2<<16 && > + "GC root stack offset is outside of fixed stack > frame and out " > + "of range for Ocaml collector!"); > + > + OS << "\t.word\t" << LI->StackOffset; > + AP.EOL("stack offset"); > + } > + > + AP.EmitAlignment(AddressAlignLog); > + } > + } > +} > > Added: llvm/trunk/test/CodeGen/Generic/GC/frame_size.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/GC/frame_size.ll?rev=45676&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/Generic/GC/frame_size.ll (added) > +++ llvm/trunk/test/CodeGen/Generic/GC/frame_size.ll Sun Jan 6 > 20:31:11 2008 > @@ -0,0 +1,14 @@ > +; RUN: llvm-as < %s | llc -asm-verbose | grep {frame size} | grep - > v 0x0 > + > +declare void @llvm.gcroot(i8** %value, i8* %tag) > +declare void @g() gc "ocaml" > + > +define void @f(i8* %arg.0, void()* %arg.1) gc "ocaml" { > +entry: > + %gcroot.0 = alloca i8* > + call void @llvm.gcroot(i8** %gcroot.0, i8* null) > + store i8* %arg.0, i8** %gcroot.0 > + call void @g() > + call void %arg.1() > + ret void > +} > > Added: llvm/trunk/test/CodeGen/Generic/GC/simple_ocaml.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/GC/simple_ocaml.ll?rev=45676&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/Generic/GC/simple_ocaml.ll (added) > +++ llvm/trunk/test/CodeGen/Generic/GC/simple_ocaml.ll Sun Jan 6 > 20:31:11 2008 > @@ -0,0 +1,42 @@ > +; RUN: llvm-as < %s | llc | grep caml.*__frametable > +; RUN: llvm-as < %s | llc -march=x86 | grep {movl .0} > + > +%struct.obj = type { i8*, %struct.obj* } > + > +define %struct.obj* @fun(%struct.obj* %head) gc "ocaml" { > +entry: > + %gcroot.0 = alloca i8* > + %gcroot.1 = alloca i8* > + > + call void @llvm.gcroot(i8** %gcroot.0, i8* null) > + call void @llvm.gcroot(i8** %gcroot.1, i8* null) > + > + %local.0 = bitcast i8** %gcroot.0 to %struct.obj** > + %local.1 = bitcast i8** %gcroot.1 to %struct.obj** > + > + store %struct.obj* %head, %struct.obj** %local.0 > + br label %bb.loop > +bb.loop: > + %t0 = load %struct.obj** %local.0 > + %t1 = getelementptr %struct.obj* %t0, i32 0, i32 1 > + %t2 = bitcast %struct.obj* %t0 to i8* > + %t3 = bitcast %struct.obj** %t1 to i8** > + %t4 = call i8* @llvm.gcread(i8* %t2, i8** %t3) > + %t5 = bitcast i8* %t4 to %struct.obj* > + %t6 = icmp eq %struct.obj* %t5, null > + br i1 %t6, label %bb.loop, label %bb.end > +bb.end: > + %t7 = malloc %struct.obj > + store %struct.obj* %t7, %struct.obj** %local.1 > + %t8 = bitcast %struct.obj* %t7 to i8* > + %t9 = load %struct.obj** %local.0 > + %t10 = getelementptr %struct.obj* %t9, i32 0, i32 1 > + %t11 = bitcast %struct.obj* %t9 to i8* > + %t12 = bitcast %struct.obj** %t10 to i8** > + call void @llvm.gcwrite(i8* %t8, i8* %t11, i8** %t12) > + ret %struct.obj* %t7 > +} > + > +declare void @llvm.gcroot(i8** %value, i8* %tag) > +declare void @llvm.gcwrite(i8* %value, i8* %obj, i8** %field) > +declare i8* @llvm.gcread(i8* %obj, i8** %field) From gordonhenriksen at mac.com Mon Jan 7 07:30:39 2008 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 07 Jan 2008 13:30:39 -0000 Subject: [llvm-commits] [llvm] r45700 - in /llvm/trunk/lib/CodeGen: OcamlCollector.cpp ShadowStackCollector.cpp Message-ID: <200801071330.m07DUd5R026232@zion.cs.uiuc.edu> Author: gordon Date: Mon Jan 7 07:30:38 2008 New Revision: 45700 URL: http://llvm.org/viewvc/llvm-project?rev=45700&view=rev Log: Pruning includes. Modified: llvm/trunk/lib/CodeGen/OcamlCollector.cpp llvm/trunk/lib/CodeGen/ShadowStackCollector.cpp Modified: llvm/trunk/lib/CodeGen/OcamlCollector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/OcamlCollector.cpp?rev=45700&r1=45699&r2=45700&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/OcamlCollector.cpp (original) +++ llvm/trunk/lib/CodeGen/OcamlCollector.cpp Mon Jan 7 07:30:38 2008 @@ -13,18 +13,12 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/Collectors.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/Collector.h" -#include "llvm/CodeGen/CollectorMetadata.h" -#include "llvm/Function.h" #include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Support/Compiler.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" -#include using namespace llvm; Modified: llvm/trunk/lib/CodeGen/ShadowStackCollector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ShadowStackCollector.cpp?rev=45700&r1=45699&r2=45700&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ShadowStackCollector.cpp (original) +++ llvm/trunk/lib/CodeGen/ShadowStackCollector.cpp Mon Jan 7 07:30:38 2008 @@ -27,19 +27,11 @@ #define DEBUG_TYPE "shadowstackgc" #include "llvm/CodeGen/Collectors.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/Collector.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" -#include "llvm/Pass.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/LLVMBuilder.h" -#include "llvm/Analysis/Verifier.h" -#include using namespace llvm; From baldrick at free.fr Mon Jan 7 07:44:22 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Jan 2008 13:44:22 -0000 Subject: [llvm-commits] [llvm] r45701 - /llvm/trunk/lib/Target/X86/X86CallingConv.td Message-ID: <200801071344.m07DiMsb026708@zion.cs.uiuc.edu> Author: baldrick Date: Mon Jan 7 07:44:22 2008 New Revision: 45701 URL: http://llvm.org/viewvc/llvm-project?rev=45701&view=rev Log: Fix long double support on x86-32 linux. Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=45701&r1=45700&r2=45701&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Mon Jan 7 07:44:22 2008 @@ -183,7 +183,7 @@ // Long doubles get slots whose size and alignment depends on the // subtarget. - CCIfType<[f80], CCAssignToStack<16, 4>>, + CCIfType<[f80], CCAssignToStack<0, 0>>, // The first 4 vector arguments are passed in XMM registers. CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], From baldrick at free.fr Mon Jan 7 08:49:31 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Jan 2008 14:49:31 -0000 Subject: [llvm-commits] [test-suite] r45702 - /test-suite/trunk/SingleSource/Regression/C/2008-01-07-LongDouble.c Message-ID: <200801071449.m07EnWLF031265@zion.cs.uiuc.edu> Author: baldrick Date: Mon Jan 7 08:49:30 2008 New Revision: 45702 URL: http://llvm.org/viewvc/llvm-project?rev=45702&view=rev Log: Check implementation of the x86 long double ABI. Added: test-suite/trunk/SingleSource/Regression/C/2008-01-07-LongDouble.c Added: test-suite/trunk/SingleSource/Regression/C/2008-01-07-LongDouble.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C/2008-01-07-LongDouble.c?rev=45702&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Regression/C/2008-01-07-LongDouble.c (added) +++ test-suite/trunk/SingleSource/Regression/C/2008-01-07-LongDouble.c Mon Jan 7 08:49:30 2008 @@ -0,0 +1,6 @@ +#include +int main(void) { + long double x = 1.0; + printf("%Lf %Lf\n", x, x); + return 0; +} From alain at frisch.fr Mon Jan 7 10:12:41 2008 From: alain at frisch.fr (Alain Frisch) Date: Mon, 07 Jan 2008 17:12:41 +0100 Subject: [llvm-commits] Patch for compiling with Mingw/Cygwin Message-ID: <47824F79.6040700@frisch.fr> Hello, The attached patch makes it possible to compile LLVM under Mingw/Cygwin (that is, with "gcc -mno-cygwin" under Cygwin). The only problem which I could not address with configure flags is that the tblgen tool expect Windows paths, whereas the build system uses Cygwin paths. The patch introduce a Gnu Make function SYSPATH which performs the translation if needed. Ideally, the SYSPATH variable in Makefile.config should be set by the configure script when given a special option (the same option could also set the other needed options -- see below). As I didn't want to play with autoconf, the current solution requires an explicit argument to be passed to make for the compilation. With the patch, I was able to compile with the following commands: ./configure --build=i686-pc-mingw32 CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin" ac_cv_search_dlopen=no ac_cv_lib_dl_dlopen=no make USE_CYGPATH=1 Alain -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: diff Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080107/0d7aff60/attachment.pl From baldrick at free.fr Mon Jan 7 10:36:38 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Jan 2008 16:36:38 -0000 Subject: [llvm-commits] [llvm] r45703 - /llvm/trunk/lib/Target/X86/X86CallingConv.td Message-ID: <200801071636.m07Gac6k003987@zion.cs.uiuc.edu> Author: baldrick Date: Mon Jan 7 10:36:38 2008 New Revision: 45703 URL: http://llvm.org/viewvc/llvm-project?rev=45703&view=rev Log: Unbreak x86-32 darwin long double! Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=45703&r1=45702&r2=45703&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Mon Jan 7 10:36:38 2008 @@ -181,9 +181,8 @@ // Doubles get 8-byte slots that are 4-byte aligned. CCIfType<[f64], CCAssignToStack<8, 4>>, - // Long doubles get slots whose size and alignment depends on the - // subtarget. - CCIfType<[f80], CCAssignToStack<0, 0>>, + // Long doubles get slots whose size depends on the subtarget. + CCIfType<[f80], CCAssignToStack<0, 4>>, // The first 4 vector arguments are passed in XMM registers. CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], From baldrick at free.fr Mon Jan 7 11:16:07 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Jan 2008 17:16:07 -0000 Subject: [llvm-commits] [llvm] r45704 - in /llvm/trunk: include/llvm/ParameterAttributes.h lib/Transforms/IPO/DeadArgumentElimination.cpp lib/Transforms/Scalar/InstructionCombining.cpp lib/VMCore/ParameterAttributes.cpp lib/VMCore/Verifier.cpp Message-ID: <200801071716.m07HG7Kd006069@zion.cs.uiuc.edu> Author: baldrick Date: Mon Jan 7 11:16:06 2008 New Revision: 45704 URL: http://llvm.org/viewvc/llvm-project?rev=45704&view=rev Log: Small cleanup for handling of type/parameter attribute incompatibility. Modified: llvm/trunk/include/llvm/ParameterAttributes.h llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/VMCore/ParameterAttributes.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/ParameterAttributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=45704&r1=45703&r2=45704&view=diff ============================================================================== --- llvm/trunk/include/llvm/ParameterAttributes.h (original) +++ llvm/trunk/include/llvm/ParameterAttributes.h Mon Jan 7 11:16:06 2008 @@ -52,12 +52,6 @@ /// @brief Attributes that only apply to function return values. const uint16_t ReturnOnly = NoReturn | NoUnwind | ReadNone | ReadOnly; -/// @brief Attributes that only apply to integers. -const uint16_t IntegerTypeOnly = SExt | ZExt; - -/// @brief Attributes that only apply to pointers. -const uint16_t PointerTypeOnly = ByVal | Nest | NoAlias | StructRet; - /// @brief Attributes that are mutually incompatible. const uint16_t MutuallyIncompatible[3] = { ByVal | InReg | Nest | StructRet, @@ -65,8 +59,8 @@ ReadNone | ReadOnly }; -/// @brief Which of the given attributes do not apply to the type. -uint16_t incompatibleWithType (const Type *Ty, uint16_t attrs); +/// @brief Which attributes cannot be applied to a type. +uint16_t typeIncompatible (const Type *Ty); } // end namespace ParamAttr Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=45704&r1=45703&r2=45704&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Mon Jan 7 11:16:06 2008 @@ -505,7 +505,7 @@ const Type *RetTy = FTy->getReturnType(); if (DeadRetVal.count(F)) { RetTy = Type::VoidTy; - RAttrs &= ~ParamAttr::incompatibleWithType(RetTy, RAttrs); + RAttrs &= ~ParamAttr::typeIncompatible(RetTy); DeadRetVal.erase(F); } @@ -561,7 +561,7 @@ // The call return attributes. uint16_t RAttrs = PAL ? PAL->getParamAttrs(0) : 0; // Adjust in case the function was changed to return void. - RAttrs &= ~ParamAttr::incompatibleWithType(NF->getReturnType(), RAttrs); + RAttrs &= ~ParamAttr::typeIncompatible(NF->getReturnType()); if (RAttrs) ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, RAttrs)); Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45704&r1=45703&r2=45704&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Jan 7 11:16:06 2008 @@ -8097,10 +8097,11 @@ FT->getReturnType() != Type::VoidTy) return false; // Cannot transform this return value. - if (!Caller->use_empty() && CallerPAL && - ParamAttr::incompatibleWithType(FT->getReturnType(), - CallerPAL->getParamAttrs(0))) - return false; // Attribute not compatible with transformed value. + if (CallerPAL && !Caller->use_empty()) { + uint16_t RAttrs = CallerPAL->getParamAttrs(0); + if (RAttrs & ParamAttr::typeIncompatible(FT->getReturnType())) + return false; // Attribute not compatible with transformed value. + } // If the callsite is an invoke instruction, and the return value is used by // a PHI node in a successor, we cannot change the return type of the call @@ -8127,9 +8128,11 @@ if (!CastInst::isCastable(ActTy, ParamTy)) return false; // Cannot transform this parameter value. - if (CallerPAL && - ParamAttr::incompatibleWithType(ParamTy, CallerPAL->getParamAttrs(i+1))) - return false; // Attribute not compatible with transformed value. + if (CallerPAL) { + uint16_t PAttrs = CallerPAL->getParamAttrs(i + 1); + if (PAttrs & ParamAttr::typeIncompatible(ParamTy)) + return false; // Attribute not compatible with transformed value. + } ConstantInt *c = dyn_cast(*AI); // Some conversions are safe even if we do not have a body. @@ -8168,7 +8171,7 @@ // If the return value is not being used, the type may not be compatible // with the existing attributes. Wipe out any problematic attributes. - RAttrs &= ~ParamAttr::incompatibleWithType(FT->getReturnType(), RAttrs); + RAttrs &= ~ParamAttr::typeIncompatible(FT->getReturnType()); // Add the new return attributes. if (RAttrs) Modified: llvm/trunk/lib/VMCore/ParameterAttributes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ParameterAttributes.cpp?rev=45704&r1=45703&r2=45704&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ParameterAttributes.cpp (original) +++ llvm/trunk/lib/VMCore/ParameterAttributes.cpp Mon Jan 7 11:16:06 2008 @@ -186,19 +186,21 @@ return getModified(PAL, modVec); } -uint16_t ParamAttr::incompatibleWithType (const Type *Ty, uint16_t attrs) { +uint16_t ParamAttr::typeIncompatible (const Type *Ty) { uint16_t Incompatible = None; if (!Ty->isInteger()) - Incompatible |= IntegerTypeOnly; + // Attributes that only apply to integers. + Incompatible |= SExt | ZExt; - if (!isa(Ty)) - Incompatible |= PointerTypeOnly; - else if (attrs & ParamAttr::ByVal) { - const PointerType *PTy = cast(Ty); + if (const PointerType *PTy = dyn_cast(Ty)) { if (!isa(PTy->getElementType())) + // Attributes that only apply to pointers to structs. Incompatible |= ParamAttr::ByVal; + } else { + // Attributes that only apply to pointers. + Incompatible |= ByVal | Nest | NoAlias | StructRet; } - return attrs & Incompatible; + return Incompatible; } Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=45704&r1=45703&r2=45704&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Jan 7 11:16:06 2008 @@ -418,10 +418,10 @@ Attrs->getParamAttrsText(MutI) + "are incompatible!", V); } - uint16_t IType = ParamAttr::incompatibleWithType(FT->getParamType(Idx-1), - Attr); - Assert1(!IType, "Wrong type for attribute " + - Attrs->getParamAttrsText(IType), V); + uint16_t TypeI = + Attr & ParamAttr::typeIncompatible(FT->getParamType(Idx-1)); + Assert1(!TypeI, "Wrong type for attribute " + + Attrs->getParamAttrsText(TypeI), V); if (Attr & ParamAttr::Nest) { Assert1(!SawNest, "More than one parameter has attribute nest!", V); From natebegeman at mac.com Mon Jan 7 11:49:23 2008 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 07 Jan 2008 17:49:23 -0000 Subject: [llvm-commits] [llvm] r45705 - /llvm/trunk/test/CodeGen/X86/vec_insert-2.ll Message-ID: <200801071749.m07HnOFP007698@zion.cs.uiuc.edu> Author: sampo Date: Mon Jan 7 11:49:23 2008 New Revision: 45705 URL: http://llvm.org/viewvc/llvm-project?rev=45705&view=rev Log: Update test to catch recent x86 insert regression and improvements Modified: llvm/trunk/test/CodeGen/X86/vec_insert-2.ll Modified: llvm/trunk/test/CodeGen/X86/vec_insert-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_insert-2.ll?rev=45705&r1=45704&r2=45705&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_insert-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_insert-2.ll Mon Jan 7 11:49:23 2008 @@ -1,3 +1,6 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep '\$132,' | count 2 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep '\$2,' | count 2 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep shufps | count 4 ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep pinsrw | count 1 ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movhpd | count 1 ; RUN: llvm-as < %s | llc -march=x86-64 -mattr=+sse2 | grep unpcklpd | count 1 From natebegeman at mac.com Mon Jan 7 11:52:24 2008 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 07 Jan 2008 17:52:24 -0000 Subject: [llvm-commits] [llvm] r45707 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200801071752.m07HqOIR007831@zion.cs.uiuc.edu> Author: sampo Date: Mon Jan 7 11:52:24 2008 New Revision: 45707 URL: http://llvm.org/viewvc/llvm-project?rev=45707&view=rev Log: Update the comment on scalar to vector to be a bit more clear. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=45707&r1=45706&r2=45707&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Jan 7 11:52:24 2008 @@ -309,8 +309,8 @@ VECTOR_SHUFFLE, /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a - /// scalar value into the low element of the resultant vector type. The top - /// elements of the vector are undefined. + /// scalar value into element 0 of the resultant vector type. The top + /// elements 1 to N-1 of the N-element vector are undefined. SCALAR_TO_VECTOR, // EXTRACT_SUBREG - This node is used to extract a sub-register value. From dalej at apple.com Mon Jan 7 12:32:58 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 7 Jan 2008 10:32:58 -0800 Subject: [llvm-commits] [llvm] r45701 - /llvm/trunk/lib/Target/X86/X86CallingConv.td In-Reply-To: <200801071344.m07DiMsb026708@zion.cs.uiuc.edu> References: <200801071344.m07DiMsb026708@zion.cs.uiuc.edu> Message-ID: <731A4BB0-C519-463A-A092-0A7E4DC855E3@apple.com> On Jan 7, 2008, at 5:44 AM, Duncan Sands wrote: > Author: baldrick > Date: Mon Jan 7 07:44:22 2008 > New Revision: 45701 > > URL: http://llvm.org/viewvc/llvm-project?rev=45701&view=rev > Log: > Fix long double support on x86-32 linux. Sorry! I think we've finally got it right now. From clattner at apple.com Mon Jan 7 12:39:44 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 7 Jan 2008 10:39:44 -0800 Subject: [llvm-commits] Patch for compiling with Mingw/Cygwin In-Reply-To: <47824F79.6040700@frisch.fr> References: <47824F79.6040700@frisch.fr> Message-ID: <76EF56A3-DC88-4B9E-B37C-78B7DF90579C@apple.com> On Jan 7, 2008, at 8:12 AM, Alain Frisch wrote: > The attached patch makes it possible to compile LLVM under Mingw/ > Cygwin (that is, with "gcc -mno-cygwin" under Cygwin). The only > problem which I could not address with configure flags is that the > tblgen tool expect Windows paths, whereas the build system uses > Cygwin paths. The patch introduce a Gnu Make function SYSPATH which > performs the translation if needed. > > Ideally, the SYSPATH variable in Makefile.config should be set by > the configure script when given a special option (the same option > could also set the other needed options -- see below). As I didn't > want to play with autoconf, the current solution requires an > explicit argument to be passed to make for the compilation. > > With the patch, I was able to compile with the following commands: > > ./configure --build=i686-pc-mingw32 CC="gcc -mno-cygwin" CXX="g++ - > mno-cygwin" ac_cv_search_dlopen=no ac_cv_lib_dl_dlopen=no > > make USE_CYGPATH=1 hi Alain, A couple of comments: You really need to add some comments in Makefile.config.in over the stuff that sets SYSPATH to indicate what it is used for, and probably over the TableGen = ... line in Makefile.rules. If you don't do this, someone may break this in the future. Another thing: does it work to add something like this to makefile.rules? ifeq ($(OS),Cygwin) USE_CYGPATH := true # Actually, it would be better to do the syspath stuff here and remove USE_CYGPATH endif The issue is that I don't really want a magic make variable floating around that people need to know to use. Maybe there is some reason that this can't be made to work, if that's the case, please do figure out the autoconf stuff. Thanks! -Chris From evan.cheng at apple.com Mon Jan 7 12:59:20 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 7 Jan 2008 10:59:20 -0800 Subject: [llvm-commits] [llvm] r45669 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/AsmPrinter.cpp lib/CodeGen/README.txt lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/CBackend/CBackend.cpp lib/Target/MSIL/MSILWriter.cpp In-Reply-To: <200801070130.m071UdMn018032@zion.cs.uiuc.edu> References: <200801070130.m071UdMn018032@zion.cs.uiuc.edu> Message-ID: <766C5863-347A-47BE-8F79-7573F4ED76C7@apple.com> On Jan 6, 2008, at 5:30 PM, Gordon Henriksen wrote: Hi Gordon, I don't know much about the GC work. But it is really necessary for AsmPrinter to use any analysis info? That seems odd to me. Evan > Author: gordon > > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) > +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Sun Jan 6 19:30:38 > 2008 > @@ -118,6 +118,10 @@ > std::string getCurrentFunctionEHName(const MachineFunction *MF); > > protected: > + /// getAnalysisUsage - Record analysis usage. > + /// > + void getAnalysisUsage(AnalysisUsage &AU) const; > + > /// doInitialization - Set up the AsmPrinter when we are working > on a new > /// module. If your pass overrides this, it must make sure to > explicitly > /// call this implementation. > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=45669&r1=45668&r2=45669&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Sun Jan 6 19:30:38 2008 > @@ -16,6 +16,8 @@ > #include "llvm/DerivedTypes.h" > #include "llvm/Constants.h" > #include "llvm/Module.h" > +#include "llvm/CodeGen/Collector.h" > +#include "llvm/CodeGen/CollectorMetadata.h" > #include "llvm/CodeGen/MachineConstantPool.h" > #include "llvm/CodeGen/MachineJumpTableInfo.h" > #include "llvm/CodeGen/MachineModuleInfo.h" > @@ -94,9 +96,20 @@ > } > > > +void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { > + MachineFunctionPass::getAnalysisUsage(AU); > + AU.addRequired(); > +} > + > bool AsmPrinter::doInitialization(Module &M) { > Mang = new Mangler(M, TAI->getGlobalPrefix()); > > + CollectorModuleMetadata *CMM = > getAnalysisToUpdate(); > + assert(CMM && "AsmPrinter didn't require > CollectorModuleMetadata?"); > + for (CollectorModuleMetadata::iterator I = CMM->begin(), > + E = CMM->end(); I != E; ++I) > + (*I)->beginAssembly(O, *this, *TAI); > + > if (!M.getModuleInlineAsm().empty()) > O << TAI->getCommentString() << " Start of file scope inline > assembly\n" > << M.getModuleInlineAsm() > @@ -158,6 +171,12 @@ > } > } > > + CollectorModuleMetadata *CMM = > getAnalysisToUpdate(); > + assert(CMM && "AsmPrinter didn't require > CollectorModuleMetadata?"); > + for (CollectorModuleMetadata::iterator I = CMM->end(), > + E = CMM->begin(); I != E; ) > + (*--I)->finishAssembly(O, *this, *TAI); > + > delete Mang; Mang = 0; > return false; > } > > Modified: llvm/trunk/lib/CodeGen/README.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/README.txt?rev=45669&r1=45668&r2=45669&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/README.txt (original) > +++ llvm/trunk/lib/CodeGen/README.txt Sun Jan 6 19:30:38 2008 > @@ -187,3 +187,8 @@ > assembly. > > // > = > = > = > --------------------------------------------------------------------- > ===// > + > +It would be good to detect collector/target compatibility instead > of silently > +doing the wrong thing. > + > +// > = > = > = > --------------------------------------------------------------------- > ===// > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=45669&r1=45668&r2=45669&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun > Jan 6 19:30:38 2008 > @@ -26,6 +26,7 @@ > #include "llvm/Intrinsics.h" > #include "llvm/IntrinsicInst.h" > #include "llvm/ParameterAttributes.h" > +#include "llvm/CodeGen/Collector.h" > #include "llvm/CodeGen/MachineFunction.h" > #include "llvm/CodeGen/MachineFrameInfo.h" > #include "llvm/CodeGen/MachineInstrBuilder.h" > @@ -426,12 +427,16 @@ > /// FuncInfo - Information about the function as a whole. > /// > FunctionLoweringInfo &FuncInfo; > + > + /// GCI - Garbage collection metadata for the function. > + CollectorMetadata *GCI; > > SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli, > AliasAnalysis &aa, > - FunctionLoweringInfo &funcinfo) > + FunctionLoweringInfo &funcinfo, > + CollectorMetadata *gci) > : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa), > - FuncInfo(funcinfo) { > + FuncInfo(funcinfo), GCI(gci) { > } > > /// getRoot - Return the current virtual root of the Selection DAG. > @@ -2907,6 +2912,22 @@ > DAG.setRoot(Tmp.getValue(1)); > return 0; > } > + > + case Intrinsic::gcroot: > + if (GCI) { > + Value *Alloca = I.getOperand(1); > + Constant *TypeMap = cast(I.getOperand(2)); > + > + FrameIndexSDNode *FI = > cast(getValue(Alloca).Val); > + GCI->addStackRoot(FI->getIndex(), TypeMap); > + } > + return 0; > + > + case Intrinsic::gcread: > + case Intrinsic::gcwrite: > + assert(0 && "Collector failed to lower gcread/gcwrite > intrinsics!"); > + return 0; > + > case Intrinsic::flt_rounds: { > setValue(&I, DAG.getNode(ISD::FLT_ROUNDS, MVT::i32)); > return 0; > @@ -4368,6 +4389,7 @@ > > void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { > AU.addRequired(); > + AU.addRequired(); > AU.setPreservesAll(); > } > > @@ -4378,6 +4400,10 @@ > AA = &getAnalysis(); > > MachineFunction &MF = MachineFunction::construct(&Fn, > TLI.getTargetMachine()); > + if (MF.getFunction()->hasCollector()) > + GCI = > &getAnalysis().get(*MF.getFunction()); > + else > + GCI = 0; > RegInfo = &MF.getRegInfo(); > DOUT << "\n\n\n=== " << Fn.getName() << "\n"; > > @@ -4515,7 +4541,7 @@ > void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, > BasicBlock *LLVMBB, > std::vector > > &PHINodesToUpdate, > FunctionLoweringInfo > &FuncInfo) { > - SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo); > + SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GCI); > > std::vector UnorderedChains; > > @@ -4774,7 +4800,7 @@ > if (!BitTestCases[i].Emitted) { > SelectionDAG HSDAG(TLI, MF, > getAnalysisToUpdate()); > CurDAG = &HSDAG; > - SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo); > + SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI); > // Set the current basic block to the mbb we wish to insert > the code into > BB = BitTestCases[i].Parent; > HSDL.setCurrentBasicBlock(BB); > @@ -4787,7 +4813,7 @@ > for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; > ++j) { > SelectionDAG BSDAG(TLI, MF, > getAnalysisToUpdate()); > CurDAG = &BSDAG; > - SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo); > + SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI); > // Set the current basic block to the mbb we wish to insert > the code into > BB = BitTestCases[i].Cases[j].ThisBB; > BSDL.setCurrentBasicBlock(BB); > @@ -4844,7 +4870,7 @@ > if (!JTCases[i].first.Emitted) { > SelectionDAG HSDAG(TLI, MF, > getAnalysisToUpdate()); > CurDAG = &HSDAG; > - SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo); > + SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI); > // Set the current basic block to the mbb we wish to insert > the code into > BB = JTCases[i].first.HeaderBB; > HSDL.setCurrentBasicBlock(BB); > @@ -4856,7 +4882,7 @@ > > SelectionDAG JSDAG(TLI, MF, > getAnalysisToUpdate()); > CurDAG = &JSDAG; > - SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo); > + SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI); > // Set the current basic block to the mbb we wish to insert the > code into > BB = JTCases[i].second.MBB; > JSDL.setCurrentBasicBlock(BB); > @@ -4904,7 +4930,7 @@ > for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) { > SelectionDAG SDAG(TLI, MF, > getAnalysisToUpdate()); > CurDAG = &SDAG; > - SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo); > + SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI); > > // Set the current basic block to the mbb we wish to insert the > code into > BB = SwitchCases[i].ThisBB; > > Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=45669&r1=45668&r2=45669&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) > +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sun Jan 6 19:30:38 > 2008 > @@ -28,6 +28,7 @@ > #include "llvm/Analysis/ConstantsScanner.h" > #include "llvm/Analysis/FindUsedTypes.h" > #include "llvm/Analysis/LoopInfo.h" > +#include "llvm/CodeGen/Passes.h" > #include "llvm/CodeGen/IntrinsicLowering.h" > #include "llvm/Transforms/Scalar.h" > #include "llvm/Target/TargetMachineRegistry.h" > @@ -2946,11 +2947,12 @@ > bool Fast) { > if (FileType != TargetMachine::AssemblyFile) return true; > > - PM.add(createLowerGCPass()); > + PM.add(createGCLoweringPass()); > PM.add(createLowerAllocationsPass(true)); > PM.add(createLowerInvokePass()); > PM.add(createCFGSimplificationPass()); // clean up after lower > invoke. > PM.add(new CBackendNameAllUsedStructsAndMergeFunctions()); > PM.add(new CWriter(o)); > + PM.add(createCollectorMetadataDeleter()); > return false; > } > > Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=45669&r1=45668&r2=45669&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original) > +++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Sun Jan 6 19:30:38 2008 > @@ -24,6 +24,7 @@ > #include "llvm/Support/MathExtras.h" > #include "llvm/Transforms/Scalar.h" > #include "llvm/ADT/StringExtras.h" > +#include "llvm/CodeGen/Passes.h" > > namespace { > // TargetMachine for the MSIL > @@ -1647,12 +1648,13 @@ > { > if (FileType != TargetMachine::AssemblyFile) return true; > MSILWriter* Writer = new MSILWriter(o); > - PM.add(createLowerGCPass()); > + PM.add(createGCLoweringPass()); > PM.add(createLowerAllocationsPass(true)); > // FIXME: Handle switch trougth native IL instruction "switch" > PM.add(createLowerSwitchPass()); > PM.add(createCFGSimplificationPass()); > PM.add(new MSILModule(Writer->UsedTypes,Writer->TD)); > PM.add(Writer); > + PM.add(createCollectorMetadataDeleter()); > return false; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Mon Jan 7 13:13:36 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Jan 2008 19:13:36 -0000 Subject: [llvm-commits] [llvm] r45712 - /llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp Message-ID: <200801071913.m07JDbmk011670@zion.cs.uiuc.edu> Author: baldrick Date: Mon Jan 7 13:13:36 2008 New Revision: 45712 URL: http://llvm.org/viewvc/llvm-project?rev=45712&view=rev Log: Add missing newline at EOF. Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp?rev=45712&r1=45711&r2=45712&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp Mon Jan 7 13:13:36 2008 @@ -258,4 +258,4 @@ if (NewMI) NewMI->copyKillDeadInfo(MI); return NewMI; -} \ No newline at end of file +} From baldrick at free.fr Mon Jan 7 13:14:43 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Jan 2008 19:14:43 -0000 Subject: [llvm-commits] [llvm] r45714 - /llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp Message-ID: <200801071914.m07JEh9I011742@zion.cs.uiuc.edu> Author: baldrick Date: Mon Jan 7 13:14:42 2008 New Revision: 45714 URL: http://llvm.org/viewvc/llvm-project?rev=45714&view=rev Log: I doubt the address of the Error string was intended to be used for the force_interpreter parameter... Spotted by gcc-4.2. Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp?rev=45714&r1=45713&r2=45714&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp Mon Jan 7 13:14:42 2008 @@ -101,7 +101,8 @@ LLVMModuleProviderRef MP, char **OutError) { std::string Error; - if (ExecutionEngine *Interp = ExecutionEngine::create(unwrap(MP), &Error)) { + if (ExecutionEngine *Interp = + ExecutionEngine::create(unwrap(MP), false, &Error)) { *OutInterp = wrap(Interp); return 0; } From resistor at mac.com Mon Jan 7 15:30:41 2008 From: resistor at mac.com (Owen Anderson) Date: Mon, 07 Jan 2008 21:30:41 -0000 Subject: [llvm-commits] [llvm] r45718 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801072130.m07LUfVY018330@zion.cs.uiuc.edu> Author: resistor Date: Mon Jan 7 15:30:40 2008 New Revision: 45718 URL: http://llvm.org/viewvc/llvm-project?rev=45718&view=rev Log: Make some predicates static. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45718&r1=45717&r2=45718&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Jan 7 15:30:40 2008 @@ -231,7 +231,7 @@ /// isLiveIn - helper method that determines, from a VarInfo, if a register /// is live into a block -bool isLiveIn(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) { +static bool isLiveIn(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) { if (V.AliveBlocks.test(MBB->getNumber())) return true; @@ -244,7 +244,7 @@ /// isLiveOut - help method that determines, from a VarInfo, if a register is /// live out of a block. -bool isLiveOut(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) { +static bool isLiveOut(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) { if (MBB == V.DefInst->getParent() || V.UsedBlocks.test(MBB->getNumber())) { for (std::vector::iterator I = V.Kills.begin(), @@ -260,7 +260,7 @@ /// isKillInst - helper method that determines, from a VarInfo, if an /// instruction kills a given register -bool isKillInst(LiveVariables::VarInfo& V, MachineInstr* MI) { +static bool isKillInst(LiveVariables::VarInfo& V, MachineInstr* MI) { return std::find(V.Kills.begin(), V.Kills.end(), MI) != V.Kills.end(); } From resistor at mac.com Mon Jan 7 15:32:09 2008 From: resistor at mac.com (Owen Anderson) Date: Mon, 07 Jan 2008 21:32:09 -0000 Subject: [llvm-commits] [llvm] r45719 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801072132.m07LW9xb018402@zion.cs.uiuc.edu> Author: resistor Date: Mon Jan 7 15:32:09 2008 New Revision: 45719 URL: http://llvm.org/viewvc/llvm-project?rev=45719&view=rev Log: Oops, missed one. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45719&r1=45718&r2=45719&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Jan 7 15:32:09 2008 @@ -268,7 +268,7 @@ /// trick parameter is 'mode' which tells it the relationship of the two /// registers. 0 - defined in the same block, 1 - first properly dominates /// second, 2 - second properly dominates first -bool interferes(LiveVariables::VarInfo& First, LiveVariables::VarInfo& Second, +static bool interferes(LiveVariables::VarInfo& First, LiveVariables::VarInfo& Second, MachineBasicBlock* scan, unsigned mode) { MachineInstr* def = 0; MachineInstr* kill = 0; From sabre at nondot.org Mon Jan 7 15:38:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 21:38:14 -0000 Subject: [llvm-commits] [llvm] r45720 - /llvm/trunk/lib/Target/README.txt Message-ID: <200801072138.m07LcEbd018641@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 15:38:14 2008 New Revision: 45720 URL: http://llvm.org/viewvc/llvm-project?rev=45720&view=rev Log: possible switch lowering improvement. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=45720&r1=45719&r2=45720&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Mon Jan 7 15:38:14 2008 @@ -519,3 +519,8 @@ In this case, whole-function-isel would also handle this. //===---------------------------------------------------------------------===// + +Investigate lowering of sparse switch statements into perfect hash tables: +http://burtleburtle.net/bob/hash/perfect.html + +//===---------------------------------------------------------------------===// From sabre at nondot.org Mon Jan 7 15:59:59 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 21:59:59 -0000 Subject: [llvm-commits] [llvm] r45723 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200801072159.m07Lxx4I019649@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 15:59:58 2008 New Revision: 45723 URL: http://llvm.org/viewvc/llvm-project?rev=45723&view=rev Log: add a note that is important for some fp apps. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=45723&r1=45722&r2=45723&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Mon Jan 7 15:59:58 2008 @@ -1597,3 +1597,24 @@ This would result in smaller code and more efficient microops. //===---------------------------------------------------------------------===// + +In SSE mode, we turn abs and neg into a load from the constant pool plus a xor +or and instruction, for example: + + xorpd LCPI2_0-"L2$pb"(%esi), %xmm2 + +However, if xmm2 gets spilled, we end up with really ugly code like this: + + %xmm2 = reload [mem] + xorpd LCPI2_0-"L2$pb"(%esi), %xmm2 + store %xmm2 -> [mem] + +Since we 'know' that this is a 'neg', we can actually "fold" the spill into +the neg/abs instruction, turning it into an *integer* operation, like this: + + xorl 2147483648, [mem+4] ## 2147483648 = (1 << 31) + +you could also use xorb, but xorl is less likely to lead to a partial register +stall. + +//===---------------------------------------------------------------------===// From evan.cheng at apple.com Mon Jan 7 17:08:23 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Jan 2008 23:08:23 -0000 Subject: [llvm-commits] [llvm] r45725 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801072308.m07N8NpO022605@zion.cs.uiuc.edu> Author: evancheng Date: Mon Jan 7 17:08:23 2008 New Revision: 45725 URL: http://llvm.org/viewvc/llvm-project?rev=45725&view=rev Log: Unbreak x86-64. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45725&r1=45724&r2=45725&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Jan 7 17:08:23 2008 @@ -1478,10 +1478,9 @@ // Add argument registers to the end of the list so that they are known live // into the call. - if (IsTailCall) - for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) - Ops.push_back(DAG.getRegister(RegsToPass[i].first, - RegsToPass[i].second.getValueType())); + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(RegsToPass[i].first, + RegsToPass[i].second.getValueType())); if (InFlag.Val) Ops.push_back(InFlag); From sabre at nondot.org Mon Jan 7 17:16:56 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Jan 2008 23:16:56 -0000 Subject: [llvm-commits] [llvm] r45726 - /llvm/trunk/lib/Target/Target.td Message-ID: <200801072316.m07NGuC4023034@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 17:16:55 2008 New Revision: 45726 URL: http://llvm.org/viewvc/llvm-project?rev=45726&view=rev Log: add a new bit. Modified: llvm/trunk/lib/Target/Target.td Modified: llvm/trunk/lib/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.td?rev=45726&r1=45725&r2=45726&view=diff ============================================================================== --- llvm/trunk/lib/Target/Target.td (original) +++ llvm/trunk/lib/Target/Target.td Mon Jan 7 17:16:55 2008 @@ -190,7 +190,8 @@ bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? bit isSimpleLoad = 0; // Is this just a load instruction? - bit mayStore = 0; // Can this instruction modify memory? + bit mayLoad = 0; // Is it possible for this inst to read memory? + bit mayStore = 0; // Is it possible for this inst to write memory? bit isImplicitDef = 0; // Is this instruction an implicit def instruction? bit isTwoAddress = 0; // Is this a two address instruction? bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? From evan.cheng at apple.com Mon Jan 7 17:57:00 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Jan 2008 23:57:00 -0000 Subject: [llvm-commits] [llvm] r45727 - in /llvm/trunk/lib/Target/ARM: ARMInstrInfo.cpp ARMInstrInfo.td ARMInstrThumb.td ARMInstrVFP.td Message-ID: <200801072357.m07Nv0sI024768@zion.cs.uiuc.edu> Author: evancheng Date: Mon Jan 7 17:56:57 2008 New Revision: 45727 URL: http://llvm.org/viewvc/llvm-project?rev=45727&view=rev Log: Only mark instructions that load a single value without extension as isSimpleLoad = 1. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=45727&r1=45726&r2=45727&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Mon Jan 7 17:56:57 2008 @@ -202,7 +202,7 @@ unsigned AddrMode = (TSFlags & ARMII::AddrModeMask); const TargetInstrDesc &TID = MI->getDesc(); unsigned NumOps = TID.getNumOperands(); - bool isLoad = TID.isSimpleLoad(); + bool isLoad = !TID.mayStore(); const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0); const MachineOperand &Base = MI->getOperand(2); const MachineOperand &Offset = MI->getOperand(NumOps-3); Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=45727&r1=45726&r2=45727&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Jan 7 17:56:57 2008 @@ -684,7 +684,8 @@ Pseudo, "$cp:\n\tadd$p $dst, pc, $a", [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; -let isSimpleLoad = 1, AddedComplexity = 10 in { +let AddedComplexity = 10 in { +let isSimpleLoad = 1 in def PICLD : AXI2<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), Pseudo, "${addr:label}:\n\tldr$p $dst, $addr", [(set GPR:$dst, (load addrmodepc:$addr))]>; @@ -738,7 +739,7 @@ // FIXME: remove when we have a way to marking a MI with these properties. // FIXME: $dst1 should be a def. But the extra ops must be in the end of the // operand list. -let isSimpleLoad = 1, isReturn = 1, isTerminator = 1 in +let isReturn = 1, isTerminator = 1 in def LDM_RET : AXI4<0x0, (outs), (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), LdFrm, "ldm${p}${addr:submode} $addr, $dst1", @@ -802,13 +803,13 @@ // // Load -let isSimpleLoad = 1 in { +let isSimpleLoad = 1 in def LDR : AI2<0x0, (outs GPR:$dst), (ins addrmode2:$addr), LdFrm, "ldr", " $dst, $addr", [(set GPR:$dst, (load addrmode2:$addr))]>; // Special LDR for loads from non-pc-relative constpools. -let isReMaterializable = 1 in +let isSimpleLoad = 1, isReMaterializable = 1 in def LDRcp : AI2<0x0, (outs GPR:$dst), (ins addrmode2:$addr), LdFrm, "ldr", " $dst, $addr", []>; @@ -875,7 +876,6 @@ def LDRSB_POST: AI3po<0xD, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base,am3offset:$offset), LdFrm, "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>; -} // isSimpleLoad // Store def STR : AI2<0x0, (outs), (ins GPR:$src, addrmode2:$addr), StFrm, @@ -939,7 +939,6 @@ // // FIXME: $dst1 should be a def. -let isSimpleLoad = 1 in def LDM : AXI4<0x0, (outs), (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), LdFrm, "ldm${p}${addr:submode} $addr, $dst1", Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=45727&r1=45726&r2=45727&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Jan 7 17:56:57 2008 @@ -188,7 +188,7 @@ } // FIXME: remove when we have a way to marking a MI with these properties. -let isSimpleLoad = 1, isReturn = 1, isTerminator = 1 in +let isReturn = 1, isTerminator = 1 in def tPOP_RET : TI<(outs reglist:$dst1, variable_ops), (ins), "pop $dst1", []>; @@ -237,7 +237,7 @@ // Load Store Instructions. // -let isSimpleLoad = 1 in { +let isSimpleLoad = 1 in def tLDR : TI4<(outs GPR:$dst), (ins t_addrmode_s4:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load t_addrmode_s4:$addr))]>; @@ -258,25 +258,27 @@ "ldrsh $dst, $addr", [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; +let isSimpleLoad = 1 in def tLDRspi : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load t_addrmode_sp:$addr))]>; // Special instruction for restore. It cannot clobber condition register // when it's expanded by eliminateCallFramePseudoInstr(). +let isSimpleLoad = 1 in def tRestore : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), "ldr $dst, $addr", []>; // Load tconstpool +let isSimpleLoad = 1 in def tLDRpci : TIs<(outs GPR:$dst), (ins i32imm:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; // Special LDR for loads from non-pc-relative constpools. -let isReMaterializable = 1 in +let isSimpleLoad = 1, isReMaterializable = 1 in def tLDRcp : TIs<(outs GPR:$dst), (ins i32imm:$addr), "ldr $dst, $addr", []>; -} // isSimpleLoad def tSTR : TI4<(outs), (ins GPR:$src, t_addrmode_s4:$addr), "str $src, $addr", @@ -307,7 +309,6 @@ // TODO: A7-44: LDMIA - load multiple -let isSimpleLoad = 1 in def tPOP : TI<(outs reglist:$dst1, variable_ops), (ins), "pop $dst1", []>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=45727&r1=45726&r2=45727&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Mon Jan 7 17:56:57 2008 @@ -110,7 +110,6 @@ // Load / store multiple Instructions. // -let isSimpleLoad = 1 in { def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1, variable_ops), "fldm${addr:submode}d${p} ${addr:base}, $dst1", @@ -120,7 +119,6 @@ variable_ops), "fldm${addr:submode}s${p} ${addr:base}, $dst1", []>; -} // isSimpleLoad let mayStore = 1 in { def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1, From isanbard at gmail.com Mon Jan 7 18:52:29 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 08 Jan 2008 00:52:29 -0000 Subject: [llvm-commits] [llvm] r45731 - /llvm/trunk/lib/Target/X86/X86JITInfo.cpp Message-ID: <200801080052.m080qThJ028018@zion.cs.uiuc.edu> Author: void Date: Mon Jan 7 18:52:29 2008 New Revision: 45731 URL: http://llvm.org/viewvc/llvm-project?rev=45731&view=rev Log: Silence warning about loss of precision. Modified: llvm/trunk/lib/Target/X86/X86JITInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86JITInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.cpp?rev=45731&r1=45730&r2=45731&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86JITInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86JITInfo.cpp Mon Jan 7 18:52:29 2008 @@ -387,7 +387,7 @@ MCE.emitWordLE(((unsigned *)&GV)[1]); #else MCE.startFunctionStub(4, 4); - MCE.emitWordLE((unsigned)GV); + MCE.emitWordLE((intptr_t)GV); #endif return MCE.finishFunctionStub(0); } From evan.cheng at apple.com Mon Jan 7 20:06:12 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 08 Jan 2008 02:06:12 -0000 Subject: [llvm-commits] [llvm] r45733 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200801080206.m0826C2x031755@zion.cs.uiuc.edu> Author: evancheng Date: Mon Jan 7 20:06:11 2008 New Revision: 45733 URL: http://llvm.org/viewvc/llvm-project?rev=45733&view=rev Log: Fix a x86-64 static codegen bug. This fixes a lot of x86-64 jit failures. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=45733&r1=45732&r2=45733&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Jan 7 20:06:11 2008 @@ -1091,7 +1091,10 @@ // Turn ADD X, c to MOV32ri X+c. This cannot be done with tblgen'd // code and is matched first so to prevent it from being turned into // LEA32r X+c. - // In 64-bit mode, use LEA to take advantage of RIP-relative addressing. + // In 64-bit small code size mode, use LEA to take advantage of + // RIP-relative addressing. + if (TM.getCodeModel() != CodeModel::Small) + break; MVT::ValueType PtrVT = TLI.getPointerTy(); SDOperand N0 = N.getOperand(0); SDOperand N1 = N.getOperand(1); From evan.cheng at apple.com Mon Jan 7 20:07:10 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 08 Jan 2008 02:07:10 -0000 Subject: [llvm-commits] [llvm] r45734 - /llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Message-ID: <200801080207.m0827A5L031793@zion.cs.uiuc.edu> Author: evancheng Date: Mon Jan 7 20:07:10 2008 New Revision: 45734 URL: http://llvm.org/viewvc/llvm-project?rev=45734&view=rev Log: Minor fix to enable x86-64 pic jit (still fails for other reasons). Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=45734&r1=45733&r2=45734&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Mon Jan 7 20:07:10 2008 @@ -171,9 +171,10 @@ bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast, bool DumpAsm, MachineCodeEmitter &MCE) { // FIXME: Move this to TargetJITInfo! - if (DefRelocModel == Reloc::Default) + if (DefRelocModel == Reloc::Default) { setRelocationModel(Reloc::Static); - Subtarget.setPICStyle(PICStyle::None); + Subtarget.setPICStyle(PICStyle::None); + } // JIT cannot ensure globals are placed in the lower 4G of address. if (Subtarget.is64Bit()) From gordonhenriksen at mac.com Mon Jan 7 21:37:32 2008 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 7 Jan 2008 22:37:32 -0500 Subject: [llvm-commits] [llvm] r45669 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/AsmPrinter.cpp lib/CodeGen/README.txt lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/CBackend/CBackend.cpp lib/Target/MSIL/MSILWriter.cpp In-Reply-To: <766C5863-347A-47BE-8F79-7573F4ED76C7@apple.com> References: <200801070130.m071UdMn018032@zion.cs.uiuc.edu> <766C5863-347A-47BE-8F79-7573F4ED76C7@apple.com> Message-ID: On 2008-01-07, at 13:59, Evan Cheng wrote: > I don't know much about the GC work. But it is really necessary for > AsmPrinter to use any analysis info? That seems odd to me. Hi Evan, Debug information has an analogue in the MachineModuleInfo pass, which you'll find is required from the target-specific subclasses of AsmPrinter. In both cases, these are ImmutablePasses (not analyses in any practical sense) and are used so that PassManager does the memory management. They store information collected during lowering. I would've put GC information in MMI except that the GC code is independent of MachineFoo. The shadow-stack algorithm works with the CBackend, as a for-instance. ? Gordon From sabre at nondot.org Mon Jan 7 22:26:20 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 04:26:20 -0000 Subject: [llvm-commits] [llvm] r45736 - /llvm/trunk/tools/bugpoint/ExtractFunction.cpp Message-ID: <200801080426.m084QKBS007268@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 22:26:20 2008 New Revision: 45736 URL: http://llvm.org/viewvc/llvm-project?rev=45736&view=rev Log: Fix PR1797 Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExtractFunction.cpp?rev=45736&r1=45735&r2=45736&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ExtractFunction.cpp (original) +++ llvm/trunk/tools/bugpoint/ExtractFunction.cpp Mon Jan 7 22:26:20 2008 @@ -335,6 +335,9 @@ for (std::vector::const_iterator I = BBs.begin(), E = BBs.end(); I != E; ++I) { BasicBlock *BB = *I; + // If the BB doesn't have a name, give it one so we have something to key + // off of. + if (!BB->hasName()) BB->setName("tmpbb"); BlocksToNotExtractFile << BB->getParent()->getName() << " " << BB->getName() << "\n"; } From sabre at nondot.org Mon Jan 7 22:59:40 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 04:59:40 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r45737 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200801080459.m084xe8i009329@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 22:59:40 2008 New Revision: 45737 URL: http://llvm.org/viewvc/llvm-project?rev=45737&view=rev Log: Fix PR1721 with a minimal hack: if we see that we are codegen'ing something with a smaller precision than the llvm register for it, do the zext/sext explicitly in the llvm IR. This mirrors what GCC does in its expr.c. Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=45737&r1=45736&r2=45737&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Jan 7 22:59:40 2008 @@ -940,6 +940,30 @@ break; } + // If this is an operation on an integer value in a precision smaller than + // the LLVM value we are computing it in, reduce the excess precision here. + // This happens with odd-sized bitfields (e.g. i33) that are evaluated in the + // next size power-of-two register (e.g. i64). This should be reevaluated + // when we have good support for unusual sized integers in the code generator. + if (Result && TREE_CODE(TREE_TYPE(exp)) == INTEGER_TYPE) { + unsigned LLVMWidth = cast(Result->getType())->getBitWidth(); + unsigned TreeWidth = TYPE_PRECISION(TREE_TYPE(exp)); + if (LLVMWidth > TreeWidth && lang_hooks.reduce_bit_field_operations) { + if (TYPE_UNSIGNED(TREE_TYPE(exp))) { + // Use an 'and' to clear excess top bits. + Constant *Mask = + ConstantInt::get(APInt::getLowBitsSet(LLVMWidth, TreeWidth)); + Result = Builder.CreateAnd(Result, Mask, "mask"); + } else { + // Shift Left then shift right. + Constant *ShAmt = ConstantInt::get(Result->getType(), + LLVMWidth-TreeWidth); + Result = Builder.CreateShl(Result, ShAmt, "sextl"); + Result = Builder.CreateAShr(Result, ShAmt, "sextr"); + } + } + } + if (TheDebugInfo && EXPR_HAS_LOCATION(exp)) { // Restore location back down the tree. TheDebugInfo->setLocationFile(EXPR_FILENAME(exp)); From resistor at mac.com Mon Jan 7 23:16:15 2008 From: resistor at mac.com (Owen Anderson) Date: Tue, 08 Jan 2008 05:16:15 -0000 Subject: [llvm-commits] [llvm] r45738 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801080516.m085GGlU010142@zion.cs.uiuc.edu> Author: resistor Date: Mon Jan 7 23:16:15 2008 New Revision: 45738 URL: http://llvm.org/viewvc/llvm-project?rev=45738&view=rev Log: Actually insert copies now! Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45738&r1=45737&r2=45738&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Jan 7 23:16:15 2008 @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DepthFirstIterator.h" @@ -47,11 +48,8 @@ bool runOnMachineFunction(MachineFunction &Fn); virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); - AU.addPreservedID(PHIEliminationID); AU.addRequired(); AU.addRequired(); - AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -516,6 +514,7 @@ /// of Static Single Assignment Form" by Briggs, et al. void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, std::set& pushed) { + // FIXME: This function needs to update LiveVariables std::map& copy_set= Waiting[MBB]; std::map worklist; @@ -540,6 +539,8 @@ } LiveVariables& LV = getAnalysis(); + MachineFunction* MF = MBB->getParent(); + const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); // Iterate over the worklist, inserting copies while (!worklist.empty() || !copy_set.empty()) { @@ -547,13 +548,29 @@ std::pair curr = *worklist.begin(); worklist.erase(curr.first); + const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(curr.first); + if (isLiveOut(LV.getVarInfo(curr.second), MBB)) { - // Insert copy from curr.second to a temporary + // Create a temporary + unsigned t = MF->getRegInfo().createVirtualRegister(RC); + + // Insert copy from curr.second to a temporary at + // the Phi defining curr.second + LiveVariables::VarInfo VI = LV.getVarInfo(curr.second); + MachineBasicBlock::iterator PI = VI.DefInst; + TII->copyRegToReg(*VI.DefInst->getParent(), PI, t, + curr.second, RC, RC); + // Push temporary on Stacks - // Insert temporary in pushed + Stacks[curr.second].push_back(t); + + // Insert curr.second in pushed + pushed.insert(curr.second); } // Insert copy from map[curr.first] to curr.second + TII->copyRegToReg(*MBB, MBB->end(), curr.second, + map[curr.first], RC, RC); map[curr.first] = curr.second; // If curr.first is a destination in copy_set... @@ -577,8 +594,13 @@ std::pair curr = *copy_set.begin(); copy_set.erase(curr.first); + const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(curr.first); + // Insert a copy from dest to a new temporary t at the end of b - // map[curr.second] = t; + unsigned t = MF->getRegInfo().createVirtualRegister(RC); + TII->copyRegToReg(*MBB, MBB->end(), t, + curr.second, RC, RC); + map[curr.second] = t; worklist.insert(curr); } @@ -628,6 +650,7 @@ InsertCopies(Fn.begin()); // FIXME: Perform renaming + // FIXME: Remove Phi instrs return false; } From sabre at nondot.org Mon Jan 7 23:16:30 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 05:16:30 -0000 Subject: [llvm-commits] [llvm] r45739 - /llvm/trunk/test/CFrontend/2008-01-07-UnusualIntSize.c Message-ID: <200801080516.m085GU0Q010161@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 23:16:29 2008 New Revision: 45739 URL: http://llvm.org/viewvc/llvm-project?rev=45739&view=rev Log: Testcase for PR1721 Added: llvm/trunk/test/CFrontend/2008-01-07-UnusualIntSize.c Added: llvm/trunk/test/CFrontend/2008-01-07-UnusualIntSize.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2008-01-07-UnusualIntSize.c?rev=45739&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/2008-01-07-UnusualIntSize.c (added) +++ llvm/trunk/test/CFrontend/2008-01-07-UnusualIntSize.c Mon Jan 7 23:16:29 2008 @@ -0,0 +1,11 @@ +// RUN: %llvmgcc %s -S -o - -O | grep {and.*8589934591} +// PR1721 + +struct s { + unsigned long long u33: 33; +} a, b; + +// This should turn into a real 33-bit add, not a 64-bit add. +_Bool test(void) { + return a.u33 + b.u33 != 0; +} From sabre at nondot.org Mon Jan 7 23:18:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 05:18:46 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45740 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200801080518.m085Ik5m010283@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 7 23:18:45 2008 New Revision: 45740 URL: http://llvm.org/viewvc/llvm-project?rev=45740&view=rev Log: Fix PR1721 with a minimal hack: if we see that we are codegen'ing something with a smaller precision than the llvm register for it, do the zext/sext explicitly in the llvm IR. This mirrors what GCC does in its expr.c. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=45740&r1=45739&r2=45740&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Jan 7 23:18:45 2008 @@ -982,6 +982,30 @@ break; } + // If this is an operation on an integer value in a precision smaller than + // the LLVM value we are computing it in, reduce the excess precision here. + // This happens with odd-sized bitfields (e.g. i33) that are evaluated in the + // next size power-of-two register (e.g. i64). This should be reevaluated + // when we have good support for unusual sized integers in the code generator. + if (Result && TREE_CODE(TREE_TYPE(exp)) == INTEGER_TYPE) { + unsigned LLVMWidth = cast(Result->getType())->getBitWidth(); + unsigned TreeWidth = TYPE_PRECISION(TREE_TYPE(exp)); + if (LLVMWidth > TreeWidth && lang_hooks.reduce_bit_field_operations) { + if (TYPE_UNSIGNED(TREE_TYPE(exp))) { + // Use an 'and' to clear excess top bits. + Constant *Mask = + ConstantInt::get(APInt::getLowBitsSet(LLVMWidth, TreeWidth)); + Result = Builder.CreateAnd(Result, Mask, "mask"); + } else { + // Shift Left then shift right. + Constant *ShAmt = ConstantInt::get(Result->getType(), + LLVMWidth-TreeWidth); + Result = Builder.CreateShl(Result, ShAmt, "sextl"); + Result = Builder.CreateAShr(Result, ShAmt, "sextr"); + } + } + } + if (TheDebugInfo && EXPR_HAS_LOCATION(exp)) { // Restore location back down the tree. TheDebugInfo->setLocationFile(EXPR_FILENAME(exp)); From isanbard at gmail.com Tue Jan 8 00:08:04 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 08 Jan 2008 06:08:04 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45741 - /llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Message-ID: <200801080608.m08685Ki013047@zion.cs.uiuc.edu> Author: void Date: Tue Jan 8 00:08:04 2008 New Revision: 45741 URL: http://llvm.org/viewvc/llvm-project?rev=45741&view=rev Log: Make the metaclass and some other metadata variables local instead of global. Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=45741&r1=45740&r2=45741&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Tue Jan 8 00:08:04 2008 @@ -9925,12 +9925,24 @@ /* struct class_t OBJC_CLASS_$_; */ UOBJC_V2_CLASS_decl = build_metadata_decl ("OBJC_CLASS_$", /* APPLE LOCAL radar 5202926 */ + /* APPLE LOCAL begin radar 5658734 */ +#ifndef ENABLE_LLVM objc_v2_class_template, true); +#else + objc_v2_class_template, false); +#endif + /* APPLE LOCAL end radar 5658734 */ /* struct class_t OBJC_METACLASS_$_; */ UOBJC_V2_METACLASS_decl = build_metadata_decl ("OBJC_METACLASS_$", /* APPLE LOCAL radar 5202926 */ + /* APPLE LOCAL begin radar 5658734 */ +#ifndef ENABLE_LLVM objc_v2_class_template, true); +#else + objc_v2_class_template, false); +#endif + /* APPLE LOCAL end radar 5658734 */ } static void @@ -12034,7 +12046,16 @@ sav = objc_implementation_context; objc_implementation_context = my_root_int; /* APPLE LOCAL radar 5202926 */ - root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, true); + /* APPLE LOCAL begin radar 5658734 */ +#ifndef ENABLE_LLVM + root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, + true); +#else + root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, + false); +#endif + root_expr = update_var_decl (root_expr); + /* APPLE LOCAL end radar 5658734 */ root_expr = build_fold_addr_expr (root_expr); /* Install class `isa' and `super' pointers at runtime. */ @@ -12045,10 +12066,32 @@ back-end, recognizes '_OBJC_' prefix and prepends an 'L' in front of this. Darwin assembler treats names starting with 'L_' as local symbols. */ /* APPLE LOCAL radar 5202926 */ - class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", objc_v2_class_template, true); + /* APPLE LOCAL begin radar 5658734 */ +#ifndef ENABLE_LLVM + class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", + objc_v2_class_template, + true); +#else + class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", + objc_v2_class_template, + false); +#endif + class_superclass_expr = update_var_decl (class_superclass_expr); + /* APPLE LOCAL end radar 5658734 */ class_superclass_expr = build_fold_addr_expr (class_superclass_expr); /* APPLE LOCAL radar 5202926 */ - metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, true); + /* APPLE LOCAL begin radar 5658734 */ +#ifndef ENABLE_LLVM + metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", + objc_v2_class_template, + true); +#else + metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", + objc_v2_class_template, + false); +#endif + metaclass_superclass_expr = update_var_decl (metaclass_superclass_expr); + /* APPLE LOCAL end radar 5658734 */ metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr); objc_implementation_context = sav; } From sabre at nondot.org Tue Jan 8 00:46:31 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 06:46:31 -0000 Subject: [llvm-commits] [llvm] r45742 - in /llvm/trunk: lib/Target/PowerPC/PPCISelDAGToDAG.cpp lib/Target/PowerPC/README.txt test/CodeGen/PowerPC/compare-fcmp-ord.ll Message-ID: <200801080646.m086kVfA015005@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 00:46:30 2008 New Revision: 45742 URL: http://llvm.org/viewvc/llvm-project?rev=45742&view=rev Log: Finally implement correct ordered comparisons for PPC, even though the code generated is not wonderful. This turns a miscompilation into a code quality bug (noted in the ppc readme). This fixes PR642, which is over 2 years old (!). Nate, please review this. Added: llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/README.txt Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=45742&r1=45741&r2=45742&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Jan 8 00:46:30 2008 @@ -624,29 +624,34 @@ /// getCRIdxForSetCC - Return the index of the condition register field /// associated with the SetCC condition, and whether or not the field is /// treated as inverted. That is, lt = 0; ge = 0 inverted. -static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) { +/// +/// If this returns with Other != -1, then the returned comparison is an or of +/// two simpler comparisons. In this case, Invert is guaranteed to be false. +static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) { + Invert = false; + Other = -1; switch (CC) { default: assert(0 && "Unknown condition!"); abort(); - case ISD::SETOLT: // FIXME: This is incorrect see PR642. - case ISD::SETULT: - case ISD::SETLT: Inv = false; return 0; - case ISD::SETOGE: // FIXME: This is incorrect see PR642. + case ISD::SETOLT: + case ISD::SETLT: return 0; // Bit #0 = SETOLT + case ISD::SETOGT: + case ISD::SETGT: return 1; // Bit #1 = SETOGT + case ISD::SETOEQ: + case ISD::SETEQ: return 2; // Bit #2 = SETOEQ + case ISD::SETUO: return 3; // Bit #3 = SETUO case ISD::SETUGE: - case ISD::SETGE: Inv = true; return 0; - case ISD::SETOGT: // FIXME: This is incorrect see PR642. - case ISD::SETUGT: - case ISD::SETGT: Inv = false; return 1; - case ISD::SETOLE: // FIXME: This is incorrect see PR642. + case ISD::SETGE: Invert = true; return 0; // !Bit #0 = SETUGE case ISD::SETULE: - case ISD::SETLE: Inv = true; return 1; - case ISD::SETOEQ: // FIXME: This is incorrect see PR642. - case ISD::SETUEQ: - case ISD::SETEQ: Inv = false; return 2; - case ISD::SETONE: // FIXME: This is incorrect see PR642. + case ISD::SETLE: Invert = true; return 1; // !Bit #1 = SETULE case ISD::SETUNE: - case ISD::SETNE: Inv = true; return 2; - case ISD::SETO: Inv = true; return 3; - case ISD::SETUO: Inv = false; return 3; + case ISD::SETNE: Invert = true; return 2; // !Bit #2 = SETUNE + case ISD::SETO: Invert = true; return 3; // !Bit #3 = SETO + case ISD::SETULT: Other = 0; return 3; // SETOLT | SETUO + case ISD::SETUGT: Other = 1; return 3; // SETOGT | SETUO + case ISD::SETUEQ: Other = 2; return 3; // SETOEQ | SETUO + case ISD::SETOGE: Other = 1; return 2; // SETOGT | SETOEQ + case ISD::SETOLE: Other = 0; return 2; // SETOLT | SETOEQ + case ISD::SETONE: Other = 0; return 1; // SETOLT | SETOGT } return 0; } @@ -726,7 +731,8 @@ } bool Inv; - unsigned Idx = getCRIdxForSetCC(CC, Inv); + int OtherCondIdx; + unsigned Idx = getCRIdxForSetCC(CC, Inv, OtherCondIdx); SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); SDOperand IntCR; @@ -737,7 +743,7 @@ CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), CR7Reg, CCReg, InFlag).getValue(1); - if (PPCSubTarget.isGigaProcessor()) + if (PPCSubTarget.isGigaProcessor() && OtherCondIdx == -1) IntCR = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg), 0); else @@ -745,13 +751,26 @@ SDOperand Ops[] = { IntCR, getI32Imm((32-(3-Idx)) & 31), getI32Imm(31), getI32Imm(31) }; - if (!Inv) { + if (OtherCondIdx == -1 && !Inv) return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); - } else { - SDOperand Tmp = - SDOperand(CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Ops, 4), 0); + + // Get the specified bit. + SDOperand Tmp = + SDOperand(CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Ops, 4), 0); + if (Inv) { + assert(OtherCondIdx == -1 && "Can't have split plus negation"); return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1)); } + + // Otherwise, we have to turn an operation like SETONE -> SETOLT | SETOGT. + // We already got the bit for the first part of the comparison (e.g. SETULE). + + // Get the other bit of the comparison. + Ops[1] = getI32Imm((32-(3-OtherCondIdx)) & 31); + SDOperand OtherCond = + SDOperand(CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Ops, 4), 0); + + return CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Tmp, OtherCond); } Modified: llvm/trunk/lib/Target/PowerPC/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/README.txt?rev=45742&r1=45741&r2=45742&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/README.txt (original) +++ llvm/trunk/lib/Target/PowerPC/README.txt Tue Jan 8 00:46:30 2008 @@ -706,3 +706,32 @@ //===---------------------------------------------------------------------===// +We compile some FP comparisons into an mfcr with two rlwinms and an or. For +example: +#include +int test(double x, double y) { return islessequal(x, y);} +int test2(double x, double y) { return islessgreater(x, y);} +int test3(double x, double y) { return !islessequal(x, y);} + +Compiles into (all three are similar, but the bits differ): + +_test: + fcmpu cr7, f1, f2 + mfcr r2 + rlwinm r3, r2, 29, 31, 31 + rlwinm r2, r2, 31, 31, 31 + or r3, r2, r3 + blr + +GCC compiles this into: + + _test: + fcmpu cr7,f1,f2 + cror 30,28,30 + mfcr r3 + rlwinm r3,r3,31,1 + blr + +which is more efficient and can use mfocr. See PR642 for some more context. + +//===---------------------------------------------------------------------===// Added: llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll?rev=45742&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll Tue Jan 8 00:46:30 2008 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | llc -march=ppc32 | grep or | count 3 +; This should produce one 'or' or 'cror' instruction per function. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i686-apple-darwin8" + +define i32 @test(double %x, double %y) nounwind { +entry: + %tmp3 = fcmp ole double %x, %y ; [#uses=1] + %tmp345 = zext i1 %tmp3 to i32 ; [#uses=1] + ret i32 %tmp345 +} + +define i32 @test2(double %x, double %y) nounwind { +entry: + %tmp3 = fcmp one double %x, %y ; [#uses=1] + %tmp345 = zext i1 %tmp3 to i32 ; [#uses=1] + ret i32 %tmp345 +} + +define i32 @test3(double %x, double %y) nounwind { +entry: + %tmp3 = fcmp ugt double %x, %y ; [#uses=1] + %tmp34 = zext i1 %tmp3 to i32 ; [#uses=1] + ret i32 %tmp34 +} + From sabre at nondot.org Tue Jan 8 00:52:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 06:52:51 -0000 Subject: [llvm-commits] [llvm] r45743 - /llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll Message-ID: <200801080652.m086qpQE015277@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 00:52:51 2008 New Revision: 45743 URL: http://llvm.org/viewvc/llvm-project?rev=45743&view=rev Log: remove darwin/i386 t-t Modified: llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll Modified: llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll?rev=45743&r1=45742&r2=45743&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/compare-fcmp-ord.ll Tue Jan 8 00:52:51 2008 @@ -1,9 +1,6 @@ ; RUN: llvm-as < %s | llc -march=ppc32 | grep or | count 3 ; This should produce one 'or' or 'cror' instruction per function. -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i686-apple-darwin8" - define i32 @test(double %x, double %y) nounwind { entry: %tmp3 = fcmp ole double %x, %y ; [#uses=1] From sabre at nondot.org Tue Jan 8 01:02:45 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 07:02:45 -0000 Subject: [llvm-commits] [llvm] r45744 - /llvm/trunk/include/llvm/Support/PatternMatch.h Message-ID: <200801080702.m0872jGU015919@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 01:02:44 2008 New Revision: 45744 URL: http://llvm.org/viewvc/llvm-project?rev=45744&view=rev Log: add match support for casts. Modified: llvm/trunk/include/llvm/Support/PatternMatch.h Modified: llvm/trunk/include/llvm/Support/PatternMatch.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PatternMatch.h?rev=45744&r1=45743&r2=45744&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PatternMatch.h (original) +++ llvm/trunk/include/llvm/Support/PatternMatch.h Tue Jan 8 01:02:44 2008 @@ -322,6 +322,30 @@ } //===----------------------------------------------------------------------===// +// Matchers for CastInst classes +// + +template +struct CastClass_match { + Op_t Op; + + CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {} + + template + bool match(OpTy *V) { + if (Class *I = dyn_cast(V)) + return Op.match(I->getOperand(0)); + return false; + } +}; + +template +inline CastClass_match m_Cast(const OpTy &Op) { + return CastClass_match(Op); +} + + +//===----------------------------------------------------------------------===// // Matchers for unary operators // From sabre at nondot.org Tue Jan 8 01:23:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 07:23:51 -0000 Subject: [llvm-commits] [llvm] r45745 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/add2.ll Message-ID: <200801080723.m087NpdG017027@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 01:23:51 2008 New Revision: 45745 URL: http://llvm.org/viewvc/llvm-project?rev=45745&view=rev Log: Implement PR1795, an instcombine hack for forming GEPs with integer pointer arithmetic. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/add2.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45745&r1=45744&r2=45745&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jan 8 01:23:51 2008 @@ -210,7 +210,7 @@ Instruction *visitUIToFP(CastInst &CI); Instruction *visitSIToFP(CastInst &CI); Instruction *visitPtrToInt(CastInst &CI); - Instruction *visitIntToPtr(CastInst &CI); + Instruction *visitIntToPtr(IntToPtrInst &CI); Instruction *visitBitCast(BitCastInst &CI); Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI); @@ -7148,8 +7148,58 @@ return commonPointerCastTransforms(CI); } -Instruction *InstCombiner::visitIntToPtr(CastInst &CI) { - return commonCastTransforms(CI); +Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) { + if (Instruction *I = commonCastTransforms(CI)) + return I; + + const Type *DestPointee = cast(CI.getType())->getElementType(); + if (!DestPointee->isSized()) return 0; + + // If this is inttoptr(add (ptrtoint x), cst), try to turn this into a GEP. + ConstantInt *Cst; + Value *X; + if (match(CI.getOperand(0), m_Add(m_Cast(m_Value(X)), + m_ConstantInt(Cst)))) { + // If the source and destination operands have the same type, see if this + // is a single-index GEP. + if (X->getType() == CI.getType()) { + // Get the size of the pointee type. + uint64_t Size = TD->getABITypeSizeInBits(DestPointee); + + // Convert the constant to intptr type. + APInt Offset = Cst->getValue(); + Offset.sextOrTrunc(TD->getPointerSizeInBits()); + + // If Offset is evenly divisible by Size, we can do this xform. + if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){ + Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size)); + return new GetElementPtrInst(X, ConstantInt::get(Offset)); + } + } + // TODO: Could handle other cases, e.g. where add is indexing into field of + // struct etc. + } else if (CI.getOperand(0)->hasOneUse() && + match(CI.getOperand(0), m_Add(m_Value(X), m_ConstantInt(Cst)))) { + // Otherwise, if this is inttoptr(add x, cst), try to turn this into an + // "inttoptr+GEP" instead of "add+intptr". + + // Get the size of the pointee type. + uint64_t Size = TD->getABITypeSize(DestPointee); + + // Convert the constant to intptr type. + APInt Offset = Cst->getValue(); + Offset.sextOrTrunc(TD->getPointerSizeInBits()); + + // If Offset is evenly divisible by Size, we can do this xform. + if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){ + Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size)); + + Instruction *P = InsertNewInstBefore(new IntToPtrInst(X, CI.getType(), + "tmp"), CI); + return new GetElementPtrInst(P, ConstantInt::get(Offset), "tmp"); + } + } + return 0; } Instruction *InstCombiner::visitBitCast(BitCastInst &CI) { Modified: llvm/trunk/test/Transforms/InstCombine/add2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add2.ll?rev=45745&r1=45744&r2=45745&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/add2.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/add2.ll Tue Jan 8 01:23:51 2008 @@ -1,6 +1,10 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \ ; RUN: grep -v OK | not grep add +;; Target triple for gep raising case below. +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i686-apple-darwin8" + define i64 @test1(i64 %A, i32 %B) { %tmp12 = zext i32 %B to i64 %tmp3 = shl i64 %tmp12, 32 @@ -9,3 +13,19 @@ ret i64 %tmp6 } +; PR1795 +define void @test2(i32 %.val24) { +EntryBlock: + add i32 %.val24, -12 + inttoptr i32 %0 to i32* + store i32 1, i32* %1 + add i32 %.val24, -16 + inttoptr i32 %2 to i32* + getelementptr i32* %3, i32 1 + load i32* %4 + tail call i32 @callee( i32 %5 ) + ret void +} + +declare i32 @callee(i32) + From duncan.sands at math.u-psud.fr Tue Jan 8 03:16:43 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Tue, 8 Jan 2008 10:16:43 +0100 Subject: [llvm-commits] [llvm-gcc-4.2] r45590 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-debug.cpp llvm-internal.h llvm-types.cpp In-Reply-To: <200801041809.m04I99we023420@zion.cs.uiuc.edu> References: <200801041809.m04I99we023420@zion.cs.uiuc.edu> Message-ID: <200801081016.44056.duncan.sands@math.u-psud.fr> > If a struct field is marked as a bitfield but > didn't need to be, treat it like an ordinary > field. The Ada front-end likes to mark fields > as bitfields preemptively, so this can occur > quite often for Ada. What is more, it can > mark non-integer fields as bitfields. In all > examples I came across so far, these non-integer > bitfields can be treated like ordinary fields. > With this patch, the Ada front-end builds (but > does not bootstrap)! It is true that the problem > of non-integer bitfields could be handled in the > Ada front-end, but since ignoring silly bitfields > seems like a good idea for all front-ends I chose > to solve it in the generic code. I forgot to mention the testcase: FrontendAda/non_bitfield.ads. Duncan. From baldrick at free.fr Tue Jan 8 04:06:26 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Jan 2008 10:06:26 -0000 Subject: [llvm-commits] [llvm] r45746 - in /llvm/trunk/lib/Target: PowerPC/PPCSubtarget.cpp X86/X86Subtarget.cpp Message-ID: <200801081006.m08A6VCG000571@zion.cs.uiuc.edu> Author: baldrick Date: Tue Jan 8 04:06:15 2008 New Revision: 45746 URL: http://llvm.org/viewvc/llvm-project?rev=45746&view=rev Log: Use size_t to store Pos, avoid truncating value on 64-bit builds. Analysis and original patch by T?r?k Edwin. Code audit found another place with the same problem, also fixed here. Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=45746&r1=45745&r2=45746&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Tue Jan 8 04:06:15 2008 @@ -103,7 +103,7 @@ const std::string &TT = M.getTargetTriple(); if (TT.length() > 7) { // Determine which version of darwin this is. - unsigned DarwinPos = TT.find("-darwin"); + size_t DarwinPos = TT.find("-darwin"); if (DarwinPos != std::string::npos) { if (isdigit(TT[DarwinPos+7])) DarwinVers = atoi(&TT[DarwinPos+7]); Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=45746&r1=45745&r2=45746&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Tue Jan 8 04:06:15 2008 @@ -257,7 +257,7 @@ // if one cannot be determined, to true. const std::string& TT = M.getTargetTriple(); if (TT.length() > 5) { - unsigned Pos; + size_t Pos; if ((Pos = TT.find("-darwin")) != std::string::npos) { TargetType = isDarwin; From sabre at nondot.org Tue Jan 8 12:05:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 18:05:21 -0000 Subject: [llvm-commits] [llvm] r45748 - in /llvm/trunk: include/llvm/Target/TargetInstrDesc.h utils/TableGen/CodeGenInstruction.cpp utils/TableGen/CodeGenInstruction.h utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200801081805.m08I5Lso024293@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 12:05:21 2008 New Revision: 45748 URL: http://llvm.org/viewvc/llvm-project?rev=45748&view=rev Log: add a mayLoad property for machine instructions, a correlary to mayStore. This is currently not set by anything. Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h llvm/trunk/utils/TableGen/CodeGenInstruction.cpp llvm/trunk/utils/TableGen/CodeGenInstruction.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=45748&r1=45747&r2=45748&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Tue Jan 8 12:05:21 2008 @@ -90,6 +90,7 @@ NotDuplicable, DelaySlot, SimpleLoad, + MayLoad, MayStore, NeverHasSideEffects, MayHaveSideEffects, @@ -308,6 +309,14 @@ //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// + + /// mayLoad - Return true if this instruction could possibly read memory. + /// Instructions with this flag set are not necessarily simple load + /// instructions, they may load a value and modify it, for example. + bool mayLoad() const { + return Flags & (1 << TID::MayLoad); + } + /// mayStore - Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store @@ -317,8 +326,6 @@ return Flags & (1 << TID::MayStore); } - // TODO: mayLoad. - /// hasNoSideEffects - Return true if all instances of this instruction are /// guaranteed to have no side effects other than: /// 1. The register operands that are def/used by the MachineInstr. Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=45748&r1=45747&r2=45748&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Tue Jan 8 12:05:21 2008 @@ -84,6 +84,7 @@ isBarrier = R->getValueAsBit("isBarrier"); isCall = R->getValueAsBit("isCall"); isSimpleLoad = R->getValueAsBit("isSimpleLoad"); + mayLoad = R->getValueAsBit("mayLoad"); mayStore = R->getValueAsBit("mayStore"); isImplicitDef= R->getValueAsBit("isImplicitDef"); bool isTwoAddress = R->getValueAsBit("isTwoAddress"); Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=45748&r1=45747&r2=45748&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Tue Jan 8 12:05:21 2008 @@ -90,7 +90,7 @@ bool isBarrier; bool isCall; bool isSimpleLoad; - bool mayStore; + bool mayLoad, mayStore; bool isImplicitDef; bool isPredicable; bool isConvertibleToThreeAddress; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45748&r1=45747&r2=45748&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Tue Jan 8 12:05:21 2008 @@ -144,12 +144,12 @@ class InstAnalyzer { const CodeGenDAGPatterns &CDP; bool &mayStore; - bool &isLoad; + bool &mayLoad; bool &NeverHasSideEffects; public: InstAnalyzer(const CodeGenDAGPatterns &cdp, - bool &maystore, bool &isload, bool &nhse) - : CDP(cdp), mayStore(maystore), isLoad(isload), NeverHasSideEffects(nhse) { + bool &maystore, bool &mayload, bool &nhse) + : CDP(cdp), mayStore(maystore), mayLoad(mayload), NeverHasSideEffects(nhse){ } void Analyze(Record *InstRecord) { @@ -166,9 +166,8 @@ private: void AnalyzeNode(const TreePatternNode *N) { - if (N->isLeaf()) { + if (N->isLeaf()) return; - } if (N->getOperator()->getName() != "set") { // Get information about the SDNode for the operator. @@ -191,11 +190,11 @@ }; void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst, - bool &mayStore, bool &isLoad, + bool &mayStore, bool &mayLoad, bool &NeverHasSideEffects) { - mayStore = isLoad = NeverHasSideEffects = false; + mayStore = mayLoad = NeverHasSideEffects = false; - InstAnalyzer(CDP, mayStore, isLoad, NeverHasSideEffects).Analyze(Inst.TheDef); + InstAnalyzer(CDP, mayStore, mayLoad,NeverHasSideEffects).Analyze(Inst.TheDef); // InstAnalyzer only correctly analyzes mayStore so far. if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it. @@ -210,7 +209,7 @@ } // These two override everything. - isLoad = Inst.isSimpleLoad; + mayLoad = Inst.mayLoad; NeverHasSideEffects = Inst.neverHasSideEffects; #if 0 @@ -281,8 +280,8 @@ const OperandInfoMapTy &OpInfo, std::ostream &OS) { // Determine properties of the instruction from its pattern. - bool mayStore, isSimpleLoad, NeverHasSideEffects; - InferFromPattern(Inst, mayStore, isSimpleLoad, NeverHasSideEffects); + bool mayStore, mayLoad, NeverHasSideEffects; + InferFromPattern(Inst, mayStore, mayLoad, NeverHasSideEffects); if (NeverHasSideEffects && Inst.mayHaveSideEffects) { std::cerr << "error: Instruction '" << Inst.TheDef->getName() @@ -308,7 +307,8 @@ if (Inst.isBarrier) OS << "|(1< Author: lattner Date: Tue Jan 8 12:21:54 2008 New Revision: 45751 URL: http://llvm.org/viewvc/llvm-project?rev=45751&view=rev Log: cleanups suggested by duncan, thanks Duncan! Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=45751&r1=45750&r2=45751&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Jan 8 12:21:54 2008 @@ -988,13 +988,13 @@ // next size power-of-two register (e.g. i64). This should be reevaluated // when we have good support for unusual sized integers in the code generator. if (Result && TREE_CODE(TREE_TYPE(exp)) == INTEGER_TYPE) { - unsigned LLVMWidth = cast(Result->getType())->getBitWidth(); + unsigned LLVMWidth = Result->getType()->getPrimitiveSizeInBits(); unsigned TreeWidth = TYPE_PRECISION(TREE_TYPE(exp)); if (LLVMWidth > TreeWidth && lang_hooks.reduce_bit_field_operations) { if (TYPE_UNSIGNED(TREE_TYPE(exp))) { // Use an 'and' to clear excess top bits. Constant *Mask = - ConstantInt::get(APInt::getLowBitsSet(LLVMWidth, TreeWidth)); + ConstantInt::get(APInt::getLowBitsSet(LLVMWidth, TreeWidth)); Result = Builder.CreateAnd(Result, Mask, "mask"); } else { // Shift Left then shift right. From kremenek at apple.com Tue Jan 8 13:38:58 2008 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 08 Jan 2008 19:38:58 -0000 Subject: [llvm-commits] [llvm] r45752 - /llvm/trunk/include/llvm/ADT/ImmutableMap.h Message-ID: <200801081938.m08Jcw94029643@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 8 13:38:55 2008 New Revision: 45752 URL: http://llvm.org/viewvc/llvm-project?rev=45752&view=rev Log: Fixed 80 col. violation. Modified: llvm/trunk/include/llvm/ADT/ImmutableMap.h Modified: llvm/trunk/include/llvm/ADT/ImmutableMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableMap.h?rev=45752&r1=45751&r2=45752&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableMap.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableMap.h Tue Jan 8 13:38:55 2008 @@ -76,7 +76,8 @@ ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); } ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) { - return ImmutableMap(F.Add(Old.Root,std::make_pair(K,D))); + return ImmutableMap(F.Add(Old.Root, + std::make_pair(K,D))); } ImmutableMap Remove(ImmutableMap Old, key_type_ref K) { From sabre at nondot.org Tue Jan 8 13:41:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 19:41:42 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r45753 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200801081941.m08JfgDc029770@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 13:41:42 2008 New Revision: 45753 URL: http://llvm.org/viewvc/llvm-project?rev=45753&view=rev Log: Cleanup suggested by Duncan, thanks! Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=45753&r1=45752&r2=45753&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Tue Jan 8 13:41:42 2008 @@ -946,7 +946,7 @@ // next size power-of-two register (e.g. i64). This should be reevaluated // when we have good support for unusual sized integers in the code generator. if (Result && TREE_CODE(TREE_TYPE(exp)) == INTEGER_TYPE) { - unsigned LLVMWidth = cast(Result->getType())->getBitWidth(); + unsigned LLVMWidth = Result->getType()->getPrimitiveSizeInBits(); unsigned TreeWidth = TYPE_PRECISION(TREE_TYPE(exp)); if (LLVMWidth > TreeWidth && lang_hooks.reduce_bit_field_operations) { if (TYPE_UNSIGNED(TREE_TYPE(exp))) { From sabre at nondot.org Tue Jan 8 15:00:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 21:00:46 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45754 - /llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Message-ID: <200801082100.m08L0kpm004674@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 15:00:44 2008 New Revision: 45754 URL: http://llvm.org/viewvc/llvm-project?rev=45754&view=rev Log: Fix the MMX related shift/rotate regressions (PR1902) Patch by Anders Carlsson, thanks! Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=45754&r1=45753&r2=45754&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Tue Jan 8 15:00:44 2008 @@ -79,7 +79,10 @@ case IX86_BUILTIN_PSLLWI: { Function *psllw = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psll_w); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psllw, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -97,7 +100,10 @@ case IX86_BUILTIN_PSLLDI: { Function *pslld = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psll_d); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(pslld, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -114,7 +120,10 @@ case IX86_BUILTIN_PSLLQI: { Function *psllq = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psll_q); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psllq, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -132,7 +141,10 @@ case IX86_BUILTIN_PSRLWI: { Function *psrlw = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psrl_w); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrlw, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -150,7 +162,10 @@ case IX86_BUILTIN_PSRLDI: { Function *psrld = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psrl_d); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrld, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -167,7 +182,10 @@ case IX86_BUILTIN_PSRLQI: { Function *psrlq = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psrl_q); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrlq, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -185,7 +203,10 @@ case IX86_BUILTIN_PSRAWI: { Function *psraw = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psra_w); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psraw, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -203,7 +224,10 @@ case IX86_BUILTIN_PSRADI: { Function *psrad = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psra_d); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrad, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; From sabre at nondot.org Tue Jan 8 15:01:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 21:01:08 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r45755 - /llvm-gcc-4.0/trunk/gcc/config/i386/llvm-i386.cpp Message-ID: <200801082101.m08L18oO004701@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 15:01:08 2008 New Revision: 45755 URL: http://llvm.org/viewvc/llvm-project?rev=45755&view=rev Log: Fix the MMX related shift/rotate regressions (PR1902) Patch by Anders Carlsson, thanks! Modified: llvm-gcc-4.0/trunk/gcc/config/i386/llvm-i386.cpp Modified: llvm-gcc-4.0/trunk/gcc/config/i386/llvm-i386.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/i386/llvm-i386.cpp?rev=45755&r1=45754&r2=45755&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/i386/llvm-i386.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/config/i386/llvm-i386.cpp Tue Jan 8 15:01:08 2008 @@ -79,7 +79,10 @@ case IX86_BUILTIN_PSLLWI: { Function *psllw = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psll_w); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psllw, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -96,7 +99,10 @@ case IX86_BUILTIN_PSLLDI: { Function *pslld = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psll_d); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(pslld, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -113,7 +119,10 @@ case IX86_BUILTIN_PSLLQI: { Function *psllq = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psll_q); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psllq, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -130,7 +139,10 @@ case IX86_BUILTIN_PSRLWI: { Function *psrlw = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psrl_w); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrlw, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -147,7 +159,10 @@ case IX86_BUILTIN_PSRLDI: { Function *psrld = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psrl_d); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrld, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -164,7 +179,10 @@ case IX86_BUILTIN_PSRLQI: { Function *psrlq = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psrl_q); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrlq, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -181,7 +199,10 @@ case IX86_BUILTIN_PSRAWI: { Function *psraw = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psra_w); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psraw, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; @@ -198,7 +219,10 @@ case IX86_BUILTIN_PSRADI: { Function *psrad = Intrinsic::getDeclaration(TheModule, Intrinsic::x86_mmx_psra_d); - Ops[1] = BuildVector(Ops[1], UndefValue::get(Type::Int32Ty), NULL); + Ops[1] = Builder.CreateZExt(Ops[1], Type::Int64Ty, "zext"); + Ops[1] = Builder.CreateBitCast(Ops[1], + VectorType::get(Type::Int64Ty, 1), + "bitcast"); Result = Builder.CreateCall(psrad, Ops.begin(), Ops.begin()+2, "tmp"); Result = Builder.CreateBitCast(Result, ResultType, "tmp"); return true; From kremenek at apple.com Tue Jan 8 15:05:59 2008 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 08 Jan 2008 21:05:59 -0000 Subject: [llvm-commits] [llvm] r45756 - /llvm/trunk/include/llvm/ADT/ImmutableMap.h Message-ID: <200801082105.m08L5xlD004990@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 8 15:05:59 2008 New Revision: 45756 URL: http://llvm.org/viewvc/llvm-project?rev=45756&view=rev Log: Added "getRoot()" to ImmutableMap. Made the ctor for ImmutableMap to construct a map from an AVL tree public. Modified: llvm/trunk/include/llvm/ADT/ImmutableMap.h Modified: llvm/trunk/include/llvm/ADT/ImmutableMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableMap.h?rev=45756&r1=45755&r2=45756&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableMap.h (original) +++ llvm/trunk/include/llvm/ADT/ImmutableMap.h Tue Jan 8 15:05:59 2008 @@ -52,20 +52,24 @@ template > class ImmutableMap { +public: typedef typename ValInfo::value_type value_type; typedef typename ValInfo::value_type_ref value_type_ref; typedef typename ValInfo::key_type key_type; typedef typename ValInfo::key_type_ref key_type_ref; typedef typename ValInfo::data_type data_type; typedef typename ValInfo::data_type_ref data_type_ref; + typedef ImutAVLTree TreeTy; -private: - typedef ImutAVLTree TreeTy; +private: TreeTy* Root; - - ImmutableMap(TreeTy* R) : Root(R) {} - + public: + /// Constructs a map from a pointer to a tree root. In general one + /// should use a Factory object to create maps instead of directly + /// invoking the constructor, but there are cases where make this + /// constructor public is useful. + explicit ImmutableMap(TreeTy* R) : Root(R) {} class Factory { typename TreeTy::Factory F; @@ -112,6 +116,8 @@ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; } + TreeTy* getRoot() const { return Root; } + bool isEmpty() const { return !Root; } //===--------------------------------------------------===// From dalej at apple.com Tue Jan 8 15:08:57 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 08 Jan 2008 21:08:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h Message-ID: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> Author: johannes Date: Tue Jan 8 15:08:57 2008 New Revision: 45757 URL: http://llvm.org/viewvc/llvm-project?rev=45757&view=rev Log: Fix gcc->llvm translation for virtual base classes. pr1746 Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp llvm-gcc-4.2/trunk/gcc/tree.c llvm-gcc-4.2/trunk/gcc/tree.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=45757&r1=45756&r2=45757&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Tue Jan 8 15:08:57 2008 @@ -1614,6 +1614,129 @@ } +/// Mapping from type to type-used-as-base-class and back. +static DenseMap BaseTypesMap; + +/// FixBaseClassField - This method is called when we have a field Field +/// of Record type within a Record, and the size of Field is smaller than the +/// size of its Record type. This may indicate the situation where a base class +/// has virtual base classes which are not allocated. Replace Field's original +/// type with a modified one reflecting what actually gets allocated. +/// +/// This can also occur when a class has an empty base class; the class will +/// have size N+4 and the field size N+1. In this case the fields will add +/// up to N+4, so we haven't really changed anything. + +static tree FixBaseClassField(tree Field) { + tree oldTy = TREE_TYPE(Field); + tree &newTy = BaseTypesMap[oldTy]; + // If already in table, reuse. + if (!newTy) { + newTy = copy_node(oldTy); + tree F2 = 0, prevF2 = 0; + // Copy the fields up to the TYPE_DECL separator. + // VAR_DECLs can also appear, representing static members. Possibly some + // other junk I haven't hit yet, just skip anything that's not a FIELD:( + for (tree F = TYPE_FIELDS(oldTy); F; prevF2 = F2, F = TREE_CHAIN(F)) { + if (TREE_CODE(F) == TYPE_DECL) + break; + if (TREE_CODE(F) == FIELD_DECL) { + F2 = copy_node(F); + if (prevF2) + TREE_CHAIN(prevF2) = F2; + else + TYPE_FIELDS(newTy) = F2; + TREE_CHAIN(F2) = 0; + } + } + BaseTypesMap[oldTy] = newTy; + BaseTypesMap[newTy] = oldTy; + /* Prevent gcc's garbage collector from destroying newTy. The + GC code doesn't understand DenseMaps:( */ + llvm_note_type_used(newTy); + TYPE_SIZE(newTy) = DECL_SIZE(Field); + TYPE_SIZE_UNIT(newTy) = DECL_SIZE_UNIT(Field); + TYPE_MAIN_VARIANT(newTy) = newTy; + // Change the name. + if (TYPE_NAME(oldTy)) { + const char *p = "anon"; + if (TREE_CODE(TYPE_NAME(oldTy)) ==IDENTIFIER_NODE) + p = IDENTIFIER_POINTER(TYPE_NAME(oldTy)); + else if (DECL_NAME(TYPE_NAME(oldTy))) + p = IDENTIFIER_POINTER(DECL_NAME(TYPE_NAME(oldTy))); + char *q = (char *)xmalloc(strlen(p)+6); + strcpy(q,p); + strcat(q,".base"); + TYPE_NAME(newTy) = get_identifier(q); + free(q); + } + } + return newTy; +} + +/// FixBaseClassFields - alter the types referred to by Field nodes that +/// represent base classes to reflect reality. +// +// Suppose we're converting type T. Look for the case where a base class A +// of T contains a virtual base class B, and B is not allocated when A is +// used as the base class of T. This is indicated by the FIELD node for A +// having a size smaller than the size of A, and the chain of fields for A +// having a TYPE_DECL node in the middle of it; that node comes after the +// allocated fields and before the unallocated virtual base classes. Create +// a new type A.base for LLVM purposes which does not contain the virtual +// base classes. (Where A is a virtual base class of T, there is also a BINFO +// node for it, but not when A is a nonvirtual base class. So we can't +// use that.) +static void FixBaseClassFields(tree type) { + assert(TREE_CODE(type)==RECORD_TYPE); + for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) { + if (TREE_CODE(Field)==FIELD_DECL && + !DECL_BIT_FIELD_TYPE(Field) && + TREE_CODE(DECL_FIELD_OFFSET(Field))==INTEGER_CST && + TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE && + TYPE_SIZE(TREE_TYPE(Field)) && + DECL_SIZE(Field) && + TREE_INT_CST_LOW(DECL_SIZE(Field)) < + TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) + TREE_TYPE(Field) = FixBaseClassField(Field); + } + // Size of the complete type will be a multiple of its alignment. + // In some cases involving empty C++ classes this is not true coming in. + // Earlier, the sizes in the field types were also wrong in a way that + // compensated as far as LLVM's translation code is concerned; now we + // have fixed that, and have to fix the size also. + if (TYPE_SIZE (type) && TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST) { + TYPE_SIZE(type) = build_int_cst( + TREE_TYPE(TYPE_SIZE(type)), + (TREE_INT_CST_LOW(TYPE_SIZE(type))+TYPE_ALIGN(type)-1) & + ~(TYPE_ALIGN(type)-1)); + TYPE_SIZE_UNIT(type) = build_int_cst( + TREE_TYPE(TYPE_SIZE_UNIT(type)), + (TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type))+TYPE_ALIGN_UNIT(type)-1) & + ~(TYPE_ALIGN_UNIT(type)-1)); + } +} + +// RestoreBaseClassFields - put things back the way they were so the C++FE +// code continues to work (there are pointers stashed away in there). + +static void RestoreBaseClassFields(tree type) { + assert(TREE_CODE(type)==RECORD_TYPE); + for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) { + if (TREE_CODE(Field)==FIELD_DECL && + !DECL_BIT_FIELD_TYPE(Field) && + TREE_CODE(DECL_FIELD_OFFSET(Field))==INTEGER_CST && + TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE && + TYPE_SIZE(TREE_TYPE(Field)) && + DECL_SIZE(Field)) { + tree &oldTy = BaseTypesMap[TREE_TYPE(Field)]; + if (oldTy) + TREE_TYPE(Field) = oldTy; + } + } +} + + /// DecodeStructFields - This method decodes the specified field, if it is a /// FIELD_DECL, adding or updating the specified StructTypeConversionInfo to @@ -1794,7 +1917,11 @@ // TYPE_DECL node sitting in the middle of the FIELD list separating virtual // base classes from everything else. // -// For LLVM purposes, we probably need to build a new type for B-within-D that +// Similarly, a nonvirtual base class which has virtual base classes might +// not contain those virtual base classes when used as a nonvirtual base class. +// There is seemingly no way to detect this except for the size differential. +// +// For LLVM purposes, we build a new type for B-within-D that // has the correct size and layout for that usage. const Type *TypeConverter::ConvertRECORD(tree type, tree orig_type) { @@ -1815,18 +1942,14 @@ bool OldConvertingStruct = ConvertingStruct; ConvertingStruct = true; - // Construct LLVM types for the base types... in order to get names for - // base classes and to ensure they are laid out. - if (tree binfo = TYPE_BINFO(type)) { - for (unsigned i = 0, e = BINFO_N_BASE_BINFOS(binfo); i != e; ++i) - ConvertType(BINFO_TYPE(BINFO_BASE_BINFO(binfo, i))); - } - StructTypeConversionInfo *Info = new StructTypeConversionInfo(*TheTarget, TYPE_ALIGN_UNIT(type), TYPE_PACKED(type)); + + // Alter any fields that appear to represent base classes so their lists + // of fields bear some resemblance to reality. + FixBaseClassFields(type); - // Convert over all of the elements of the struct. for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) DecodeStructFields(Field, *Info); @@ -1906,7 +2029,11 @@ Info->getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField); SetFieldIndex(Field, FieldNo); } - + + // Put the original gcc struct back the way it was; necessary to prevent the + // binfo-walking code in cp/class from getting confused. + RestoreBaseClassFields(type); + const Type *ResultTy = Info->getLLVMType(); StructTypeInfoMap[ResultTy] = Info; Modified: llvm-gcc-4.2/trunk/gcc/tree.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.c?rev=45757&r1=45756&r2=45757&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree.c Tue Jan 8 15:08:57 2008 @@ -7902,4 +7902,16 @@ } /* APPLE LOCAL end CW asm blocks */ +/* LLVM LOCAL begin */ +/* This data structure keeps gcc's garbage collector from + deleting types created by the llvm virtual base class handling + stuff in llvm-types.cpp. */ +static GTY(()) VEC(tree,gc) *llvm_types_used; + +void +llvm_note_type_used(tree type) +{ + VEC_safe_push(tree, gc, llvm_types_used, type); +} +/* LLVM LOCAL end */ #include "gt-tree.h" Modified: llvm-gcc-4.2/trunk/gcc/tree.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.h?rev=45757&r1=45756&r2=45757&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree.h (original) +++ llvm-gcc-4.2/trunk/gcc/tree.h Tue Jan 8 15:08:57 2008 @@ -4318,6 +4318,8 @@ extern tree lower_bound_in_type (tree, tree); extern int operand_equal_for_phi_arg_p (tree, tree); extern bool empty_body_p (tree); +/* LLVM LOCAL */ +extern void llvm_note_type_used(tree); /* In stmt.c */ From baldrick at free.fr Tue Jan 8 15:51:53 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Jan 2008 21:51:53 -0000 Subject: [llvm-commits] [llvm] r45758 - /llvm/trunk/test/CodeGen/X86/2008-01-08-IllegalCMP.ll Message-ID: <200801082151.m08LprTN007877@zion.cs.uiuc.edu> Author: baldrick Date: Tue Jan 8 15:51:53 2008 New Revision: 45758 URL: http://llvm.org/viewvc/llvm-project?rev=45758&view=rev Log: Crashes llc when using Chris's new legalization logic. Added: llvm/trunk/test/CodeGen/X86/2008-01-08-IllegalCMP.ll Added: llvm/trunk/test/CodeGen/X86/2008-01-08-IllegalCMP.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-01-08-IllegalCMP.ll?rev=45758&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-01-08-IllegalCMP.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-01-08-IllegalCMP.ll Tue Jan 8 15:51:53 2008 @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llc + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define i64 @__absvdi2(i64 %a) nounwind { +entry: + %w.0 = select i1 false, i64 0, i64 %a ; [#uses=2] + %tmp9 = icmp slt i64 %w.0, 0 ; [#uses=1] + br i1 %tmp9, label %bb12, label %bb13 + +bb12: ; preds = %entry + unreachable + +bb13: ; preds = %entry + ret i64 %w.0 +} From resistor at mac.com Tue Jan 8 15:54:55 2008 From: resistor at mac.com (Owen Anderson) Date: Tue, 08 Jan 2008 21:54:55 -0000 Subject: [llvm-commits] [llvm] r45759 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801082154.m08LsuC8008031@zion.cs.uiuc.edu> Author: resistor Date: Tue Jan 8 15:54:52 2008 New Revision: 45759 URL: http://llvm.org/viewvc/llvm-project?rev=45759&view=rev Log: Rename registers that do not need copies. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45759&r1=45758&r2=45759&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Jan 8 15:54:52 2008 @@ -44,6 +44,7 @@ std::map > Stacks; std::set UsedByAnother; + std::map > RenameSets; bool runOnMachineFunction(MachineFunction &Fn); @@ -442,7 +443,8 @@ } } - // FIXME: Cache renaming information + // Cache renaming information + RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), PHIUnion)); ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end()); ++P; @@ -649,8 +651,22 @@ // FIXME: This process should probably preserve LiveVariables InsertCopies(Fn.begin()); - // FIXME: Perform renaming - // FIXME: Remove Phi instrs + // Perform renaming + typedef std::map > RenameSetType; + for (RenameSetType::iterator I = RenameSets.begin(), E = RenameSets.end(); + I != E; ++I) + for (std::set::iterator SI = I->second.begin(), + SE = I->second.end(); SI != SE; ++SI) + Fn.getRegInfo().replaceRegWith(*SI, I->first); + + // FIXME: Insert last-minute copies + + // Remove PHIs + for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) + for (MachineBasicBlock::iterator BI = I->begin(), BE = I->end(); + BI != BE; ++BI) + if (BI->getOpcode() == TargetInstrInfo::PHI) + BI->eraseFromParent(); return false; } From evan.cheng at apple.com Tue Jan 8 16:24:46 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 8 Jan 2008 14:24:46 -0800 Subject: [llvm-commits] [llvm] r45687 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/MachineInstr.cpp lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/Target/X86/X86CodeEmitter.cpp utils/TableGen/CodeGenInstruction.cpp utils/TableGen/CodeGenInstruction.h utils/TableGen/DAGISelEmitter.cpp utils/TableGen/InstrInfoEmitter.cpp In-Reply-To: <200801070519.m075JYxD029332@zion.cs.uiuc.edu> References: <200801070519.m075JYxD029332@zion.cs.uiuc.edu> Message-ID: <8844C523-76F6-4240-B657-884BEACF21F2@apple.com> Comments are accurate. Thx! Evan On Jan 6, 2008, at 9:19 PM, Chris Lattner wrote: > Author: lattner > Date: Sun Jan 6 23:19:29 2008 > New Revision: 45687 > > URL: http://llvm.org/viewvc/llvm-project?rev=45687&view=rev > Log: > rename hasVariableOperands() -> isVariadic(). Add some comments. > Evan, please review the comments I added to getNumDefs to make sure > that they are accurate, thx. > > Modified: > llvm/trunk/include/llvm/Target/TargetInstrInfo.h > llvm/trunk/lib/CodeGen/MachineInstr.cpp > llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp > llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp > llvm/trunk/utils/TableGen/CodeGenInstruction.cpp > llvm/trunk/utils/TableGen/CodeGenInstruction.h > llvm/trunk/utils/TableGen/DAGISelEmitter.cpp > llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp > > Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Sun Jan 6 > 23:19:29 2008 > @@ -125,9 +125,7 @@ > // block. > const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 12; > > -// M_VARIABLE_OPS - Set if this instruction can have a variable > number of extra > -// operands in addition to the minimum number operands specified. > -const unsigned M_VARIABLE_OPS = 1 << 13; > +const unsigned M_VARIADIC = 1 << 13; > > // M_PREDICABLE - Set if this instruction has a predicate operand that > // controls execution. It may be set to 'always'. > @@ -141,8 +139,6 @@ > // (e.g. instructions with unique labels attached). > const unsigned M_NOT_DUPLICABLE = 1 << 16; > > -// M_HAS_OPTIONAL_DEF - Set if this instruction has an optional > definition, e.g. > -// ARM instructions which can set condition code if 's' bit is set. > const unsigned M_HAS_OPTIONAL_DEF = 1 << 17; > > // M_NEVER_HAS_SIDE_EFFECTS - Set if this instruction has no side > effects that > @@ -182,7 +178,7 @@ > /// it is set. Returns -1 if it is not set. > int getOperandConstraint(unsigned OpNum, > TOI::OperandConstraint Constraint) const { > - assert((OpNum < NumOperands || hasVariableOperands()) && > + assert((OpNum < NumOperands || isVariadic()) && > "Invalid operand # of TargetInstrInfo"); > if (OpNum < NumOperands && > (OpInfo[OpNum].Constraints & (1 << Constraint))) { > @@ -202,18 +198,32 @@ > return Name; > } > > + /// getNumOperands - Return the number of declared > MachineOperands for this > + /// MachineInstruction. Note that variadic (isVariadic() returns > true) > + /// instructions may have additional operands at the end of the > list, and note > + /// that the machine instruction may include implicit register > def/uses as > + /// well. > unsigned getNumOperands() const { > return NumOperands; > } > > + /// getNumDefs - Return the number of MachineOperands that are > register > + /// definitions. Register definitions always occur at the start > of the > + /// machine operand list. This is the number of "outs" in > the .td file. > unsigned getNumDefs() const { > return NumDefs; > } > > - bool hasVariableOperands() const { > - return Flags & M_VARIABLE_OPS; > + /// isVariadic - Return true if this instruction can have a > variable number of > + /// operands. In this case, the variable operands will be after > the normal > + /// operands but before the implicit definitions and uses (if any > are > + /// present). > + bool isVariadic() const { > + return Flags & M_VARIADIC; > } > > + /// hasOptionalDef - Set if this instruction has an optional > definition, e.g. > + /// ARM instructions which can set condition code if 's' bit is > set. > bool hasOptionalDef() const { > return Flags & M_HAS_OPTIONAL_DEF; > } > > Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) > +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Sun Jan 6 23:19:29 2008 > @@ -488,8 +488,7 @@ > /// > bool MachineInstr::OperandsComplete() const { > unsigned short NumOperands = TID->getNumOperands(); > - if (TID->hasVariableOperands() == 0 && > - getNumOperands()-NumImplicitOps >= NumOperands) > + if (!TID->isVariadic() && getNumOperands()-NumImplicitOps >= > NumOperands) > return true; // Broken: we have all the operands of this > instruction! > return false; > } > @@ -498,7 +497,7 @@ > /// > unsigned MachineInstr::getNumExplicitOperands() const { > unsigned NumOperands = TID->getNumOperands(); > - if (TID->hasVariableOperands() == 0) > + if (!TID->isVariadic()) > return NumOperands; > > for (unsigned e = getNumOperands(); NumOperands != e; + > +NumOperands) { > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sun Jan 6 > 23:19:29 2008 > @@ -294,7 +294,7 @@ > const TargetInstrDescriptor *II, > unsigned Op) { > if (Op >= II->getNumOperands()) { > - assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of > instruction"); > + assert(II->isVariadic() && "Invalid operand # of instruction"); > return NULL; > } > if (II->OpInfo[Op].isLookupPtrRegClass()) > @@ -678,7 +678,7 @@ > II.getImplicitDefs() != 0; > #ifndef NDEBUG > assert((II.getNumOperands() == NumMIOperands || > - HasPhysRegOuts || II.hasVariableOperands()) && > + HasPhysRegOuts || II.isVariadic()) && > "#operands for dag node doesn't match .td file!"); > #endif > > > Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Sun Jan 6 23:19:29 > 2008 > @@ -799,6 +799,5 @@ > break; > } > > - assert((Desc->Flags & M_VARIABLE_OPS) != 0 || > - CurOp == NumOps && "Unknown encoding!"); > + assert((Desc->isVariadic() || CurOp == NumOps) && "Unknown > encoding!"); > } > > Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original) > +++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Sun Jan 6 > 23:19:29 2008 > @@ -99,7 +99,7 @@ > mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); > neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); > hasOptionalDef = false; > - hasVariableNumberOfOperands = false; > + isVariadic = false; > > if (mayHaveSideEffects && neverHasSideEffects) > throw R->getName() + > @@ -159,7 +159,7 @@ > else if (Rec->isSubClassOf("OptionalDefOperand")) > hasOptionalDef = true; > } else if (Rec->getName() == "variable_ops") { > - hasVariableNumberOfOperands = true; > + isVariadic = true; > continue; > } else if (!Rec->isSubClassOf("RegisterClass") && > Rec->getName() != "ptr_rc") > > Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original) > +++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Sun Jan 6 > 23:19:29 2008 > @@ -99,7 +99,7 @@ > bool isReMaterializable; > bool hasDelaySlot; > bool usesCustomDAGSchedInserter; > - bool hasVariableNumberOfOperands; > + bool isVariadic; > bool hasCtrlDep; > bool isNotDuplicable; > bool hasOptionalDef; > > Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Sun Jan 6 23:19:29 > 2008 > @@ -835,7 +835,7 @@ > if (InstPatNode && InstPatNode->getOperator()->getName() == > "set") { > InstPatNode = InstPatNode->getChild(InstPatNode- > >getNumChildren()-1); > } > - bool HasVarOps = isRoot && II.hasVariableNumberOfOperands; > + bool HasVarOps = isRoot && II.isVariadic; > // FIXME: fix how we deal with physical register operands. > bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0; > bool HasImpResults = isRoot && DstRegs.size() > 0; > > Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45687&r1=45686&r2=45687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Sun Jan 6 > 23:19:29 2008 > @@ -320,9 +320,9 @@ > if (Inst.hasOptionalDef) OS << "|M_HAS_OPTIONAL_DEF"; > if (Inst.usesCustomDAGSchedInserter) > OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION"; > - if (Inst.hasVariableNumberOfOperands) OS << "|M_VARIABLE_OPS"; > - if (Inst.mayHaveSideEffects) OS << "| > M_MAY_HAVE_SIDE_EFFECTS"; > - if (NeverHasSideEffects) OS << "| > M_NEVER_HAS_SIDE_EFFECTS"; > + if (Inst.isVariadic) OS << "|M_VARIADIC"; > + if (Inst.mayHaveSideEffects) OS << "|M_MAY_HAVE_SIDE_EFFECTS"; > + if (NeverHasSideEffects) OS << "|M_NEVER_HAS_SIDE_EFFECTS"; > OS << ", 0"; > > // Emit all of the target-specific flags... > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Jan 8 16:26:20 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 8 Jan 2008 14:26:20 -0800 Subject: [llvm-commits] [llvm] r45027 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/VMCore/AutoUpgrade.cpp test/Assembler/AutoUpgradeIntrinsics.ll In-Reply-To: References: <200712140638.lBE6csKG028926@zion.cs.uiuc.edu> Message-ID: <0E704CE2-66B4-44F5-B59B-806BF25DE473@apple.com> It looks ok. But please add test cases that cover more than one of these intrinsics please. Evan On Jan 6, 2008, at 4:35 AM, Bill Wendling wrote: > Here's a potential patch as a follow-up for this patch: > > > > It's not tested (I got a compiler error during compilation of > LLVM...not LLVM-GCC). What do you think? > > -bw > > On Dec 13, 2007, at 10:38 PM, Anders Carlsson wrote: > >> Author: andersca >> Date: Fri Dec 14 00:38:54 2007 >> New Revision: 45027 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45027&view=rev >> Log: >> All MMX shift instructions took a <2 x i32> vector as the shift >> amount parameter. Change this to be <1 x i64> instead, which >> matches the assembler instruction. >> >> Modified: >> llvm/trunk/include/llvm/IntrinsicsX86.td >> llvm/trunk/lib/VMCore/AutoUpgrade.cpp >> llvm/trunk/test/Assembler/AutoUpgradeIntrinsics.ll >> >> Modified: llvm/trunk/include/llvm/IntrinsicsX86.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=45027&r1=45026&r2=45027&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) >> +++ llvm/trunk/include/llvm/IntrinsicsX86.td Fri Dec 14 00:38:54 2007 >> @@ -767,30 +767,30 @@ >> // Shift left logical >> def int_x86_mmx_psll_w : GCCBuiltin<"__builtin_ia32_psllw">, >> Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> def int_x86_mmx_psll_d : GCCBuiltin<"__builtin_ia32_pslld">, >> Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> def int_x86_mmx_psll_q : GCCBuiltin<"__builtin_ia32_psllq">, >> Intrinsic<[llvm_v1i64_ty, llvm_v1i64_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> >> def int_x86_mmx_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw">, >> Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> def int_x86_mmx_psrl_d : GCCBuiltin<"__builtin_ia32_psrld">, >> Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> def int_x86_mmx_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq">, >> Intrinsic<[llvm_v1i64_ty, llvm_v1i64_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> >> def int_x86_mmx_psra_w : GCCBuiltin<"__builtin_ia32_psraw">, >> Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> def int_x86_mmx_psra_d : GCCBuiltin<"__builtin_ia32_psrad">, >> Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty, >> - llvm_v2i32_ty], [IntrNoMem]>; >> + llvm_v1i64_ty], [IntrNoMem]>; >> } >> >> // Pack ops. >> >> Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AutoUpgrade.cpp?rev=45027&r1=45026&r2=45027&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) >> +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Fri Dec 14 00:38:54 2007 >> @@ -12,6 +12,7 @@ >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> >> #include "llvm/AutoUpgrade.h" >> +#include "llvm/Constants.h" >> #include "llvm/Function.h" >> #include "llvm/Module.h" >> #include "llvm/Instructions.h" >> @@ -110,6 +111,39 @@ >> } >> >> break; >> + case 'x': >> + // This fixes all MMX shift intrinsic instructions to take a >> + // v1i64 instead of a v2i32 as the second parameter. >> + if (Name.compare(5,10,"x86.mmx.ps",10) == 0 && >> + (Name.compare(13,4,"psll", 4) == 0 || >> + Name.compare(13,4,"psra", 4) == 0 || >> + Name.compare(13,4,"psrl", 4) == 0)) { >> + >> + const llvm::Type *VT = VectorType::get(IntegerType::get(64), >> 1); >> + >> + // We don't have to do anything if the parameter already has >> + // the correct type. >> + if (FTy->getParamType(1) == VT) >> + break; >> + >> + // We first need to change the name of the old (bad) >> intrinsic, because >> + // its type is incorrect, but we cannot overload that name. >> We >> + // arbitrarily unique it here allowing us to construct a >> correctly named >> + // and typed function below. >> + F->setName(""); >> + >> + assert(FTy->getNumParams() == 2 && "MMX shift intrinsics >> take 2 args!"); >> + >> + // Now construct the new intrinsic with the correct name >> and type. We >> + // leave the old function around in order to query its >> type, whatever it >> + // may be, and correctly convert up to the new type. >> + return cast(M->getOrInsertFunction(Name, >> + FTy- >> >getReturnType(), >> + FTy- >> >getParamType(0), >> + VT, >> + (Type *)0)); >> + } >> + break; >> } >> >> // This may not belong here. This function is effectively being >> overloaded >> @@ -141,6 +175,40 @@ >> >> switch(NewFn->getIntrinsicID()) { >> default: assert(0 && "Unknown function for CallInst upgrade."); >> + case Intrinsic::x86_mmx_psll_d: >> + case Intrinsic::x86_mmx_psll_q: >> + case Intrinsic::x86_mmx_psll_w: >> + case Intrinsic::x86_mmx_psra_d: >> + case Intrinsic::x86_mmx_psra_w: >> + case Intrinsic::x86_mmx_psrl_d: >> + case Intrinsic::x86_mmx_psrl_q: >> + case Intrinsic::x86_mmx_psrl_w: { >> + SmallVector Operands; >> + >> + Operands.push_back(CI->getOperand(1)); >> + >> + // Cast the second parameter to the correct type. >> + BitCastInst *BC = new BitCastInst(CI->getOperand(2), >> + NewFn->getFunctionType()- >> >getParamType(1), >> + "upgraded", CI); >> + Operands.push_back(BC); >> + >> + // Construct a new CallInst >> + CallInst *NewCI = new CallInst(NewFn, Operands.begin(), >> Operands.end(), >> + "upgraded."+CI->getName(), CI); >> + NewCI->setTailCall(CI->isTailCall()); >> + NewCI->setCallingConv(CI->getCallingConv()); >> + >> + // Handle any uses of the old CallInst. >> + if (!CI->use_empty()) >> + // Replace all uses of the old call with the new cast which >> has the >> + // correct type. >> + CI->replaceAllUsesWith(NewCI); >> + >> + // Clean up the old call now that it has been completely >> upgraded. >> + CI->eraseFromParent(); >> + break; >> + } >> case Intrinsic::ctlz: >> case Intrinsic::ctpop: >> case Intrinsic::cttz: >> >> Modified: llvm/trunk/test/Assembler/AutoUpgradeIntrinsics.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/AutoUpgradeIntrinsics.ll?rev=45027&r1=45026&r2=45027&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/Assembler/AutoUpgradeIntrinsics.ll (original) >> +++ llvm/trunk/test/Assembler/AutoUpgradeIntrinsics.ll Fri Dec 14 >> 00:38:54 2007 >> @@ -6,6 +6,8 @@ >> ; RUN: not grep {llvm\\.part\\.select\\.i\[0-9\]*\\.i\[0-9\]*} >> ; RUN: llvm-as < %s | llvm-dis | \ >> ; RUN: not grep {llvm\\.bswap\\.i\[0-9\]*\\.i\[0-9\]*} >> +; RUN: llvm-as < %s | llvm-dis | \ >> +; RUN: grep {llvm\\.x86\\.mmx\\.ps} | grep {2 x i32> | count 6 >> >> declare i32 @llvm.ctpop.i28(i28 %val) >> declare i32 @llvm.cttz.i29(i29 %val) >> @@ -50,3 +52,30 @@ >> ret i32 %d >> } >> >> +declare <4 x i16> @llvm.x86.mmx.psra.w(<4 x i16>, <2 x i32>) >> nounwind readnone >> +declare <4 x i16> @llvm.x86.mmx.psll.w(<4 x i16>, <2 x i32>) >> nounwind readnone >> +declare <4 x i16> @llvm.x86.mmx.psrl.w(<4 x i16>, <2 x i32>) >> nounwind readnone >> +define void @sh16(<4 x i16> %A, <2 x i32> %B) { >> + %r1 = call <4 x i16> @llvm.x86.mmx.psra.w( <4 x i16> %A, <2 x >> i32> %B ) ; <<4 x i16>> [#uses=0] >> + %r2 = call <4 x i16> @llvm.x86.mmx.psll.w( <4 x i16> %A, <2 x >> i32> %B ) ; <<4 x i16>> [#uses=0] >> + %r3 = call <4 x i16> @llvm.x86.mmx.psrl.w( <4 x i16> %A, <2 x >> i32> %B ) ; <<4 x i16>> [#uses=0] >> + ret void >> +} >> + >> +declare <2 x i32> @llvm.x86.mmx.psra.d(<2 x i32>, <2 x i32>) >> nounwind readnone >> +declare <2 x i32> @llvm.x86.mmx.psll.d(<2 x i32>, <2 x i32>) >> nounwind readnone >> +declare <2 x i32> @llvm.x86.mmx.psrl.d(<2 x i32>, <2 x i32>) >> nounwind readnone >> +define void @sh32(<2 x i32> %A, <2 x i32> %B) { >> + %r1 = call <2 x i32> @llvm.x86.mmx.psra.d( <2 x i32> %A, <2 x >> i32> %B ) ; <<2 x i32>> [#uses=0] >> + %r2 = call <2 x i32> @llvm.x86.mmx.psll.d( <2 x i32> %A, <2 x >> i32> %B ) ; <<2 x i32>> [#uses=0] >> + %r3 = call <2 x i32> @llvm.x86.mmx.psrl.d( <2 x i32> %A, <2 x >> i32> %B ) ; <<2 x i32>> [#uses=0] >> + ret void >> +} >> + >> +declare <1 x i64> @llvm.x86.mmx.psll.q(<1 x i64>, <2 x i32>) >> nounwind readnone >> +declare <1 x i64> @llvm.x86.mmx.psrl.q(<1 x i64>, <2 x i32>) >> nounwind readnone >> +define void @sh64(<1 x i64> %A, <2 x i32> %B) { >> + %r1 = call <1 x i64> @llvm.x86.mmx.psll.q( <1 x i64> %A, <2 x >> i32> %B ) ; <<1 x i64>> [#uses=0] >> + %r2 = call <1 x i64> @llvm.x86.mmx.psrl.q( <1 x i64> %A, <2 x >> i32> %B ) ; <<1 x i64>> [#uses=0] >> + ret void >> +} >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Tue Jan 8 16:28:26 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 8 Jan 2008 14:28:26 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> Message-ID: <13AF29F7-C524-4BC9-9ADD-1E8BDAE38278@apple.com> On Jan 8, 2008, at 1:08 PM, Dale Johannesen wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=45757&view=rev > Log: > Fix gcc->llvm translation for virtual base classes. pr1746 Yay, very nice Dale. > +/// Mapping from type to type-used-as-base-class and back. > +static DenseMap BaseTypesMap; Does this play well with PCH? Please add a comment above this that says that the trees are kept pinned for the GC by the llvm_types_used map. If this doesn't work with PCH (Devang, thoughts?) it might be better to use the GCC splay tree or whatever they use for tree->tree mappings. Thanks for tackling this Dale, -Chris From dalej at apple.com Tue Jan 8 16:36:52 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 8 Jan 2008 14:36:52 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <13AF29F7-C524-4BC9-9ADD-1E8BDAE38278@apple.com> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> <13AF29F7-C524-4BC9-9ADD-1E8BDAE38278@apple.com> Message-ID: <4D53F61E-94E7-47D2-BA84-A4F64673A759@apple.com> On Jan 8, 2008, at 2:28 PM, Chris Lattner wrote: > On Jan 8, 2008, at 1:08 PM, Dale Johannesen wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=45757&view=rev >> Log: >> Fix gcc->llvm translation for virtual base classes. pr1746 > > Yay, very nice Dale. > >> +/// Mapping from type to type-used-as-base-class and back. >> +static DenseMap BaseTypesMap; > > Does this play well with PCH? Please add a comment above this that > says that the trees are kept pinned for the GC by the > llvm_types_used map. > > If this doesn't work with PCH (Devang, thoughts?) it might be better > to use the GCC splay tree or whatever they use for tree->tree > mappings. I haven't tried it (except that there are no failures in the PCH part of the gcc testsuite, which probably doesn't prove much). It should be OK for the map to be zeroes after a PCH read; all that will happen is some trees get rebuilt when this might be avoidable. It should also be OK for it to contain tree's, since all such trees are referred to from GTY'd storage. From clattner at apple.com Tue Jan 8 16:38:25 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 8 Jan 2008 14:38:25 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <4D53F61E-94E7-47D2-BA84-A4F64673A759@apple.com> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> <13AF29F7-C524-4BC9-9ADD-1E8BDAE38278@apple.com> <4D53F61E-94E7-47D2-BA84-A4F64673A759@apple.com> Message-ID: <9BF47794-6301-42B6-B023-F5A2D3B8F8D0@apple.com> >>> +/// Mapping from type to type-used-as-base-class and back. >>> +static DenseMap BaseTypesMap; >> >> Does this play well with PCH? Please add a comment above this that >> says that the trees are kept pinned for the GC by the >> llvm_types_used map. >> >> If this doesn't work with PCH (Devang, thoughts?) it might be >> better to use the GCC splay tree or whatever they use for tree- >> >tree mappings. > > I haven't tried it (except that there are no failures in the PCH > part of the gcc testsuite, which probably doesn't prove much). > It should be OK for the map to be zeroes after a PCH read; all that > will happen is some trees get rebuilt when this might be avoidable. > It should also be OK for it to contain tree's, since all such trees > are referred to from GTY'd storage. Ok. Devang, when it gets read in, will it be default constructed? If so, this should be ok then. -Chris From isanbard at gmail.com Tue Jan 8 17:07:41 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 08 Jan 2008 23:07:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45761 - /llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Message-ID: <200801082307.m08N7w7b012047@zion.cs.uiuc.edu> Author: void Date: Tue Jan 8 17:05:19 2008 New Revision: 45761 URL: http://llvm.org/viewvc/llvm-project?rev=45761&view=rev Log: Revert r45741; this broke the Objective-C ABI. Instead, mark metadata as "external". Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=45761&r1=45760&r2=45761&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Tue Jan 8 17:05:19 2008 @@ -9925,24 +9925,12 @@ /* struct class_t OBJC_CLASS_$_; */ UOBJC_V2_CLASS_decl = build_metadata_decl ("OBJC_CLASS_$", /* APPLE LOCAL radar 5202926 */ - /* APPLE LOCAL begin radar 5658734 */ -#ifndef ENABLE_LLVM objc_v2_class_template, true); -#else - objc_v2_class_template, false); -#endif - /* APPLE LOCAL end radar 5658734 */ /* struct class_t OBJC_METACLASS_$_; */ UOBJC_V2_METACLASS_decl = build_metadata_decl ("OBJC_METACLASS_$", /* APPLE LOCAL radar 5202926 */ - /* APPLE LOCAL begin radar 5658734 */ -#ifndef ENABLE_LLVM objc_v2_class_template, true); -#else - objc_v2_class_template, false); -#endif - /* APPLE LOCAL end radar 5658734 */ } static void @@ -12046,16 +12034,12 @@ sav = objc_implementation_context; objc_implementation_context = my_root_int; /* APPLE LOCAL radar 5202926 */ - /* APPLE LOCAL begin radar 5658734 */ -#ifndef ENABLE_LLVM - root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, - true); -#else - root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, - false); + root_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, true); + /* APPLE LOCAL LLVM begin - radar 5658734 */ +#ifdef ENABLE_LLVM + DECL_EXTERNAL(root_expr) = 1; #endif - root_expr = update_var_decl (root_expr); - /* APPLE LOCAL end radar 5658734 */ + /* APPLE LOCAL LLVM end - radar 5658734 */ root_expr = build_fold_addr_expr (root_expr); /* Install class `isa' and `super' pointers at runtime. */ @@ -12066,32 +12050,20 @@ back-end, recognizes '_OBJC_' prefix and prepends an 'L' in front of this. Darwin assembler treats names starting with 'L_' as local symbols. */ /* APPLE LOCAL radar 5202926 */ - /* APPLE LOCAL begin radar 5658734 */ -#ifndef ENABLE_LLVM - class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", - objc_v2_class_template, - true); -#else - class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", - objc_v2_class_template, - false); + class_superclass_expr = build_metadata_decl ("OBJC_CLASS_$", objc_v2_class_template, true); + /* APPLE LOCAL LLVM begin - radar 5658734 */ +#ifdef ENABLE_LLVM + DECL_EXTERNAL(class_superclass_expr) = 1; #endif - class_superclass_expr = update_var_decl (class_superclass_expr); - /* APPLE LOCAL end radar 5658734 */ + /* APPLE LOCAL LLVM end - radar 5658734 */ class_superclass_expr = build_fold_addr_expr (class_superclass_expr); /* APPLE LOCAL radar 5202926 */ - /* APPLE LOCAL begin radar 5658734 */ -#ifndef ENABLE_LLVM - metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", - objc_v2_class_template, - true); -#else - metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", - objc_v2_class_template, - false); + metaclass_superclass_expr = build_metadata_decl ("OBJC_METACLASS_$", objc_v2_class_template, true); + /* APPLE LOCAL LLVM begin - radar 5658734 */ +#ifdef ENABLE_LLVM + DECL_EXTERNAL(metaclass_superclass_expr) = 1; #endif - metaclass_superclass_expr = update_var_decl (metaclass_superclass_expr); - /* APPLE LOCAL end radar 5658734 */ + /* APPLE LOCAL LLVM end - radar 5658734 */ metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr); objc_implementation_context = sav; } From sabre at nondot.org Tue Jan 8 17:08:09 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Jan 2008 23:08:09 -0000 Subject: [llvm-commits] [llvm] r45762 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/longlong-deadload.ll Message-ID: <200801082308.m08N8ARo012065@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 17:08:06 2008 New Revision: 45762 URL: http://llvm.org/viewvc/llvm-project?rev=45762&view=rev Log: Make load->store deletion a bit smarter. This allows us to compile this: void test(long long *P) { *P ^= 1; } into just: _test: movl 4(%esp), %eax xorl $1, (%eax) ret instead of code like this: _test: movl 4(%esp), %ecx xorl $1, (%ecx) movl 4(%ecx), %edx movl %edx, 4(%ecx) ret Added: llvm/trunk/test/CodeGen/X86/longlong-deadload.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=45762&r1=45761&r2=45762&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Jan 8 17:08:06 2008 @@ -4122,6 +4122,34 @@ return SDOperand(); } +/// ReachesChainWithoutSideEffects - Do a little local search to see if Src can +/// reach Dest without any side effects like a store, or call. Non-volatile +/// loads are ok though. +static bool ReachesChainWithoutSideEffects(SDOperand Src, SDOperand Dest, + unsigned Depth = 0) { + if (Src == Dest) return true; + + // Don't search too deeply, we just want to be able to see through + // TokenFactor's etc. + if (Depth == 2) return false; + + // If this is a token factor, all inputs to the TF happen in parallel. If any + // of the operands of the TF reach dest, then we can do the xform. + if (Src.getOpcode() == ISD::TokenFactor) { + for (unsigned i = 0, e = Src.getNumOperands(); i != e; ++i) + if (ReachesChainWithoutSideEffects(Src.getOperand(i), Dest, Depth+1)) + return true; + return false; + } + + // Loads don't have side effects, look through them. + if (LoadSDNode *Ld = dyn_cast(Src)) { + if (!Ld->isVolatile()) + return ReachesChainWithoutSideEffects(Ld->getChain(), Dest, Depth+1); + } + return false; +} + SDOperand DAGCombiner::visitSTORE(SDNode *N) { StoreSDNode *ST = cast(N); SDOperand Chain = ST->getChain(); @@ -4250,10 +4278,12 @@ // If this is a load followed by a store to the same location, then the store // is dead/noop. if (LoadSDNode *Ld = dyn_cast(Value)) { - if (Chain.Val == Ld && Ld->getBasePtr() == Ptr && + if (Ld->getBasePtr() == Ptr && ST->getStoredVT() == Ld->getLoadedVT() && ST->getAddressingMode() == ISD::UNINDEXED && - ST->getStoredVT() == Ld->getLoadedVT() && - !ST->isVolatile()) { + !ST->isVolatile() && + // There can't be any side effects between the load and store, such as + // a call or store. + ReachesChainWithoutSideEffects(Chain, SDOperand(Ld, 1))) { // The store is dead, remove it. return Chain; } Added: llvm/trunk/test/CodeGen/X86/longlong-deadload.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/longlong-deadload.ll?rev=45762&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/longlong-deadload.ll (added) +++ llvm/trunk/test/CodeGen/X86/longlong-deadload.ll Tue Jan 8 17:08:06 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep '4{(%...)} +; This should not load or store the top part of *P. + +define void @test(i64* %P) nounwind { +entry: + %tmp1 = load i64* %P, align 8 ; [#uses=1] + %tmp2 = xor i64 %tmp1, 1 ; [#uses=1] + store i64 %tmp2, i64* %P, align 8 + ret void +} + From dpatel at apple.com Tue Jan 8 18:16:26 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 8 Jan 2008 16:16:26 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <4D53F61E-94E7-47D2-BA84-A4F64673A759@apple.com> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> <13AF29F7-C524-4BC9-9ADD-1E8BDAE38278@apple.com> <4D53F61E-94E7-47D2-BA84-A4F64673A759@apple.com> Message-ID: <8F709D4A-A9A3-4737-B715-D89E7463F175@apple.com> On Jan 8, 2008, at 2:36 PM, Dale Johannesen wrote: > > On Jan 8, 2008, at 2:28 PM, Chris Lattner wrote: > >> On Jan 8, 2008, at 1:08 PM, Dale Johannesen wrote: >>> URL: http://llvm.org/viewvc/llvm-project?rev=45757&view=rev >>> Log: >>> Fix gcc->llvm translation for virtual base classes. pr1746 >> >> Yay, very nice Dale. >> >>> +/// Mapping from type to type-used-as-base-class and back. >>> +static DenseMap BaseTypesMap; >> >> Does this play well with PCH? Please add a comment above this that >> says that the trees are kept pinned for the GC by the >> llvm_types_used map. >> >> If this doesn't work with PCH (Devang, thoughts?) it might be >> better to use the GCC splay tree or whatever they use for tree- >> >tree mappings. > > I haven't tried it (except that there are no failures in the PCH > part of the gcc testsuite, which probably doesn't prove much). > It should be OK for the map to be zeroes after a PCH read; all that > will happen is some trees get rebuilt when this might be avoidable. > It should also be OK for it to contain tree's, since all such trees > are referred to from GTY'd storage. BaseTypeMap is empty at the beginning. PCH reading does not insert any entries so this map will be empty after PCH read. If LLVM types refers to mapped tree nodes then it is OK because such tree nodes are GTY'd. As long as it is safe to rebuilt some trees for BaseTypeMap this patch looks OK. - Devang From dalej at apple.com Tue Jan 8 18:16:55 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 09 Jan 2008 00:16:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45765 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Message-ID: <200801090016.m090GtPj015612@zion.cs.uiuc.edu> Author: johannes Date: Tue Jan 8 18:16:55 2008 New Revision: 45765 URL: http://llvm.org/viewvc/llvm-project?rev=45765&view=rev Log: Watch out for overflow rounding up sizes of large objects. Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=45765&r1=45764&r2=45765&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Tue Jan 8 18:16:55 2008 @@ -1706,14 +1706,25 @@ // compensated as far as LLVM's translation code is concerned; now we // have fixed that, and have to fix the size also. if (TYPE_SIZE (type) && TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST) { - TYPE_SIZE(type) = build_int_cst( - TREE_TYPE(TYPE_SIZE(type)), - (TREE_INT_CST_LOW(TYPE_SIZE(type))+TYPE_ALIGN(type)-1) & - ~(TYPE_ALIGN(type)-1)); - TYPE_SIZE_UNIT(type) = build_int_cst( - TREE_TYPE(TYPE_SIZE_UNIT(type)), - (TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type))+TYPE_ALIGN_UNIT(type)-1) & - ~(TYPE_ALIGN_UNIT(type)-1)); + // This computes (size+align-1) & ~(align-1) + // NB "sizetype" is #define'd in one of the gcc headers. Gotcha! + tree size_type = TREE_TYPE(TYPE_SIZE(type)); + tree alignm1 = fold_build2(PLUS_EXPR, size_type, + build_int_cst(size_type, TYPE_ALIGN(type)), + fold_build1(NEGATE_EXPR, size_type, + build_int_cst(size_type, 1))); + tree lhs = fold_build2(PLUS_EXPR, size_type, TYPE_SIZE(type), alignm1); + tree rhs = fold_build1(BIT_NOT_EXPR, size_type, alignm1); + TYPE_SIZE(type) = fold_build2(BIT_AND_EXPR, size_type, lhs, rhs); + + size_type = TREE_TYPE(TYPE_SIZE_UNIT(type)); + alignm1 = fold_build2(PLUS_EXPR, size_type, + build_int_cst(size_type, TYPE_ALIGN_UNIT(type)), + fold_build1(NEGATE_EXPR, size_type, + build_int_cst(size_type, 1))); + lhs = fold_build2(PLUS_EXPR, size_type, TYPE_SIZE_UNIT(type), alignm1); + rhs = fold_build1(BIT_NOT_EXPR, size_type, alignm1); + TYPE_SIZE_UNIT(type) = fold_build2(BIT_AND_EXPR, size_type, lhs, rhs); } } From sabre at nondot.org Tue Jan 8 18:17:57 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Jan 2008 00:17:57 -0000 Subject: [llvm-commits] [llvm] r45766 - /llvm/trunk/lib/Target/README.txt Message-ID: <200801090017.m090Hwgd015650@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 18:17:57 2008 New Revision: 45766 URL: http://llvm.org/viewvc/llvm-project?rev=45766&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=45766&r1=45765&r2=45766&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Jan 8 18:17:57 2008 @@ -524,3 +524,24 @@ http://burtleburtle.net/bob/hash/perfect.html //===---------------------------------------------------------------------===// + +We should turn things like "load+fabs+store" and "load+fneg+store" into the +corresponding integer operations. On a yonah, this loop: + +double a[256]; + for (b = 0; b < 10000000; b++) + for (i = 0; i < 256; i++) + a[i] = -a[i]; + +is twice as slow as this loop: + +long long a[256]; + for (b = 0; b < 10000000; b++) + for (i = 0; i < 256; i++) + a[i] ^= (1ULL << 63); + +and I suspect other processors are similar. On X86 in particular this is a +big win because doing this with integers allows the use of read/modify/write +instructions. + +//===---------------------------------------------------------------------===// From sabre at nondot.org Tue Jan 8 18:37:20 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Jan 2008 00:37:20 -0000 Subject: [llvm-commits] [llvm] r45768 - in /llvm/trunk/lib/Target/X86: README.txt X86InstrInfo.cpp Message-ID: <200801090037.m090bK0r016540@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 18:37:18 2008 New Revision: 45768 URL: http://llvm.org/viewvc/llvm-project?rev=45768&view=rev Log: add a testcase Modified: llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=45768&r1=45767&r2=45768&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Tue Jan 8 18:37:18 2008 @@ -1601,13 +1601,13 @@ In SSE mode, we turn abs and neg into a load from the constant pool plus a xor or and instruction, for example: - xorpd LCPI2_0-"L2$pb"(%esi), %xmm2 + xorpd LCPI1_0, %xmm2 However, if xmm2 gets spilled, we end up with really ugly code like this: - %xmm2 = reload [mem] - xorpd LCPI2_0-"L2$pb"(%esi), %xmm2 - store %xmm2 -> [mem] + movsd (%esp), %xmm0 + xorpd LCPI1_0, %xmm0 + movsd %xmm0, (%esp) Since we 'know' that this is a 'neg', we can actually "fold" the spill into the neg/abs instruction, turning it into an *integer* operation, like this: @@ -1615,6 +1615,17 @@ xorl 2147483648, [mem+4] ## 2147483648 = (1 << 31) you could also use xorb, but xorl is less likely to lead to a partial register -stall. +stall. Here is a contrived testcase: + +double a, b, c; +void test(double *P) { + double X = *P; + a = X; + bar(); + X = -X; + b = X; + bar(); + c = X; +} //===---------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45768&r1=45767&r2=45768&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Jan 8 18:37:18 2008 @@ -1740,8 +1740,7 @@ // No fusion if (PrintFailedFusing) - cerr << "We failed to fuse (" - << ((i == 1) ? "r" : "s") << "): " << *MI; + cerr << "We failed to fuse operand " << i << *MI; return NULL; } @@ -1773,8 +1772,8 @@ } MachineInstr* X86InstrInfo::foldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops, - MachineInstr *LoadMI) const { + SmallVectorImpl &Ops, + MachineInstr *LoadMI) const { // Check switch flag if (NoFusing) return NULL; @@ -1802,7 +1801,7 @@ bool X86InstrInfo::canFoldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops) const { + SmallVectorImpl &Ops) const { // Check switch flag if (NoFusing) return 0; From sabre at nondot.org Tue Jan 8 19:01:18 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Jan 2008 01:01:18 -0000 Subject: [llvm-commits] [llvm] r45770 - /llvm/trunk/tools/llvm-ld/llvm-ld.cpp Message-ID: <200801090101.m0911Il9018218@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 8 19:01:17 2008 New Revision: 45770 URL: http://llvm.org/viewvc/llvm-project?rev=45770&view=rev Log: Fix llvm-ld -Xlinker, patch by Daniel Teske! Modified: llvm/trunk/tools/llvm-ld/llvm-ld.cpp Modified: llvm/trunk/tools/llvm-ld/llvm-ld.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ld/llvm-ld.cpp?rev=45770&r1=45769&r2=45770&view=diff ============================================================================== --- llvm/trunk/tools/llvm-ld/llvm-ld.cpp (original) +++ llvm/trunk/tools/llvm-ld/llvm-ld.cpp Tue Jan 8 19:01:17 2008 @@ -338,10 +338,8 @@ } // Add the requested options - for (unsigned index = 0; index < XLinker.size(); index++) { + for (unsigned index = 0; index < XLinker.size(); index++) args.push_back(XLinker[index]); - args.push_back(Libraries[index]); - } // Add in the libraries to link. for (unsigned index = 0; index < LinkItems.size(); index++) From evan.cheng at apple.com Tue Jan 8 20:16:50 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Jan 2008 02:16:50 -0000 Subject: [llvm-commits] [llvm] r45772 - in /llvm/trunk: include/llvm/IntrinsicsX86.td test/CodeGen/X86/2007-05-17-ShuffleISelBug.ll test/CodeGen/X86/vec_shift.ll Message-ID: <200801090216.m092Guui021727@zion.cs.uiuc.edu> Author: evancheng Date: Tue Jan 8 20:16:44 2008 New Revision: 45772 URL: http://llvm.org/viewvc/llvm-project?rev=45772&view=rev Log: Fix sse2.psrl.w and sse2.psrl.q definitions. Added: llvm/trunk/test/CodeGen/X86/vec_shift.ll Modified: llvm/trunk/include/llvm/IntrinsicsX86.td llvm/trunk/test/CodeGen/X86/2007-05-17-ShuffleISelBug.ll Modified: llvm/trunk/include/llvm/IntrinsicsX86.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=45772&r1=45771&r2=45772&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) +++ llvm/trunk/include/llvm/IntrinsicsX86.td Tue Jan 8 20:16:44 2008 @@ -329,13 +329,13 @@ llvm_i32_ty], [IntrNoMem]>; def int_x86_sse2_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw128">, Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, - llvm_v4i32_ty], [IntrNoMem]>; + llvm_v8i16_ty], [IntrNoMem]>; def int_x86_sse2_psrl_d : GCCBuiltin<"__builtin_ia32_psrld128">, Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; def int_x86_sse2_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq128">, Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty, - llvm_v4i32_ty], [IntrNoMem]>; + llvm_v2i64_ty], [IntrNoMem]>; def int_x86_sse2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi128">, Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; Modified: llvm/trunk/test/CodeGen/X86/2007-05-17-ShuffleISelBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-05-17-ShuffleISelBug.ll?rev=45772&r1=45771&r2=45772&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-05-17-ShuffleISelBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-05-17-ShuffleISelBug.ll Tue Jan 8 20:16:44 2008 @@ -3,7 +3,7 @@ declare <8 x i16> @llvm.x86.sse2.packuswb.128(<8 x i16>, <8 x i16>) -declare <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16>, <4 x i32>) +declare <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16>, <8 x i16>) define fastcc void @test(i32* %src, i32 %sbpr, i32* %dst, i32 %dbpr, i32 %w, i32 %h, i32 %dstalpha, i32 %mask) { %tmp633 = shufflevector <8 x i16> zeroinitializer, <8 x i16> undef, <8 x i32> < i32 4, i32 4, i32 5, i32 5, i32 6, i32 6, i32 7, i32 7 > @@ -12,7 +12,7 @@ %tmp777 = add <4 x i32> %tmp776, shufflevector (<4 x i32> < i32 65537, i32 0, i32 0, i32 0 >, <4 x i32> < i32 65537, i32 0, i32 0, i32 0 >, <4 x i32> zeroinitializer) %tmp805 = add <4 x i32> %tmp777, zeroinitializer %tmp832 = bitcast <4 x i32> %tmp805 to <8 x i16> - %tmp838 = tail call <8 x i16> @llvm.x86.sse2.psrl.w( <8 x i16> %tmp832, <4 x i32> < i32 8, i32 undef, i32 undef, i32 undef > ) + %tmp838 = tail call <8 x i16> @llvm.x86.sse2.psrl.w( <8 x i16> %tmp832, <8 x i16> < i16 8, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef > ) %tmp1020 = tail call <8 x i16> @llvm.x86.sse2.packuswb.128( <8 x i16> zeroinitializer, <8 x i16> %tmp838 ) %tmp1030 = bitcast <8 x i16> %tmp1020 to <4 x i32> %tmp1033 = add <4 x i32> zeroinitializer, %tmp1030 Added: llvm/trunk/test/CodeGen/X86/vec_shift.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shift.ll?rev=45772&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shift.ll (added) +++ llvm/trunk/test/CodeGen/X86/vec_shift.ll Tue Jan 8 20:16:44 2008 @@ -0,0 +1,34 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep psllw +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep psrlq +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep psraw + +define <2 x i64> @t1(<2 x i64> %b1, <2 x i64> %c) nounwind { +entry: + %tmp6 = bitcast <2 x i64> %c to <8 x i16> ; <<8 x i16>> [#uses=1] + %tmp8 = bitcast <2 x i64> %b1 to <8 x i16> ; <<8 x i16>> [#uses=1] + %tmp9 = tail call <8 x i16> @llvm.x86.sse2.psll.w( <8 x i16> %tmp8, <8 x i16> %tmp6 ) nounwind readnone ; <<8 x i16>> [#uses=1] + %tmp10 = bitcast <8 x i16> %tmp9 to <2 x i64> ; <<2 x i64>> [#uses=1] + ret <2 x i64> %tmp10 +} + +define <2 x i64> @t3(<2 x i64> %b1, i32 %c) nounwind { +entry: + %tmp2 = bitcast <2 x i64> %b1 to <8 x i16> ; <<8 x i16>> [#uses=1] + %tmp4 = insertelement <4 x i32> undef, i32 %c, i32 0 ; <<4 x i32>> [#uses=1] + %tmp8 = bitcast <4 x i32> %tmp4 to <8 x i16> ; <<8 x i16>> [#uses=1] + %tmp9 = tail call <8 x i16> @llvm.x86.sse2.psra.w( <8 x i16> %tmp2, <8 x i16> %tmp8 ) ; <<8 x i16>> [#uses=1] + %tmp11 = bitcast <8 x i16> %tmp9 to <2 x i64> ; <<2 x i64>> [#uses=1] + ret <2 x i64> %tmp11 +} + +declare <8 x i16> @llvm.x86.sse2.psra.w(<8 x i16>, <8 x i16>) nounwind readnone + +define <2 x i64> @t2(<2 x i64> %b1, <2 x i64> %c) nounwind { +entry: + %tmp9 = tail call <2 x i64> @llvm.x86.sse2.psrl.q( <2 x i64> %b1, <2 x i64> %c ) nounwind readnone ; <<2 x i64>> [#uses=1] + ret <2 x i64> %tmp9 +} + +declare <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64>, <2 x i64>) nounwind readnone + +declare <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16>, <8 x i16>) nounwind readnone From llvm at cs.uiuc.edu Tue Jan 8 22:44:07 2008 From: llvm at cs.uiuc.edu (LLVM) Date: Tue, 8 Jan 2008 22:44:07 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/ Message-ID: <200801090444.m094i7UR029242@zion.cs.uiuc.edu> Changes in directory llvm-www/devmtg/current: --- Log message: Directory /var/cvs/llvm/llvm-www/devmtg/current added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From resistor at mac.com Wed Jan 9 00:19:05 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 09 Jan 2008 06:19:05 -0000 Subject: [llvm-commits] [llvm] r45773 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801090619.m096J6Sr002612@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 00:19:05 2008 New Revision: 45773 URL: http://llvm.org/viewvc/llvm-project?rev=45773&view=rev Log: Fix some simple bugs. StrongPHIElimination now does not crash on 164.gzip. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45773&r1=45772&r2=45773&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 00:19:05 2008 @@ -178,7 +178,6 @@ else if (preorder[ABlock] > preorder[BBlock]) return false; - assert(0 && "Error sorting by dominance!"); return false; } }; @@ -208,8 +207,9 @@ for (std::vector::iterator I = worklist.begin(), E = worklist.end(); I != E; ++I) { unsigned pre = preorder[LV.getVarInfo(*I).DefInst->getParent()]; - MachineBasicBlock* parentBlock = - LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent(); + MachineBasicBlock* parentBlock = CurrentParent->getReg() ? + LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent() : + 0; while (pre > maxpreorder[parentBlock]) { stack.pop_back(); From jon at alacatialabs.com Tue Jan 8 22:47:44 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Tue, 8 Jan 2008 22:47:44 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/index.html Message-ID: <200801090447.m094li7l029588@zion.cs.uiuc.edu> Changes in directory llvm-www/devmtg/current: index.html added (r1.1) --- Log message: Added initial dev meeting page. --- Diffs of the changes: (+49 -0) index.html | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 49 insertions(+) Index: llvm-www/devmtg/current/index.html diff -c /dev/null llvm-www/devmtg/current/index.html:1.1 *** /dev/null Tue Jan 8 22:47:20 2008 --- llvm-www/devmtg/current/index.html Tue Jan 8 22:47:10 2008 *************** *** 0 **** --- 1,49 ---- + +
LLVM Developers' Meeting
+ +
+
    +
  1. Important Notes
  2. +
  3. Attendees
  4. +
+
+
    +
  • What: The second general meeting of LLVM Developers and Users. +
  • +
  • Why: To get acquainted, learn how LLVM is used, and exchange + ideas.
  • +
  • When: To be determined.
  • +
  • Where: To be determined.
  • +
+
+ + + +
+

We are in the early stages of planning the second LLVM group meeting. At this point in time, we are asking that anyone interested in attending email the answers to these questions to the person organizing this meeting:

+
    +
  • Are you willing to give a talk? on what topic?
  • +
  • What topics are your primary interests?
  • +
  • Are you or your company willing to make a donation?
  • +
  • What timeframe and location is best for you?
  • +
+
+ + + +
+

This table lists all attendees that have expressed interest in attending this year's conference.

+ + + + + + + + + +
Unconfirmed Attendees
NameOrganization
Robert HundtGoogle
Jonathan JohnsonAlacatia Labs, Inc.
Chris LattnerApple, Inc.
Joseph RanieriAlacatia Labs, Inc.
Chuck RoseAdobe Systems Incorporated
Mike StumpApple, Inc.
+

Total unconfirmed: 6

+
+ + \ No newline at end of file From jon at alacatialabs.com Tue Jan 8 22:49:20 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Tue, 8 Jan 2008 22:49:20 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/index.html Message-ID: <200801090449.m094nKAr029857@zion.cs.uiuc.edu> Changes in directory llvm-www/devmtg/current: index.html updated: 1.1 -> 1.2 --- Log message: Fixed virtual include paths for developer meeting page. --- Diffs of the changes: (+2 -2) index.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/devmtg/current/index.html diff -u llvm-www/devmtg/current/index.html:1.1 llvm-www/devmtg/current/index.html:1.2 --- llvm-www/devmtg/current/index.html:1.1 Tue Jan 8 22:47:10 2008 +++ llvm-www/devmtg/current/index.html Tue Jan 8 22:49:01 2008 @@ -1,4 +1,4 @@ - +
LLVM Developers' Meeting
+ + + + + + + +
@@ -46,4 +46,4 @@

Total unconfirmed: 6

- \ No newline at end of file + \ No newline at end of file From resistor at mac.com Wed Jan 9 04:32:36 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 09 Jan 2008 10:32:36 -0000 Subject: [llvm-commits] [llvm] r45774 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801091032.m09AWcd8026421@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 04:32:30 2008 New Revision: 45774 URL: http://llvm.org/viewvc/llvm-project?rev=45774&view=rev Log: Fix an infinite recursion bug in InsertCopies. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45774&r1=45773&r2=45774&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 04:32:30 2008 @@ -101,7 +101,7 @@ std::vector& DF, std::vector >& locals); void ScheduleCopies(MachineBasicBlock* MBB, std::set& pushed); - void InsertCopies(MachineBasicBlock* MBB); + void InsertCopies(MachineBasicBlock* MBB, std::set& v); }; char StrongPHIElimination::ID = 0; @@ -610,7 +610,10 @@ } /// InsertCopies - insert copies into MBB and all of its successors -void StrongPHIElimination::InsertCopies(MachineBasicBlock* MBB) { +void StrongPHIElimination::InsertCopies(MachineBasicBlock* MBB, + std::set& visited) { + visited.insert(MBB); + std::set pushed; // Rewrite register uses from Stacks @@ -629,7 +632,8 @@ for (GraphTraits::ChildIteratorType I = GraphTraits::child_begin(MBB), E = GraphTraits::child_end(MBB); I != E; ++I) - InsertCopies(*I); + if (!visited.count(*I)) + InsertCopies(*I, visited); // As we exit this block, pop the names we pushed while processing it for (std::set::iterator I = pushed.begin(), @@ -649,7 +653,8 @@ // Insert copies // FIXME: This process should probably preserve LiveVariables - InsertCopies(Fn.begin()); + std::set visited; + InsertCopies(Fn.begin(), visited); // Perform renaming typedef std::map > RenameSetType; From resistor at mac.com Wed Jan 9 04:41:41 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 09 Jan 2008 10:41:41 -0000 Subject: [llvm-commits] [llvm] r45775 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801091041.m09AfgHe026801@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 04:41:39 2008 New Revision: 45775 URL: http://llvm.org/viewvc/llvm-project?rev=45775&view=rev Log: StrongPHIElim: Now with even fewer trivial bugs! Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45775&r1=45774&r2=45775&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 04:41:39 2008 @@ -215,7 +215,9 @@ stack.pop_back(); CurrentParent = stack.back(); - parentBlock = LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent(); + parentBlock = CurrentParent->getReg() ? + LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent() : + 0; } DomForestNode* child = new DomForestNode(*I, CurrentParent); @@ -361,7 +363,7 @@ std::set ProcessedNames; MachineBasicBlock::iterator P = MBB->begin(); - while (P->getOpcode() == TargetInstrInfo::PHI) { + while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand(0).getReg()); unsigned DestReg = P->getOperand(0).getReg(); From sam at bishop.dhs.org Wed Jan 9 11:34:00 2008 From: sam at bishop.dhs.org (Sam Bishop) Date: Wed, 9 Jan 2008 10:34:00 -0700 (MST) Subject: [llvm-commits] CommandLine.html patch Message-ID: <62094.137.201.242.130.1199900040.squirrel@webmail.nwind.net> I've attached a patch which fixes a few punctuation errors and typos in the CommandLine class documentation. (Thanks for the documentation, by the way!) Also, I was confused by one of the examples regarding the handling of program-wide global options such as a debug flag. "DebugFlag" is the global variable set by the parser; the following is given as an example of how you would use it: // DEBUG macro - This macro should be used by code to emit debug information. // In the '-debug' option is specified on the command line, and if this is a // debug build, then the code specified as the option to the macro will be // executed. Otherwise it will not be. Example: // // DOUT << "Bitset contains: " << Bitset << "\n"; // #ifdef NDEBUG #define DEBUG(X) #else #define DEBUG(X) do { if (DebugFlag) { X; } } while (0) #endif I'm very new to LLVM, so I can only guess at how DOUT is related to DEBUG(). Is there another example that would be more straightforward? Thanks, Sam Bishop -------------- next part -------------- A non-text attachment was scrubbed... Name: CommandLine.html.patch Type: application/octet-stream Size: 11963 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/0acdf19f/attachment.obj From sam at bishop.dhs.org Wed Jan 9 11:54:27 2008 From: sam at bishop.dhs.org (Sam Bishop) Date: Wed, 9 Jan 2008 10:54:27 -0700 (MST) Subject: [llvm-commits] CommandLine.html patch In-Reply-To: <62094.137.201.242.130.1199900040.squirrel@webmail.nwind.net> References: <62094.137.201.242.130.1199900040.squirrel@webmail.nwind.net> Message-ID: <16507.137.201.242.130.1199901267.squirrel@webmail.nwind.net> On Wed, January 9, 2008 10:34 am, Sam Bishop wrote: > Also, I was confused by one of the examples regarding the handling of > program-wide global options such as a debug flag > ... > I'm very new to LLVM, so I can only guess at how DOUT is related to DEBUG(). > Is there another example that would be more straightforward? On second thought, I'd recommend simply removing the DOUT example from the comment. I have attached an updated patch. Sam -------------- next part -------------- A non-text attachment was scrubbed... Name: CommandLine.html.patch Type: application/octet-stream Size: 12966 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/c6ce20fa/attachment.obj From jon at alacatialabs.com Wed Jan 9 12:38:38 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Wed, 9 Jan 2008 12:38:38 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/index.html Message-ID: <200801091838.m09Iccun018699@zion.cs.uiuc.edu> Changes in directory llvm-www/devmtg/current: index.html updated: 1.2 -> 1.3 --- Log message: Updated list of attendees, added link from dev. meeting sidebar entry and frontpage entry below the 2.2 release schedule. --- Diffs of the changes: (+2 -1) index.html | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm-www/devmtg/current/index.html diff -u llvm-www/devmtg/current/index.html:1.2 llvm-www/devmtg/current/index.html:1.3 --- llvm-www/devmtg/current/index.html:1.2 Tue Jan 8 22:49:01 2008 +++ llvm-www/devmtg/current/index.html Wed Jan 9 12:37:54 2008 @@ -36,6 +36,7 @@ + @@ -43,7 +44,7 @@
Unconfirmed Attendees
NameOrganization
Owen AndersonApple, Inc.
Robert HundtGoogle
Jonathan JohnsonAlacatia Labs, Inc.
Chris LattnerApple, Inc.
Chuck RoseAdobe Systems Incorporated
Mike StumpApple, Inc.
-

Total unconfirmed: 6

+

Total unconfirmed: 7

\ No newline at end of file From jon at alacatialabs.com Wed Jan 9 12:38:38 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Wed, 9 Jan 2008 12:38:38 -0600 Subject: [llvm-commits] CVS: llvm-www/header.incl www-index.html Message-ID: <200801091838.m09IccBv018702@zion.cs.uiuc.edu> Changes in directory llvm-www: header.incl updated: 1.63 -> 1.64 www-index.html updated: 1.149 -> 1.150 --- Log message: Updated list of attendees, added link from dev. meeting sidebar entry and frontpage entry below the 2.2 release schedule. --- Diffs of the changes: (+9 -0) header.incl | 1 + www-index.html | 8 ++++++++ 2 files changed, 9 insertions(+) Index: llvm-www/header.incl diff -u llvm-www/header.incl:1.63 llvm-www/header.incl:1.64 --- llvm-www/header.incl:1.63 Thu Sep 27 01:27:42 2007 +++ llvm-www/header.incl Wed Jan 9 12:37:54 2008 @@ -91,6 +91,7 @@ Developer Mtgs Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.149 llvm-www/www-index.html:1.150 --- llvm-www/www-index.html:1.149 Fri Sep 28 18:23:11 2007 +++ llvm-www/www-index.html Wed Jan 9 12:37:54 2008 @@ -129,6 +129,14 @@
+
Upcoming Meeting
+ +
+

We are planning this year's developer meeting. Please provide input and let us know if you are interested in attending.

+
+ +
+
Try out LLVM in your browser
From isanbard at gmail.com Wed Jan 9 12:45:39 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 9 Jan 2008 10:45:39 -0800 Subject: [llvm-commits] CommandLine.html patch In-Reply-To: <62094.137.201.242.130.1199900040.squirrel@webmail.nwind.net> References: <62094.137.201.242.130.1199900040.squirrel@webmail.nwind.net> Message-ID: <16e5fdf90801091045v405f403cj58a1a54357ee85b7@mail.gmail.com> On Jan 9, 2008 9:34 AM, Sam Bishop wrote: > Also, I was confused by one of the examples regarding the handling of > program-wide global options such as a debug flag. "DebugFlag" is the global > variable set by the parser; the following is given as an example of how you > would use it: > > // DEBUG macro - This macro should be used by code to emit debug information. > // In the '-debug' option is specified on the command line, and if this is a > // debug build, then the code specified as the option to the macro will be > // executed. Otherwise it will not be. Example: > // > // DOUT << "Bitset contains: " << Bitset << "\n"; > // > #ifdef NDEBUG > #define DEBUG(X) > #else > #define DEBUG(X) do { if (DebugFlag) { X; } } while (0) > #endif > > I'm very new to LLVM, so I can only guess at how DOUT is related to DEBUG(). > Is there another example that would be more straightforward? > DOUT is documented here: http://llvm.org/docs/CodingStandards.html#ll_iostream Though you're right that this example is misplaced. -bw From sabre at nondot.org Wed Jan 9 13:28:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Jan 2008 19:28:51 -0000 Subject: [llvm-commits] [llvm] r45780 - /llvm/trunk/docs/CommandLine.html Message-ID: <200801091928.m09JSpKj021766@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 13:28:50 2008 New Revision: 45780 URL: http://llvm.org/viewvc/llvm-project?rev=45780&view=rev Log: many cleanups and fixed, contributed by Sam Bishop Modified: llvm/trunk/docs/CommandLine.html Modified: llvm/trunk/docs/CommandLine.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandLine.html?rev=45780&r1=45779&r2=45780&view=diff ============================================================================== --- llvm/trunk/docs/CommandLine.html (original) +++ llvm/trunk/docs/CommandLine.html Wed Jan 9 13:28:50 2008 @@ -138,7 +138,7 @@
  • Globally accessible: Libraries can specify command line arguments that are automatically enabled in any tool that links to the library. This is possible -because the application doesn't have to keep a "list" of arguments to pass to +because the application doesn't have to keep a list of arguments to pass to the parser. This also makes supporting dynamically loaded options trivial.
  • @@ -216,12 +216,12 @@ declarations.

    Now that you are ready to support command line arguments, we need to tell the -system which ones we want, and what type of argument they are. The CommandLine +system which ones we want, and what type of arguments they are. The CommandLine library uses a declarative syntax to model command line arguments with the global variable declarations that capture the parsed values. This means that for every command line option that you would like to support, there should be a global variable declaration to capture the result. For example, in a compiler, -we would like to support the unix standard '-o <filename>' option +we would like to support the Unix-standard '-o <filename>' option to specify where to put the output. With the CommandLine library, this is represented like this:

    @@ -383,7 +383,7 @@ -help - display available options (--help-hidden for more)
    -

    and "opt --help-hidden" prints this:

    +

    and "compiler --help-hidden" prints this:

     USAGE: compiler [options] <input file>
    @@ -432,7 +432,7 @@
     

    The third line (which is the only one we modified from above) defines a -"-q alias that updates the "Quiet" variable (as specified by +"-q" alias that updates the "Quiet" variable (as specified by the cl::aliasopt modifier) whenever it is specified. Because aliases do not hold state, the only thing the program has to query is the Quiet variable now. Another nice feature of aliases is @@ -462,24 +462,24 @@

    -

    So far, we have seen how the CommandLine library handles builtin types like +

    So far we have seen how the CommandLine library handles builtin types like std::string, bool and int, but how does it handle things it doesn't know about, like enums or 'int*'s?

    -

    The answer is that it uses a table driven generic parser (unless you specify +

    The answer is that it uses a table-driven generic parser (unless you specify your own parser, as described in the Extension Guide). This parser maps literal strings to whatever type is required, and requires you to tell it what this mapping should be.

    -

    Lets say that we would like to add four optimization levels to our +

    Let's say that we would like to add four optimization levels to our optimizer, using the standard flags "-g", "-O0", "-O1", and "-O2". We could easily implement this with boolean options like above, but there are several problems with this strategy:

    1. A user could specify more than one of the options at a time, for example, -"opt -O3 -O2". The CommandLine library would not be able to catch this -erroneous input for us.
    2. +"compiler -O3 -O2". The CommandLine library would not be able to +catch this erroneous input for us.
    3. We would have to test 4 different variables to see which ones are set.
    4. @@ -634,7 +634,7 @@
      -

      Now that we have the standard run of the mill argument types out of the way, +

      Now that we have the standard run-of-the-mill argument types out of the way, lets get a little wild and crazy. Lets say that we want our optimizer to accept a list of optimizations to perform, allowing duplicates. For example, we might want to run: "compiler -dce -constprop -inline -dce -strip". In @@ -750,7 +750,7 @@

      Finally, if external storage is used, then the location specified must be of type unsigned. In all other ways a cl::bits option is morally equivalent to a cl::bits option is equivalent to a cl::list option.

      @@ -916,7 +916,7 @@
         static cl::list<std::string> Files(cl::Positional, cl::OneOrMore);
      -  static cl::listlt;std::string> Libraries("l", cl::ZeroOrMore);
      +  static cl::list<std::string> Libraries("l", cl::ZeroOrMore);
       
         int main(int argc, char**argv) {
           // ...
      @@ -969,7 +969,7 @@
       standard Unix Bourne shell (/bin/sh).  To run /bin/sh, first
       you specify options to the shell itself (like -x which turns on trace
       output), then you specify the name of the script to run, then you specify
      -arguments to the script.  These arguments to the script are parsed by the bourne
      +arguments to the script.  These arguments to the script are parsed by the Bourne
       shell command line option processor, but are not interpreted as options to the
       shell itself.  Using the CommandLine library, we would specify this as:

      @@ -1042,10 +1042,7 @@ // DEBUG macro - This macro should be used by code to emit debug information. // In the '-debug' option is specified on the command line, and if this is a // debug build, then the code specified as the option to the macro will be -// executed. Otherwise it will not be. Example: -// -// DOUT << "Bitset contains: " << Bitset << "\n"; -// +// executed. Otherwise it will not be. #ifdef NDEBUG #define DEBUG(X) #else @@ -1057,7 +1054,7 @@

      This allows clients to blissfully use the DEBUG() macro, or the DebugFlag explicitly if they want to. Now we just need to be able to set the DebugFlag boolean when the option is set. To do this, we pass -an additial argument to our command line argument processor, and we specify +an additional argument to our command line argument processor, and we specify where to fill in with the cl::location attribute:

      @@ -1206,15 +1203,15 @@
    5. The cl::NotHidden modifier (which is the default for cl::opt and cl::list options), indicates the option is to appear +href="#cl::list">cl::list options) indicates the option is to appear in both help listings.
    6. The cl::Hidden modifier (which is the -default for cl::alias options), indicates that +default for cl::alias options) indicates that the option should not appear in the --help output, but should appear in the --help-hidden output.
    7. -
    8. The cl::ReallyHidden modifier, +
    9. The cl::ReallyHidden modifier indicates that the option should not appear in any help output.
    10. @@ -1255,7 +1252,7 @@ indicates that the option must be specified at least one time.
    11. The cl::ConsumeAfter modifier is described in the Positional arguments section
    12. +href="#positional">Positional arguments section. @@ -1328,7 +1325,7 @@

      The formatting option group is used to specify that the command line option has special abilities and is otherwise different from other command line -arguments. As usual, you can only specify at most one of these arguments.

      +arguments. As usual, you can only specify one of these arguments at most.

        @@ -1337,7 +1334,7 @@ "normal".
      • The cl::Positional modifier -specifies that this is a positional argument, that does not have a command line +specifies that this is a positional argument that does not have a command line option associated with it. See the Positional Arguments section for more information.
      • @@ -1358,7 +1355,7 @@ specified.
      • The cl::Grouping modifier is used -to implement unix style tools (like ls) that have lots of single letter +to implement Unix-style tools (like ls) that have lots of single letter arguments, but only require a single dash. For example, the 'ls -labF' command actually enables four different options, all of which are single letters. Note that cl::Grouping @@ -1426,7 +1423,7 @@ positional arguments, and only makes sense for lists) indicates that positional argument should consume any strings after it (including strings that start with a "-") up until another recognized positional argument. For example, if you -have two "eating" positional arguments "pos1" and "pos2" the +have two "eating" positional arguments, "pos1" and "pos2", the string "-pos1 -foo -bar baz -pos2 -bork" would cause the "-foo -bar -baz" strings to be applied to the "-pos1" option and the "-bork" string to be applied to the "-pos2" option.
      • @@ -1487,14 +1484,14 @@ href="#cl::ParseCommandLineOptions">cl::ParseCommandLineOptions, except that it is designed to take values for options from an environment variable, for those cases in which reading the command line is not convenient or -not desired. It fills in the values of all the command line option variables -just like cl::ParseCommandLineOptions does.

        -

        It takes three parameters: first, the name of the program (since -argv may not be available, it can't just look in argv[0]), -second, the name of the environment variable to examine, and third, the optional +

        It takes three parameters: the name of the program (since argv may +not be available, it can't just look in argv[0]), the name of the +environment variable to examine, and the optional additional extra text to emit when the --help option is invoked.

        @@ -1518,7 +1515,7 @@

        The cl::SetVersionPrinter function is designed to be called -directly from main, and before +directly from main and before cl::ParseCommandLineOptions. Its use is optional. It simply arranges for a function to be called in response to the --version option instead of having the CommandLine library print out the usual version string @@ -1783,7 +1780,7 @@

        This approach works well in situations where you would line to parse an option using special syntax for a not-very-special data-type. The drawback of this approach is that users of your parser have to be aware that they are using -your parser, instead of the builtin ones.

        +your parser instead of the builtin ones.

        @@ -1807,16 +1804,16 @@

      Our new class inherits from the cl::basic_parser template class to -fill in the default, boiler plate, code for us. We give it the data type that -we parse into (the last argument to the parse method so that clients of -our custom parser know what object type to pass in to the parse method (here we -declare that we parse into 'unsigned' variables.

      +fill in the default, boiler plate code for us. We give it the data type that +we parse into, the last argument to the parse method, so that clients of +our custom parser know what object type to pass in to the parse method. (Here we +declare that we parse into 'unsigned' variables.)

      For most purposes, the only method that must be implemented in a custom parser is the parse method. The parse method is called whenever the option is invoked, passing in the option itself, the option name, the string to parse, and a reference to a return value. If the string to parse -is not well formed, the parser should output an error message and return true. +is not well-formed, the parser should output an error message and return true. Otherwise it should return false and set 'Val' to the parsed value. In our example, we implement parse as:

      From clattner at apple.com Wed Jan 9 13:29:17 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Jan 2008 11:29:17 -0800 Subject: [llvm-commits] CommandLine.html patch In-Reply-To: <16507.137.201.242.130.1199901267.squirrel@webmail.nwind.net> References: <62094.137.201.242.130.1199900040.squirrel@webmail.nwind.net> <16507.137.201.242.130.1199901267.squirrel@webmail.nwind.net> Message-ID: On Jan 9, 2008, at 9:54 AM, Sam Bishop wrote: > On Wed, January 9, 2008 10:34 am, Sam Bishop wrote: >> Also, I was confused by one of the examples regarding the handling of >> program-wide global options such as a debug flag >> ... >> I'm very new to LLVM, so I can only guess at how DOUT is related to >> DEBUG(). >> Is there another example that would be more straightforward? > > On second thought, I'd recommend simply removing the DOUT example > from the > comment. I have attached an updated patch. Very nice, applied, thanks! http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080107/056997.html -Chris From baldrick at free.fr Wed Jan 9 13:42:09 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 09 Jan 2008 19:42:09 -0000 Subject: [llvm-commits] [llvm] r45781 - in /llvm/trunk/lib/System: DynamicLibrary.cpp Path.cpp Message-ID: <200801091942.m09Jg9i3022848@zion.cs.uiuc.edu> Author: baldrick Date: Wed Jan 9 13:42:09 2008 New Revision: 45781 URL: http://llvm.org/viewvc/llvm-project?rev=45781&view=rev Log: Fix compile failures with g++-4.3. Modified: llvm/trunk/lib/System/DynamicLibrary.cpp llvm/trunk/lib/System/Path.cpp Modified: llvm/trunk/lib/System/DynamicLibrary.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/DynamicLibrary.cpp?rev=45781&r1=45780&r2=45781&view=diff ============================================================================== --- llvm/trunk/lib/System/DynamicLibrary.cpp (original) +++ llvm/trunk/lib/System/DynamicLibrary.cpp Wed Jan 9 13:42:09 2008 @@ -13,6 +13,7 @@ #include "llvm/System/DynamicLibrary.h" #include "llvm/Config/config.h" +#include #include // Collection of symbol name/value pairs to be searched prior to any libraries. Modified: llvm/trunk/lib/System/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Path.cpp?rev=45781&r1=45780&r2=45781&view=diff ============================================================================== --- llvm/trunk/lib/System/Path.cpp (original) +++ llvm/trunk/lib/System/Path.cpp Wed Jan 9 13:42:09 2008 @@ -14,6 +14,7 @@ #include "llvm/System/Path.h" #include "llvm/Config/config.h" #include +#include #include using namespace llvm; using namespace sys; From duncan.sands at math.u-psud.fr Wed Jan 9 14:43:26 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Wed, 9 Jan 2008 21:43:26 +0100 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> Message-ID: <200801092143.27891.duncan.sands@math.u-psud.fr> Hi Dale, thanks for fixing this. > +/// FixBaseClassFields - alter the types referred to by Field nodes that Do you really have to modify the fields of the record? Instead, you could have a map in ConvertRECORD (possibly in StructTypeConversionInfo) that gives the type to use for each field [currently you use the record as the map, stashing the new type there] or just calculate the type in ConvertRECORD and pass the type as an extra parameter to all subroutines or somesuch. Alternatively, couldn't you just convert the original field type to LLVM then drop fields off the end of the LLVM type if they go over the DECL_SIZE, or something along those lines? > + TREE_INT_CST_LOW(DECL_SIZE(Field)) < > + TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) This probably kills Ada (testing now), since the size doesn't have to be a constant in general (likewise in RestoreBaseClassFields). Ciao, Duncan. From dalej at apple.com Wed Jan 9 15:03:06 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 9 Jan 2008 13:03:06 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <200801092143.27891.duncan.sands@math.u-psud.fr> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> <200801092143.27891.duncan.sands@math.u-psud.fr> Message-ID: On Jan 9, 2008, at 12:43 PM, Duncan Sands wrote: > Hi Dale, thanks for fixing this. > >> +/// FixBaseClassFields - alter the types referred to by Field >> nodes that > > Do you really have to modify the fields of the record? Instead, you > could > have a map in ConvertRECORD (possibly in StructTypeConversionInfo) > that gives > the type to use for each field [currently you use the record as the > map, stashing > the new type there] or just calculate the type in ConvertRECORD and > pass the type > as an extra parameter to all subroutines or somesuch. > > Alternatively, couldn't you just convert the original field type to > LLVM then drop > fields off the end of the LLVM type if they go over the DECL_SIZE, > or something > along those lines? Other implementations may be possible. This approach (which I agree has unaesthetic aspects) makes minimal changes to existing logic; I think that's a fairly important virtue. The idea I liked best was to get the C++ FE to generate the right fields in the first place, but couldn't get it to work. >> + TREE_INT_CST_LOW(DECL_SIZE(Field)) < >> + TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) > > This probably kills Ada (testing now), since the size doesn't have > to be > a constant in general (likewise in RestoreBaseClassFields). OK, didn't know that. That's an easy fix. I figured if I broke Ada somebody would tell me :) From dalej at apple.com Wed Jan 9 15:13:22 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 9 Jan 2008 13:13:22 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45757 - in /llvm-gcc-4.2/trunk/gcc: llvm-types.cpp tree.c tree.h In-Reply-To: <200801092143.27891.duncan.sands@math.u-psud.fr> References: <200801082108.m08L8vjH005155@zion.cs.uiuc.edu> <200801092143.27891.duncan.sands@math.u-psud.fr> Message-ID: <29652C19-322E-4DA0-B2C5-024B9B22E36C@apple.com> The patch below should address this problem, let me know. On Jan 9, 2008, at 12:43 PM, Duncan Sands wrote: >> + TREE_INT_CST_LOW(DECL_SIZE(Field)) < >> + TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) > > This probably kills Ada (testing now), since the size doesn't have > to be > a constant in general (likewise in RestoreBaseClassFields). Index: llvm-types.cpp =================================================================== --- llvm-types.cpp (revision 45777) +++ llvm-types.cpp (working copy) @@ -1696,6 +1696,8 @@ TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE && TYPE_SIZE(TREE_TYPE(Field)) && DECL_SIZE(Field) && + TREE_CODE(DECL_SIZE(Field))==INTEGER_CST && + TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST && TREE_INT_CST_LOW(DECL_SIZE(Field)) < TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) TREE_TYPE(Field) = FixBaseClassField(Field); From lattner at apple.com Wed Jan 9 16:03:35 2008 From: lattner at apple.com (Tanya Lattner) Date: Wed, 9 Jan 2008 14:03:35 -0800 Subject: [llvm-commits] [llvm] r45775 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <200801091041.m09AfgHe026801@zion.cs.uiuc.edu> References: <200801091041.m09AfgHe026801@zion.cs.uiuc.edu> Message-ID: Just glancing at this briefly for the first time. I really think that runOnMachineFunction could benefit from comments that give an overview of the algorithm. Secondly, the classes/structs and member variables could also use some comments. You should also explain what a dominance forest/node is and maybe some more comments on its construction. I'd also more closely document the trivial interferences. I know this stuff is in the paper, but it makes your code easier to understand for people who haven't read it. Yes, I'm a comment freak. Is the DFS numbering of the MachineFunction something that would be useful for other optimizations? Maybe it could be pulled out and used as an analysis? -Tanya On Jan 9, 2008, at 2:41 AM, Owen Anderson wrote: > Author: resistor > Date: Wed Jan 9 04:41:39 2008 > New Revision: 45775 > > URL: http://llvm.org/viewvc/llvm-project?rev=45775&view=rev > Log: > StrongPHIElim: Now with even fewer trivial bugs! > > Modified: > llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > > Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ > StrongPHIElimination.cpp?rev=45775&r1=45774&r2=45775&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) > +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 > 04:41:39 2008 > @@ -215,7 +215,9 @@ > stack.pop_back(); > CurrentParent = stack.back(); > > - parentBlock = LV.getVarInfo(CurrentParent->getReg()).DefInst- > >getParent(); > + parentBlock = CurrentParent->getReg() ? > + LV.getVarInfo(CurrentParent->getReg()).DefInst- > >getParent() : > + 0; > } > > DomForestNode* child = new DomForestNode(*I, CurrentParent); > @@ -361,7 +363,7 @@ > std::set ProcessedNames; > > MachineBasicBlock::iterator P = MBB->begin(); > - while (P->getOpcode() == TargetInstrInfo::PHI) { > + while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { > LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand > (0).getReg()); > > unsigned DestReg = P->getOperand(0).getReg(); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From resistor at mac.com Wed Jan 9 16:40:55 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 09 Jan 2008 22:40:55 -0000 Subject: [llvm-commits] [llvm] r45783 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801092240.m09Meuif032153@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 16:40:54 2008 New Revision: 45783 URL: http://llvm.org/viewvc/llvm-project?rev=45783&view=rev Log: Clean up StrongPHIElimination a bit, and add some more comments to the internal structures. There's still more work to do on this front. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45783&r1=45782&r2=45783&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 16:40:54 2008 @@ -39,13 +39,28 @@ static char ID; // Pass identification, replacement for typeid StrongPHIElimination() : MachineFunctionPass((intptr_t)&ID) {} + // Waiting stores, for each MBB, the set of copies that need to + // be inserted into that MBB DenseMap > Waiting; + // Stacks holds the renaming stack for each register std::map > Stacks; + + // Registers in UsedByAnother are PHI nodes that are themselves + // used as operands to another another PHI node std::set UsedByAnother; + + // RenameSets are the sets of operands to a PHI (the defining instruction + // of the key) that can be renamed without copies std::map > RenameSets; + // Store the DFS-in number of each block + DenseMap preorder; + + // Store the DFS-out number of each block + DenseMap maxpreorder; + bool runOnMachineFunction(MachineFunction &Fn); virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -59,19 +74,32 @@ maxpreorder.clear(); Waiting.clear(); + Stacks.clear(); + UsedByAnother.clear(); + RenameSets.clear(); } private: + + /// DomForestNode - Represents a node in the "dominator forest". This is + /// a forest in which the nodes represent registers and the edges + /// represent a dominance relation in the block defining those registers. struct DomForestNode { private: + // Store references to our children std::vector children; + // The register we represent unsigned reg; + // Add another node as our child void addChild(DomForestNode* DFN) { children.push_back(DFN); } public: typedef std::vector::iterator iterator; + // Create a DomForestNode by providing the register it represents, and + // the node to be its parent. The virtual root node has register 0 + // and a null parent. DomForestNode(unsigned r, DomForestNode* parent) : reg(r) { if (parent) parent->addChild(this); @@ -82,16 +110,14 @@ delete *I; } + /// getReg - Return the regiser that this node represents inline unsigned getReg() { return reg; } + // Provide iterator access to our children inline DomForestNode::iterator begin() { return children.begin(); } inline DomForestNode::iterator end() { return children.end(); } }; - DenseMap preorder; - DenseMap maxpreorder; - - void computeDFS(MachineFunction& MF); void processBlock(MachineBasicBlock* MBB); @@ -188,22 +214,28 @@ StrongPHIElimination::computeDomForest(std::set& regs) { LiveVariables& LV = getAnalysis(); + // Begin by creating a virtual root node, since the actual results + // may well be a forest. Assume this node has maximum DFS-out number. DomForestNode* VirtualRoot = new DomForestNode(0, 0); maxpreorder.insert(std::make_pair((MachineBasicBlock*)0, ~0UL)); + // Populate a worklist with the registers std::vector worklist; worklist.reserve(regs.size()); for (std::set::iterator I = regs.begin(), E = regs.end(); I != E; ++I) worklist.push_back(*I); + // Sort the registers by the DFS-in number of their defining block PreorderSorter PS(preorder, LV); std::sort(worklist.begin(), worklist.end(), PS); + // Create a "current parent" stack, and put the virtual root on top of it DomForestNode* CurrentParent = VirtualRoot; std::vector stack; stack.push_back(VirtualRoot); + // Iterate over all the registers in the previously computed order for (std::vector::iterator I = worklist.begin(), E = worklist.end(); I != E; ++I) { unsigned pre = preorder[LV.getVarInfo(*I).DefInst->getParent()]; @@ -211,6 +243,8 @@ LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent() : 0; + // If the DFS-in number of the register is greater than the DFS-out number + // of the current parent, repeatedly pop the parent stack until it isn't. while (pre > maxpreorder[parentBlock]) { stack.pop_back(); CurrentParent = stack.back(); @@ -220,11 +254,16 @@ 0; } + // Now that we've found the appropriate parent, create a DomForestNode for + // this register and attach it to the forest DomForestNode* child = new DomForestNode(*I, CurrentParent); + + // Push this new node on the "current parent" stack stack.push_back(child); CurrentParent = child; } + // Return a vector containing the children of the virtual root node std::vector ret; ret.insert(ret.end(), VirtualRoot->begin(), VirtualRoot->end()); return ret; @@ -269,8 +308,9 @@ /// trick parameter is 'mode' which tells it the relationship of the two /// registers. 0 - defined in the same block, 1 - first properly dominates /// second, 2 - second properly dominates first -static bool interferes(LiveVariables::VarInfo& First, LiveVariables::VarInfo& Second, - MachineBasicBlock* scan, unsigned mode) { +static bool interferes(LiveVariables::VarInfo& First, + LiveVariables::VarInfo& Second, + MachineBasicBlock* scan, unsigned mode) { MachineInstr* def = 0; MachineInstr* kill = 0; From evan.cheng at apple.com Wed Jan 9 17:01:56 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Jan 2008 23:01:56 -0000 Subject: [llvm-commits] [llvm] r45787 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp test/CodeGen/X86/2008-01-08-SchedulerCrash.ll Message-ID: <200801092301.m09N1u6l000788@zion.cs.uiuc.edu> Author: evancheng Date: Wed Jan 9 17:01:55 2008 New Revision: 45787 URL: http://llvm.org/viewvc/llvm-project?rev=45787&view=rev Log: Special copy SUnit's do not have SDNode's. Added: llvm/trunk/test/CodeGen/X86/2008-01-08-SchedulerCrash.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=45787&r1=45786&r2=45787&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Jan 9 17:01:55 2008 @@ -1208,13 +1208,13 @@ for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { if (I->isCtrl) continue; // ignore chain preds - if (I->Dep->Node->getOpcode() != ISD::CopyFromReg) + if (!I->Dep->Node || I->Dep->Node->getOpcode() != ISD::CopyFromReg) Scratches++; } for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { if (I->isCtrl) continue; // ignore chain succs - if (I->Dep->Node->getOpcode() != ISD::CopyToReg) + if (!I->Dep->Node || I->Dep->Node->getOpcode() != ISD::CopyToReg) Scratches += 10; } return Scratches; Added: llvm/trunk/test/CodeGen/X86/2008-01-08-SchedulerCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-01-08-SchedulerCrash.ll?rev=45787&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-01-08-SchedulerCrash.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-01-08-SchedulerCrash.ll Wed Jan 9 17:01:55 2008 @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | llc -march=x86 + + %struct.indexentry = type { i32, i8*, i8*, i8*, i8*, i8* } + +define i32 @_bfd_stab_section_find_nearest_line(i32 %offset) nounwind { +entry: + %tmp910 = add i32 0, %offset ; [#uses=1] + br i1 true, label %bb951, label %bb917 + +bb917: ; preds = %entry + ret i32 0 + +bb951: ; preds = %bb986, %entry + %tmp955 = sdiv i32 0, 2 ; [#uses=3] + %tmp961 = getelementptr %struct.indexentry* null, i32 %tmp955, i32 0 ; [#uses=1] + br i1 true, label %bb986, label %bb967 + +bb967: ; preds = %bb951 + ret i32 0 + +bb986: ; preds = %bb951 + %tmp993 = load i32* %tmp961, align 4 ; [#uses=1] + %tmp995 = icmp ugt i32 %tmp993, %tmp910 ; [#uses=2] + %tmp1002 = add i32 %tmp955, 1 ; [#uses=1] + %low.0 = select i1 %tmp995, i32 0, i32 %tmp1002 ; [#uses=1] + %high.0 = select i1 %tmp995, i32 %tmp955, i32 0 ; [#uses=1] + %tmp1006 = icmp eq i32 %low.0, %high.0 ; [#uses=1] + br i1 %tmp1006, label %UnifiedReturnBlock, label %bb951 + +UnifiedReturnBlock: ; preds = %bb986 + ret i32 1 +} From resistor at mac.com Wed Jan 9 18:01:41 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 10 Jan 2008 00:01:41 -0000 Subject: [llvm-commits] [llvm] r45791 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801100001.m0A01f3N004760@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 18:01:41 2008 New Revision: 45791 URL: http://llvm.org/viewvc/llvm-project?rev=45791&view=rev Log: Copies need to be inserted before the first terminator, not at the end of the block. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45791&r1=45790&r2=45791&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 18:01:41 2008 @@ -613,7 +613,7 @@ } // Insert copy from map[curr.first] to curr.second - TII->copyRegToReg(*MBB, MBB->end(), curr.second, + TII->copyRegToReg(*MBB, MBB->getFirstTerminator(), curr.second, map[curr.first], RC, RC); map[curr.first] = curr.second; @@ -642,7 +642,7 @@ // Insert a copy from dest to a new temporary t at the end of b unsigned t = MF->getRegInfo().createVirtualRegister(RC); - TII->copyRegToReg(*MBB, MBB->end(), t, + TII->copyRegToReg(*MBB, MBB->getFirstTerminator(), t, curr.second, RC, RC); map[curr.second] = t; From evan.cheng at apple.com Wed Jan 9 18:09:10 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 00:09:10 -0000 Subject: [llvm-commits] [llvm] r45792 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801100009.m0A09AK8005161@zion.cs.uiuc.edu> Author: evancheng Date: Wed Jan 9 18:09:10 2008 New Revision: 45792 URL: http://llvm.org/viewvc/llvm-project?rev=45792&view=rev Log: Remove comments that do not correspond to anything after recent refactoring. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45792&r1=45791&r2=45792&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Jan 9 18:09:10 2008 @@ -1209,6 +1209,34 @@ &ArgValues[0], ArgValues.size()).getValue(Op.ResNo); } +SDOperand +X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG, + const SDOperand &StackPtr, + const CCValAssign &VA, + SDOperand Chain, + SDOperand Arg) { + SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); + unsigned Flags = cast(FlagsOp)->getValue(); + if (Flags & ISD::ParamFlags::ByVal) { + unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> + ISD::ParamFlags::ByValAlignOffs); + + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> + ISD::ParamFlags::ByValSizeOffs; + + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); + SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32); + + return DAG.getMemcpy(Chain, PtrOff, Arg, SizeNode, AlignNode, + AlwaysInline); + } else { + return DAG.getStore(Chain, Arg, PtrOff, NULL, 0); + } +} + SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); SDOperand Chain = Op.getOperand(0); @@ -1524,47 +1552,6 @@ //===----------------------------------------------------------------------===// -// FastCall Calling Convention implementation -//===----------------------------------------------------------------------===// -// -// The X86 'fastcall' calling convention passes up to two integer arguments in -// registers (an appropriate portion of ECX/EDX), passes arguments in C order, -// and requires that the callee pop its arguments off the stack (allowing proper -// tail calls), and has the same return value conventions as C calling convs. -// -// This calling convention always arranges for the callee pop value to be 8n+4 -// bytes, which is needed for tail recursion elimination and stack alignment -// reasons. - -SDOperand -X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG, - const SDOperand &StackPtr, - const CCValAssign &VA, - SDOperand Chain, - SDOperand Arg) { - SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); - SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); - unsigned Flags = cast(FlagsOp)->getValue(); - if (Flags & ISD::ParamFlags::ByVal) { - unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> - ISD::ParamFlags::ByValAlignOffs); - - unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> - ISD::ParamFlags::ByValSizeOffs; - - SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); - SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); - SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32); - - return DAG.getMemcpy(Chain, PtrOff, Arg, SizeNode, AlignNode, - AlwaysInline); - } else { - return DAG.getStore(Chain, Arg, PtrOff, NULL, 0); - } -} - -//===----------------------------------------------------------------------===// // Fast Calling Convention (tail call) implementation //===----------------------------------------------------------------------===// From sabre at nondot.org Wed Jan 9 18:30:38 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 00:30:38 -0000 Subject: [llvm-commits] [llvm] r45795 - /llvm/trunk/test/CodeGen/Generic/bool-vector.ll Message-ID: <200801100030.m0A0UcbB006467@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 18:30:38 2008 New Revision: 45795 URL: http://llvm.org/viewvc/llvm-project?rev=45795&view=rev Log: new testcase for PR1845 Added: llvm/trunk/test/CodeGen/Generic/bool-vector.ll Added: llvm/trunk/test/CodeGen/Generic/bool-vector.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/bool-vector.ll?rev=45795&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Generic/bool-vector.ll (added) +++ llvm/trunk/test/CodeGen/Generic/bool-vector.ll Wed Jan 9 18:30:38 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc +; PR1845 + +define void @boolVectorSelect(<4 x i1>* %boolVectorPtr) { +Body: + %castPtr = bitcast <4 x i1>* %boolVectorPtr to <4 x i1>* + %someBools = load <4 x i1>* %castPtr, align 1 ; <<4 x i1>> + %internal = alloca <4 x i1>, align 16 ; <<4 x i1>*> [#uses=1] + store <4 x i1> %someBools, <4 x i1>* %internal, align 1 + ret void +} From sabre at nondot.org Wed Jan 9 18:30:58 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 00:30:58 -0000 Subject: [llvm-commits] [llvm] r45796 - in /llvm/trunk: include/llvm/Target/TargetData.h lib/Target/TargetData.cpp Message-ID: <200801100030.m0A0UwoY006494@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 18:30:57 2008 New Revision: 45796 URL: http://llvm.org/viewvc/llvm-project?rev=45796&view=rev Log: Fix PR1845 and rdar://5676945. Generic vectors smaller than hardware supported type will be scalarized, so we can infer their alignment from that info. We now codegen pr1845 into: _boolVectorSelect: lbz r2, 0(r3) stb r2, -16(r1) blr Modified: llvm/trunk/include/llvm/Target/TargetData.h llvm/trunk/lib/Target/TargetData.cpp Modified: llvm/trunk/include/llvm/Target/TargetData.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=45796&r1=45795&r2=45796&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetData.h (original) +++ llvm/trunk/include/llvm/Target/TargetData.h Wed Jan 9 18:30:57 2008 @@ -92,7 +92,7 @@ void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width); unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, - bool ABIAlign) const; + bool ABIAlign, const Type *Ty) const; //! Internal helper method that returns requested alignment for type. unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const; Modified: llvm/trunk/lib/Target/TargetData.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=45796&r1=45795&r2=45796&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetData.cpp (original) +++ llvm/trunk/lib/Target/TargetData.cpp Wed Jan 9 18:30:57 2008 @@ -154,7 +154,8 @@ p:@verbatim::@endverbatim: Pointer size, ABI and preferred alignment.

      - @verbatim::@endverbatim: Numeric type alignment. Type is + @verbatim::@endverbatim: Numeric type + alignment. Type is one of i|f|v|a, corresponding to integer, floating point, vector (aka packed) or aggregate. Size indicates the size, e.g., 32 or 64 bits. \p @@ -258,7 +259,8 @@ /// getAlignmentInfo - Return the alignment (either ABI if ABIInfo = true or /// preferred if ABIInfo = false) the target wants for the specified datatype. unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, - uint32_t BitWidth, bool ABIInfo) const { + uint32_t BitWidth, bool ABIInfo, + const Type *Ty) const { // Check to see if we have an exact match and remember the best match we see. int BestMatchIdx = -1; int LargestInt = -1; @@ -293,14 +295,22 @@ } } - // For integers, if we didn't find a best match, use the largest one found. - if (BestMatchIdx == -1) - BestMatchIdx = LargestInt; - // Okay, we didn't find an exact solution. Fall back here depending on what // is being looked for. - assert(BestMatchIdx != -1 && "Didn't find alignment info for this datatype!"); - + if (BestMatchIdx == -1) { + // If we didn't find an integer alignment, fall back on most conservative. + if (AlignType == INTEGER_ALIGN) { + BestMatchIdx = LargestInt; + } else { + assert(AlignType == VECTOR_ALIGN && "Unknown alignment type!"); + + // If we didn't find a vector size that is smaller or equal to this type, + // then we will end up scalarizing this to its element type. Just return + // the alignment of the element. + return getAlignment(cast(Ty)->getElementType(), ABIInfo); + } + } + // Since we got a "best match" index, just return it. return ABIInfo ? Alignments[BestMatchIdx].ABIAlign : Alignments[BestMatchIdx].PrefAlign; @@ -474,7 +484,7 @@ // Get the layout annotation... which is lazily created on demand. const StructLayout *Layout = getStructLayout(cast(Ty)); - unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref); + unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty); return std::max(Align, (unsigned)Layout->getAlignment()); } case Type::IntegerTyID: @@ -490,22 +500,16 @@ case Type::X86_FP80TyID: AlignType = FLOAT_ALIGN; break; - case Type::VectorTyID: { - const VectorType *VTy = cast(Ty); - // Degenerate vectors are assumed to be scalar-ized - if (VTy->getNumElements() == 1) - return getAlignment(VTy->getElementType(), abi_or_pref); - else - AlignType = VECTOR_ALIGN; + case Type::VectorTyID: + AlignType = VECTOR_ALIGN; break; - } default: assert(0 && "Bad type for getAlignment!!!"); break; } return getAlignmentInfo((AlignTypeEnum)AlignType, getTypeSizeInBits(Ty), - abi_or_pref); + abi_or_pref, Ty); } unsigned char TargetData::getABITypeAlignment(const Type *Ty) const { From resistor at mac.com Wed Jan 9 18:33:13 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 10 Jan 2008 00:33:13 -0000 Subject: [llvm-commits] [llvm] r45797 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801100033.m0A0XDbg006792@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 18:33:11 2008 New Revision: 45797 URL: http://llvm.org/viewvc/llvm-project?rev=45797&view=rev Log: Get rid of the isKillInst predicate. LiveVariables already provides this information. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45797&r1=45796&r2=45797&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 18:33:11 2008 @@ -298,22 +298,18 @@ return false; } -/// isKillInst - helper method that determines, from a VarInfo, if an -/// instruction kills a given register -static bool isKillInst(LiveVariables::VarInfo& V, MachineInstr* MI) { - return std::find(V.Kills.begin(), V.Kills.end(), MI) != V.Kills.end(); -} - /// interferes - checks for local interferences by scanning a block. The only /// trick parameter is 'mode' which tells it the relationship of the two /// registers. 0 - defined in the same block, 1 - first properly dominates /// second, 2 - second properly dominates first -static bool interferes(LiveVariables::VarInfo& First, - LiveVariables::VarInfo& Second, - MachineBasicBlock* scan, unsigned mode) { +static bool interferes(unsigned a, unsigned b, MachineBasicBlock* scan, + LiveVariables& LV, unsigned mode) { MachineInstr* def = 0; MachineInstr* kill = 0; + LiveVariables::VarInfo& First = LV.getVarInfo(a); + LiveVariables::VarInfo& Second = LV.getVarInfo(b); + bool interference = false; // Wallk the block, checking for interferences @@ -350,10 +346,10 @@ break; } // Store KillInsts if they match up with the DefInst - } else if (isKillInst(First, curr)) { + } else if (LV.KillsRegister(curr, a)) { if (def == First.DefInst) { kill = curr; - } else if (isKillInst(Second, curr)) { + } else if (LV.KillsRegister(curr, b)) { if (def == Second.DefInst) { kill = curr; } @@ -372,7 +368,7 @@ break; } // Save KillInsts of First - } else if (isKillInst(First, curr)) { + } else if (LV.KillsRegister(curr, a)) { kill = curr; } // Symmetric with the above @@ -385,7 +381,7 @@ interference = false; break; } - } else if (isKillInst(Second, curr)) { + } else if (LV.KillsRegister(curr, b)) { kill = curr; } } @@ -468,7 +464,7 @@ } // If there's an interference, we need to insert copies - if (interferes(FirstInfo, SecondInfo, scan, mode)) { + if (interferes(p.first, p.second, scan, LV, mode)) { // Insert copies for First for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { if (P->getOperand(i-1).getReg() == p.first) { From evan.cheng at apple.com Wed Jan 9 18:37:26 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 00:37:26 -0000 Subject: [llvm-commits] [llvm] r45798 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801100037.m0A0bQmJ007001@zion.cs.uiuc.edu> Author: evancheng Date: Wed Jan 9 18:37:26 2008 New Revision: 45798 URL: http://llvm.org/viewvc/llvm-project?rev=45798&view=rev Log: Do not use the stack pointer directly, issue a copyfromreg instead. Otherwise we can end up with something like ADD32ri %esp, x which two-address pass won't like. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45798&r1=45797&r2=45798&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Jan 9 18:37:26 2008 @@ -1332,7 +1332,7 @@ } else { assert(VA.isMemLoc()); if (StackPtr.Val == 0) - StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy()); + StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain, Arg)); From resistor at mac.com Wed Jan 9 18:47:01 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 10 Jan 2008 00:47:01 -0000 Subject: [llvm-commits] [llvm] r45799 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801100047.m0A0l2OL007469@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 18:47:01 2008 New Revision: 45799 URL: http://llvm.org/viewvc/llvm-project?rev=45799&view=rev Log: Add more comments explaining the basics of how the decision of when to rename and when to insert copies is made. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45799&r1=45798&r2=45799&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 18:47:01 2008 @@ -390,7 +390,10 @@ return interference; } -/// processBlock - Eliminate PHIs in the given block +/// processBlock - Determine how to break up PHIs in the current block. Each +/// PHI is broken up by some combination of renaming its operands and inserting +/// copies. This method is responsible for determining which operands receive +/// which treatment. void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { LiveVariables& LV = getAnalysis(); @@ -398,21 +401,37 @@ // before the current one. std::set ProcessedNames; + // Iterate over all the PHI nodes in this block MachineBasicBlock::iterator P = MBB->begin(); while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand(0).getReg()); unsigned DestReg = P->getOperand(0).getReg(); - // Hold the names that are currently in the candidate set. + // PHIUnion is the set of incoming registers to the PHI node that + // are going to be renames rather than having copies inserted. This set + // is refinded over the course of this function. UnionedBlocks is the set + // of corresponding MBBs. std::set PHIUnion; std::set UnionedBlocks; + // Iterate over the operands of the PHI node for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { unsigned SrcReg = P->getOperand(i-1).getReg(); LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg); - // Check for trivial interferences + // Check for trivial interferences via liveness information, allowing us + // to avoid extra work later. Any registers that interfere cannot both + // be in the renaming set, so choose one and add copies for it instead. + // The conditions are: + // 1) if the operand is live into the PHI node's block OR + // 2) if the PHI node is live out of the operand's defining block OR + // 3) if the operand is itself a PHI node and the original PHI is + // live into the operand's defining block OR + // 4) if the operand is already being renamed for another PHI node + // in this block OR + // 5) if any two operands are defined in the same block, insert copies + // for one of them if (isLiveIn(SrcInfo, P->getParent()) || isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) || ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI && @@ -420,24 +439,32 @@ ProcessedNames.count(SrcReg) || UnionedBlocks.count(SrcInfo.DefInst->getParent())) { - // add a copy from a_i to p in Waiting[From[a_i]] + // Add a copy for the selected register MachineBasicBlock* From = P->getOperand(i).getMBB(); Waiting[From].insert(std::make_pair(SrcReg, DestReg)); UsedByAnother.insert(SrcReg); } else { + // Otherwise, add it to the renaming set PHIUnion.insert(SrcReg); UnionedBlocks.insert(SrcInfo.DefInst->getParent()); } } + // Compute the dominator forest for the renaming set. This is a forest + // where the nodes are the registers and the edges represent dominance + // relations between the defining blocks of the registers std::vector DF = computeDomForest(PHIUnion); - // Walk DomForest to resolve interferences + // Walk DomForest to resolve interferences at an inter-block level. This + // will remove registers from the renaming set (and insert copies for them) + // if interferences are found. std::vector > localInterferences; processPHIUnion(P, PHIUnion, DF, localInterferences); - // Check for local interferences + // The dominator forest walk may have returned some register pairs whose + // interference cannot be determines from dominator analysis. We now + // examine these pairs for local interferences. for (std::vector >::iterator I = localInterferences.begin(), E = localInterferences.end(); I != E; ++I) { std::pair p = *I; @@ -481,10 +508,13 @@ } } - // Cache renaming information + // Add the renaming set for this PHI node to our overal renaming information RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), PHIUnion)); + // Remember which registers are already renamed, so that we don't try to + // rename them for another PHI node in this block ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end()); + ++P; } } From sabre at nondot.org Wed Jan 9 18:48:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 00:48:17 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45800 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200801100048.m0A0mHI2007550@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 18:48:14 2008 New Revision: 45800 URL: http://llvm.org/viewvc/llvm-project?rev=45800&view=rev Log: Fix a "bug" introduced by attribute(annotate). Before this patch it would always call " ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl));" even if there are no annotate attributes on a global, causing the string to be emitted and unused. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=45800&r1=45799&r2=45800&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Jan 9 18:48:14 2008 @@ -754,12 +754,14 @@ // Handle annotate attribute on global. tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); + if (annotateAttr == 0) + return; // Get file and line number - Constant *lineNo = ConstantInt::get(Type::Int32Ty, DECL_SOURCE_LINE(decl)); - Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl)); - const Type *SBP= PointerType::getUnqual(Type::Int8Ty); - file = ConstantExpr::getBitCast(file, SBP); + Constant *lineNo = ConstantInt::get(Type::Int32Ty, DECL_SOURCE_LINE(decl)); + Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl)); + const Type *SBP= PointerType::getUnqual(Type::Int8Ty); + file = ConstantExpr::getBitCast(file, SBP); // There may be multiple annotate attributes. Pass return of lookup_attr // to successive lookups. @@ -779,10 +781,12 @@ assert(TREE_CODE(val) == STRING_CST && "Annotate attribute arg should always be a string"); Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); - Constant *Element[4] = {ConstantExpr::getBitCast(GV,SBP), + Constant *Element[4] = { + ConstantExpr::getBitCast(GV,SBP), ConstantExpr::getBitCast(strGV,SBP), file, - lineNo}; + lineNo + }; AttributeAnnotateGlobals.push_back(ConstantStruct::get(Element, 4, false)); } From sabre at nondot.org Wed Jan 9 18:48:43 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 00:48:43 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r45801 - /llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Message-ID: <200801100048.m0A0mhWk007577@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 18:48:43 2008 New Revision: 45801 URL: http://llvm.org/viewvc/llvm-project?rev=45801&view=rev Log: Fix a "bug" introduced by attribute(annotate). Before this patch it would always call " ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl));" even if there are no annotate attributes on a global, causing the string to be emitted and unused. Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=45801&r1=45800&r2=45801&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Wed Jan 9 18:48:43 2008 @@ -714,12 +714,14 @@ // Handle annotate attribute on global. tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); + if (annotateAttr == 0) + return; // Get file and line number - Constant *lineNo = ConstantInt::get(Type::Int32Ty, DECL_SOURCE_LINE(decl)); - Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl)); - const Type *SBP= PointerType::getUnqual(Type::Int8Ty); - file = ConstantExpr::getBitCast(file, SBP); + Constant *lineNo = ConstantInt::get(Type::Int32Ty, DECL_SOURCE_LINE(decl)); + Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl)); + const Type *SBP= PointerType::getUnqual(Type::Int8Ty); + file = ConstantExpr::getBitCast(file, SBP); // There may be multiple annotate attributes. Pass return of lookup_attr // to successive lookups. @@ -739,10 +741,12 @@ assert(TREE_CODE(val) == STRING_CST && "Annotate attribute arg should always be a string"); Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); - Constant *Element[4] = {ConstantExpr::getBitCast(GV,SBP), + Constant *Element[4] = { + ConstantExpr::getBitCast(GV,SBP), ConstantExpr::getBitCast(strGV,SBP), file, - lineNo}; + lineNo + }; AttributeAnnotateGlobals.push_back(ConstantStruct::get(Element, 4, false)); } From sabre at nondot.org Wed Jan 9 19:01:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 01:01:27 -0000 Subject: [llvm-commits] [llvm] r45803 - /llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Message-ID: <200801100101.m0A11RSh008288@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 19:01:27 2008 New Revision: 45803 URL: http://llvm.org/viewvc/llvm-project?rev=45803&view=rev Log: provide def_* and use_* iterators in addition to reg_* iterators. The first only returns definitions of a register, the second only returns uses, the third returns both. Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=45803&r1=45802&r2=45803&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Wed Jan 9 19:01:27 2008 @@ -64,11 +64,31 @@ /// reg_begin/reg_end - Provide iteration support to walk over all definitions /// and uses of a register within the MachineFunction that corresponds to this /// MachineRegisterInfo object. - class reg_iterator; + template + class defusechain_iterator; + + /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified + /// register. + typedef defusechain_iterator reg_iterator; reg_iterator reg_begin(unsigned RegNo) const { return reg_iterator(getRegUseDefListHead(RegNo)); } static reg_iterator reg_end() { return reg_iterator(0); } + + /// def_iterator/def_begin/def_end - Walk all defs of the specified register. + typedef defusechain_iterator def_iterator; + def_iterator def_begin(unsigned RegNo) const { + return def_iterator(getRegUseDefListHead(RegNo)); + } + static def_iterator def_end() { return def_iterator(0); } + + /// use_iterator/use_begin/use_end - Walk all uses of the specified register. + typedef defusechain_iterator use_iterator; + use_iterator use_begin(unsigned RegNo) const { + return use_iterator(getRegUseDefListHead(RegNo)); + } + static use_iterator use_end() { return use_iterator(0); } + /// replaceRegWith - Replace all instances of FromReg with ToReg in the /// machine function. This is like llvm-level X->replaceAllUsesWith(Y), @@ -174,23 +194,36 @@ void HandleVRegListReallocation(); public: - /// reg_iterator - This class provides iterator support for machine - /// operands in the function that use or define a specific register. - class reg_iterator : public forward_iterator { + /// defusechain_iterator - This class provides iterator support for machine + /// operands in the function that use or define a specific register. If + /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it + /// returns defs. If neither are true then you are silly and it always + /// returns end(). + template + class defusechain_iterator + : public forward_iterator { MachineOperand *Op; - reg_iterator(MachineOperand *op) : Op(op) {} + defusechain_iterator(MachineOperand *op) : Op(op) { + // If the first node isn't one we're interested in, advance to one that + // we are interested in. + if (op) { + if (!ReturnUses && op->isUse() || + !ReturnDefs && op->isDef()) + ++*this; + } + } friend class MachineRegisterInfo; public: typedef forward_iterator::reference reference; typedef forward_iterator::pointer pointer; - reg_iterator(const reg_iterator &I) : Op(I.Op) {} - reg_iterator() : Op(0) {} + defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {} + defusechain_iterator() : Op(0) {} - bool operator==(const reg_iterator &x) const { + bool operator==(const defusechain_iterator &x) const { return Op == x.Op; } - bool operator!=(const reg_iterator &x) const { + bool operator!=(const defusechain_iterator &x) const { return !operator==(x); } @@ -198,13 +231,19 @@ bool atEnd() const { return Op == 0; } // Iterator traversal: forward iteration only - reg_iterator &operator++() { // Preincrement + defusechain_iterator &operator++() { // Preincrement assert(Op && "Cannot increment end iterator!"); Op = Op->getNextOperandForReg(); + + // If this is an operand we don't care about, skip it. + while (Op && (!ReturnUses && Op->isUse() || + !ReturnDefs && Op->isDef())) + Op = Op->getNextOperandForReg(); + return *this; } - reg_iterator operator++(int) { // Postincrement - reg_iterator tmp = *this; ++*this; return tmp; + defusechain_iterator operator++(int) { // Postincrement + defusechain_iterator tmp = *this; ++*this; return tmp; } MachineOperand &getOperand() const { From lattner at apple.com Wed Jan 9 19:15:17 2008 From: lattner at apple.com (Tanya Lattner) Date: Wed, 9 Jan 2008 17:15:17 -0800 Subject: [llvm-commits] [llvm] r45799 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <200801100047.m0A0l2OL007469@zion.cs.uiuc.edu> References: <200801100047.m0A0l2OL007469@zion.cs.uiuc.edu> Message-ID: <86537C11-8206-4E37-8640-93A90A77EFE0@apple.com> Nice! On Jan 9, 2008, at 4:47 PM, Owen Anderson wrote: > Author: resistor > Date: Wed Jan 9 18:47:01 2008 > New Revision: 45799 > > URL: http://llvm.org/viewvc/llvm-project?rev=45799&view=rev > Log: > Add more comments explaining the basics of how the decision of when > to rename and when to insert > copies is made. > > Modified: > llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > > Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ > StrongPHIElimination.cpp?rev=45799&r1=45798&r2=45799&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) > +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 > 18:47:01 2008 > @@ -390,7 +390,10 @@ > return interference; > } > > -/// processBlock - Eliminate PHIs in the given block > +/// processBlock - Determine how to break up PHIs in the current > block. Each > +/// PHI is broken up by some combination of renaming its operands > and inserting > +/// copies. This method is responsible for determining which > operands receive > +/// which treatment. > void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { > LiveVariables& LV = getAnalysis(); > > @@ -398,21 +401,37 @@ > // before the current one. > std::set ProcessedNames; > > + // Iterate over all the PHI nodes in this block > MachineBasicBlock::iterator P = MBB->begin(); > while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { > LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand > (0).getReg()); > > unsigned DestReg = P->getOperand(0).getReg(); > > - // Hold the names that are currently in the candidate set. > + // PHIUnion is the set of incoming registers to the PHI node that > + // are going to be renames rather than having copies > inserted. This set > + // is refinded over the course of this function. > UnionedBlocks is the set > + // of corresponding MBBs. > std::set PHIUnion; > std::set UnionedBlocks; > > + // Iterate over the operands of the PHI node > for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { > unsigned SrcReg = P->getOperand(i-1).getReg(); > LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg); > > - // Check for trivial interferences > + // Check for trivial interferences via liveness information, > allowing us > + // to avoid extra work later. Any registers that interfere > cannot both > + // be in the renaming set, so choose one and add copies for > it instead. > + // The conditions are: > + // 1) if the operand is live into the PHI node's block OR > + // 2) if the PHI node is live out of the operand's > defining block OR > + // 3) if the operand is itself a PHI node and the original > PHI is > + // live into the operand's defining block OR > + // 4) if the operand is already being renamed for another > PHI node > + // in this block OR > + // 5) if any two operands are defined in the same block, > insert copies > + // for one of them > if (isLiveIn(SrcInfo, P->getParent()) || > isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) || > ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI && > @@ -420,24 +439,32 @@ > ProcessedNames.count(SrcReg) || > UnionedBlocks.count(SrcInfo.DefInst->getParent())) { > > - // add a copy from a_i to p in Waiting[From[a_i]] > + // Add a copy for the selected register > MachineBasicBlock* From = P->getOperand(i).getMBB(); > Waiting[From].insert(std::make_pair(SrcReg, DestReg)); > UsedByAnother.insert(SrcReg); > } else { > + // Otherwise, add it to the renaming set > PHIUnion.insert(SrcReg); > UnionedBlocks.insert(SrcInfo.DefInst->getParent()); > } > } > > + // Compute the dominator forest for the renaming set. This is > a forest > + // where the nodes are the registers and the edges represent > dominance > + // relations between the defining blocks of the registers > std::vector DF = > > computeDomForest(PHIUnion); > > - // Walk DomForest to resolve interferences > + // Walk DomForest to resolve interferences at an inter-block > level. This > + // will remove registers from the renaming set (and insert > copies for them) > + // if interferences are found. > std::vector > localInterferences; > processPHIUnion(P, PHIUnion, DF, localInterferences); > > - // Check for local interferences > + // The dominator forest walk may have returned some register > pairs whose > + // interference cannot be determines from dominator analysis. > We now > + // examine these pairs for local interferences. > for (std::vector >::iterator I = > localInterferences.begin(), E = localInterferences.end(); > I != E; ++I) { > std::pair p = *I; > @@ -481,10 +508,13 @@ > } > } > > - // Cache renaming information > + // Add the renaming set for this PHI node to our overal > renaming information > RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), > PHIUnion)); > > + // Remember which registers are already renamed, so that we > don't try to > + // rename them for another PHI node in this block > ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end()); > + > ++P; > } > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Wed Jan 9 19:28:25 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 10 Jan 2008 01:28:25 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45804 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm.h objc/objc-act.c Message-ID: <200801100128.m0A1SPD1010358@zion.cs.uiuc.edu> Author: void Date: Wed Jan 9 19:28:25 2008 New Revision: 45804 URL: http://llvm.org/viewvc/llvm-project?rev=45804&view=rev Log: We're creating incorrect metadata. LLVM gives this for class references: L_OBJC_CLASS_REFERENCES_0: .space 4 .. L_OBJC_CLASS_NAME_0: ... while GCC gives: L_OBJC_CLASS_REFERENCES_0: .long L_OBJC_CLASS_NAME_0 .. L_OBJC_CLASS_NAME_0: ... which is correct. What's happening is that the reference is being created and LLVM is setting it's initializer to "null" because it's not pointing to something at that time. But then reference is modified to point to some object. However, LLVM wasn't updating its initializer information at that point. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp llvm-gcc-4.2/trunk/gcc/llvm.h llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=45804&r1=45803&r2=45804&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Jan 9 19:28:25 2008 @@ -798,6 +798,17 @@ } } +/// reset_initializer_llvm - Change the initializer for a global variable. +void reset_initializer_llvm(tree decl) { + // Get or create the global variable now. + GlobalVariable *GV = cast(DECL_LLVM(decl)); + + // Convert the initializer over. + Constant *Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl)); + + // Set the initializer. + GV->setInitializer(Init); +} /// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to /// LLVM as a global variable. This function implements the end of Modified: llvm-gcc-4.2/trunk/gcc/llvm.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm.h?rev=45804&r1=45803&r2=45804&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm.h Wed Jan 9 19:28:25 2008 @@ -44,12 +44,15 @@ /* make_decl_llvm - This is also defined in tree.h and used by macros there. */ void make_decl_llvm(union tree_node*); +/* reset_initializer_llvm - Change the initializer for a global variable. */ +void reset_initializer_llvm(union tree_node*); + /* emit_global_to_llvm - Emit the specified VAR_DECL to LLVM as a global * variable. */ void emit_global_to_llvm(union tree_node*); -/* emit_global_to_llvm - Emit the specified alias to LLVM +/* emit_alias_to_llvm - Emit the specified alias to LLVM */ void emit_alias_to_llvm(union tree_node*, union tree_node*, union tree_node*); Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=45804&r1=45803&r2=45804&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Wed Jan 9 19:28:25 2008 @@ -76,6 +76,9 @@ #include "langhooks-def.h" /* APPLE LOCAL optimization pragmas 3124235/3420242 */ #include "opts.h" +#ifdef ENABLE_LLVM +#include "llvm.h" /* for reset_initializer_llvm */ +#endif #define OBJC_VOID_AT_END void_list_node @@ -5541,6 +5544,13 @@ { decl = TREE_PURPOSE (chain); finish_var_decl (decl, expr); + /* APPLE LOCAL LLVM begin - radar 5676233 */ +#ifdef ENABLE_LLVM + /* Reset the initializer for this reference as it most likely + changed. */ + reset_initializer_llvm(decl); +#endif + /* APPLE LOCAL LLVM end - radar 5676233 */ } else { @@ -18172,8 +18182,16 @@ for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) { handle_class_ref (chain); - if (TREE_PURPOSE (chain)) + /* APPLE LOCAL LLVM begin - radar 5676233 */ + if (TREE_PURPOSE (chain)) { generate_classref_translation_entry (chain); +#ifdef ENABLE_LLVM + /* Reset the initializer for this reference as it most likely + changed. */ + reset_initializer_llvm(TREE_PURPOSE (chain)); +#endif + } + /* APPLE LOCAL LLVM end - radar 5676233 */ } for (impent = imp_list; impent; impent = impent->next) From resistor at mac.com Wed Jan 9 19:36:43 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 10 Jan 2008 01:36:43 -0000 Subject: [llvm-commits] [llvm] r45805 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <200801100136.m0A1ah2d010938@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 19:36:43 2008 New Revision: 45805 URL: http://llvm.org/viewvc/llvm-project?rev=45805&view=rev Log: Get rid of all uses of LiveVariables::VarInfo::DefInst in favor of the equivalent API from MachineRegisterInfo. Once all clients are switched over, the former will be going away. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45805&r1=45804&r2=45805&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 19:36:43 2008 @@ -121,7 +121,8 @@ void computeDFS(MachineFunction& MF); void processBlock(MachineBasicBlock* MBB); - std::vector computeDomForest(std::set& instrs); + std::vector computeDomForest(std::set& instrs, + MachineRegisterInfo& MRI); void processPHIUnion(MachineInstr* Inst, std::set& PHIUnion, std::vector& DF, @@ -186,18 +187,18 @@ class PreorderSorter { private: DenseMap& preorder; - LiveVariables& LV; + MachineRegisterInfo& MRI; public: PreorderSorter(DenseMap& p, - LiveVariables& L) : preorder(p), LV(L) { } + MachineRegisterInfo& M) : preorder(p), MRI(M) { } bool operator()(unsigned A, unsigned B) { if (A == B) return false; - MachineBasicBlock* ABlock = LV.getVarInfo(A).DefInst->getParent(); - MachineBasicBlock* BBlock = LV.getVarInfo(A).DefInst->getParent(); + MachineBasicBlock* ABlock = MRI.getVRegDef(A)->getParent(); + MachineBasicBlock* BBlock = MRI.getVRegDef(B)->getParent(); if (preorder[ABlock] < preorder[BBlock]) return true; @@ -211,9 +212,8 @@ /// computeDomForest - compute the subforest of the DomTree corresponding /// to the defining blocks of the registers in question std::vector -StrongPHIElimination::computeDomForest(std::set& regs) { - LiveVariables& LV = getAnalysis(); - +StrongPHIElimination::computeDomForest(std::set& regs, + MachineRegisterInfo& MRI) { // Begin by creating a virtual root node, since the actual results // may well be a forest. Assume this node has maximum DFS-out number. DomForestNode* VirtualRoot = new DomForestNode(0, 0); @@ -227,7 +227,7 @@ worklist.push_back(*I); // Sort the registers by the DFS-in number of their defining block - PreorderSorter PS(preorder, LV); + PreorderSorter PS(preorder, MRI); std::sort(worklist.begin(), worklist.end(), PS); // Create a "current parent" stack, and put the virtual root on top of it @@ -238,9 +238,9 @@ // Iterate over all the registers in the previously computed order for (std::vector::iterator I = worklist.begin(), E = worklist.end(); I != E; ++I) { - unsigned pre = preorder[LV.getVarInfo(*I).DefInst->getParent()]; + unsigned pre = preorder[MRI.getVRegDef(*I)->getParent()]; MachineBasicBlock* parentBlock = CurrentParent->getReg() ? - LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent() : + MRI.getVRegDef(CurrentParent->getReg())->getParent() : 0; // If the DFS-in number of the register is greater than the DFS-out number @@ -250,7 +250,7 @@ CurrentParent = stack.back(); parentBlock = CurrentParent->getReg() ? - LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent() : + MRI.getVRegDef(CurrentParent->getReg())->getParent() : 0; } @@ -271,11 +271,13 @@ /// isLiveIn - helper method that determines, from a VarInfo, if a register /// is live into a block -static bool isLiveIn(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) { +static bool isLiveIn(unsigned r, MachineBasicBlock* MBB, + MachineRegisterInfo& MRI, LiveVariables& LV) { + LiveVariables::VarInfo V = LV.getVarInfo(r); if (V.AliveBlocks.test(MBB->getNumber())) return true; - if (V.DefInst->getParent() != MBB && + if (MRI.getVRegDef(r)->getParent() != MBB && V.UsedBlocks.test(MBB->getNumber())) return true; @@ -284,8 +286,10 @@ /// isLiveOut - help method that determines, from a VarInfo, if a register is /// live out of a block. -static bool isLiveOut(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) { - if (MBB == V.DefInst->getParent() || +static bool isLiveOut(unsigned r, MachineBasicBlock* MBB, + MachineRegisterInfo& MRI, LiveVariables& LV) { + LiveVariables::VarInfo& V = LV.getVarInfo(r); + if (MBB == MRI.getVRegDef(r)->getParent() || V.UsedBlocks.test(MBB->getNumber())) { for (std::vector::iterator I = V.Kills.begin(), E = V.Kills.end(); I != E; ++I) @@ -307,8 +311,9 @@ MachineInstr* def = 0; MachineInstr* kill = 0; - LiveVariables::VarInfo& First = LV.getVarInfo(a); - LiveVariables::VarInfo& Second = LV.getVarInfo(b); + // The code is still in SSA form at this point, so there is only one + // definition per VReg. Thus we can safely use MRI->getVRegDef(). + const MachineRegisterInfo* MRI = &scan->getParent()->getRegInfo(); bool interference = false; @@ -319,23 +324,23 @@ // Same defining block... if (mode == 0) { - if (curr == First.DefInst) { - // If we find our first DefInst, save it + if (curr == MRI->getVRegDef(a)) { + // If we find our first definition, save it if (!def) { def = curr; - // If there's already an unkilled DefInst, then + // If there's already an unkilled definition, then // this is an interference } else if (!kill) { interference = true; break; - // If there's a DefInst followed by a KillInst, then + // If there's a definition followed by a KillInst, then // they can't interfere } else { interference = false; break; } // Symmetric with the above - } else if (curr == Second.DefInst ) { + } else if (curr == MRI->getVRegDef(b)) { if (!def) { def = curr; } else if (!kill) { @@ -345,24 +350,24 @@ interference = false; break; } - // Store KillInsts if they match up with the DefInst + // Store KillInsts if they match up with the definition } else if (LV.KillsRegister(curr, a)) { - if (def == First.DefInst) { + if (def == MRI->getVRegDef(a)) { kill = curr; } else if (LV.KillsRegister(curr, b)) { - if (def == Second.DefInst) { + if (def == MRI->getVRegDef(b)) { kill = curr; } } } // First properly dominates second... } else if (mode == 1) { - if (curr == Second.DefInst) { - // DefInst of second without kill of first is an interference + if (curr == MRI->getVRegDef(b)) { + // Definition of second without kill of first is an interference if (!kill) { interference = true; break; - // DefInst after a kill is a non-interference + // Definition after a kill is a non-interference } else { interference = false; break; @@ -373,7 +378,7 @@ } // Symmetric with the above } else if (mode == 2) { - if (curr == First.DefInst) { + if (curr == MRI->getVRegDef(a)) { if (!kill) { interference = true; break; @@ -396,6 +401,7 @@ /// which treatment. void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { LiveVariables& LV = getAnalysis(); + MachineRegisterInfo& MRI = MBB->getParent()->getRegInfo(); // Holds names that have been added to a set in any PHI within this block // before the current one. @@ -404,8 +410,6 @@ // Iterate over all the PHI nodes in this block MachineBasicBlock::iterator P = MBB->begin(); while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { - LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand(0).getReg()); - unsigned DestReg = P->getOperand(0).getReg(); // PHIUnion is the set of incoming registers to the PHI node that @@ -418,7 +422,6 @@ // Iterate over the operands of the PHI node for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { unsigned SrcReg = P->getOperand(i-1).getReg(); - LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg); // Check for trivial interferences via liveness information, allowing us // to avoid extra work later. Any registers that interfere cannot both @@ -432,12 +435,14 @@ // in this block OR // 5) if any two operands are defined in the same block, insert copies // for one of them - if (isLiveIn(SrcInfo, P->getParent()) || - isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) || - ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI && - isLiveIn(PHIInfo, SrcInfo.DefInst->getParent()) ) || + if (isLiveIn(SrcReg, P->getParent(), MRI, LV) || + isLiveOut(P->getOperand(0).getReg(), + MRI.getVRegDef(SrcReg)->getParent(), MRI, LV) || + ( MRI.getVRegDef(SrcReg)->getOpcode() == TargetInstrInfo::PHI && + isLiveIn(P->getOperand(0).getReg(), + MRI.getVRegDef(SrcReg)->getParent(), MRI, LV) ) || ProcessedNames.count(SrcReg) || - UnionedBlocks.count(SrcInfo.DefInst->getParent())) { + UnionedBlocks.count(MRI.getVRegDef(SrcReg)->getParent())) { // Add a copy for the selected register MachineBasicBlock* From = P->getOperand(i).getMBB(); @@ -446,7 +451,7 @@ } else { // Otherwise, add it to the renaming set PHIUnion.insert(SrcReg); - UnionedBlocks.insert(SrcInfo.DefInst->getParent()); + UnionedBlocks.insert(MRI.getVRegDef(SrcReg)->getParent()); } } @@ -454,7 +459,7 @@ // where the nodes are the registers and the edges represent dominance // relations between the defining blocks of the registers std::vector DF = - computeDomForest(PHIUnion); + computeDomForest(PHIUnion, MRI); // Walk DomForest to resolve interferences at an inter-block level. This // will remove registers from the renaming set (and insert copies for them) @@ -469,24 +474,22 @@ localInterferences.begin(), E = localInterferences.end(); I != E; ++I) { std::pair p = *I; - LiveVariables::VarInfo& FirstInfo = LV.getVarInfo(p.first); - LiveVariables::VarInfo& SecondInfo = LV.getVarInfo(p.second); - MachineDominatorTree& MDT = getAnalysis(); // Determine the block we need to scan and the relationship between // the two registers MachineBasicBlock* scan = 0; unsigned mode = 0; - if (FirstInfo.DefInst->getParent() == SecondInfo.DefInst->getParent()) { - scan = FirstInfo.DefInst->getParent(); + if (MRI.getVRegDef(p.first)->getParent() == + MRI.getVRegDef(p.second)->getParent()) { + scan = MRI.getVRegDef(p.first)->getParent(); mode = 0; // Same block - } else if (MDT.dominates(FirstInfo.DefInst->getParent(), - SecondInfo.DefInst->getParent())) { - scan = SecondInfo.DefInst->getParent(); + } else if (MDT.dominates(MRI.getVRegDef(p.first)->getParent(), + MRI.getVRegDef(p.second)->getParent())) { + scan = MRI.getVRegDef(p.second)->getParent(); mode = 1; // First dominates second } else { - scan = FirstInfo.DefInst->getParent(); + scan = MRI.getVRegDef(p.first)->getParent(); mode = 2; // Second dominates first } @@ -531,6 +534,9 @@ std::vector worklist(DF.begin(), DF.end()); SmallPtrSet visited; + // Code is still in SSA form, so we can use MRI::getVRegDef() + MachineRegisterInfo& MRI = Inst->getParent()->getParent()->getRegInfo(); + LiveVariables& LV = getAnalysis(); unsigned DestReg = Inst->getOperand(0).getReg(); @@ -538,16 +544,15 @@ while (!worklist.empty()) { DomForestNode* DFNode = worklist.back(); - LiveVariables::VarInfo& Info = LV.getVarInfo(DFNode->getReg()); visited.insert(DFNode); bool inserted = false; for (DomForestNode::iterator CI = DFNode->begin(), CE = DFNode->end(); CI != CE; ++CI) { DomForestNode* child = *CI; - LiveVariables::VarInfo& CInfo = LV.getVarInfo(child->getReg()); - if (isLiveOut(Info, CInfo.DefInst->getParent())) { + if (isLiveOut(DFNode->getReg(), + MRI.getVRegDef(child->getReg())->getParent(), MRI, LV)) { // Insert copies for parent for (int i = Inst->getNumOperands() - 1; i >= 2; i-=2) { if (Inst->getOperand(i-1).getReg() == DFNode->getReg()) { @@ -560,8 +565,11 @@ PHIUnion.erase(SrcReg); } } - } else if (isLiveIn(Info, CInfo.DefInst->getParent()) || - Info.DefInst->getParent() == CInfo.DefInst->getParent()) { + } else if (isLiveIn(DFNode->getReg(), + MRI.getVRegDef(child->getReg())->getParent(), + MRI, LV) || + MRI.getVRegDef(DFNode->getReg())->getParent() == + MRI.getVRegDef(child->getReg())->getParent()) { // Add (p, c) to possible local interferences locals.push_back(std::make_pair(DFNode->getReg(), child->getReg())); } @@ -610,6 +618,7 @@ LiveVariables& LV = getAnalysis(); MachineFunction* MF = MBB->getParent(); + MachineRegisterInfo& MRI = MF->getRegInfo(); const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); // Iterate over the worklist, inserting copies @@ -620,15 +629,14 @@ const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(curr.first); - if (isLiveOut(LV.getVarInfo(curr.second), MBB)) { + if (isLiveOut(curr.second, MBB, MRI, LV)) { // Create a temporary unsigned t = MF->getRegInfo().createVirtualRegister(RC); // Insert copy from curr.second to a temporary at // the Phi defining curr.second - LiveVariables::VarInfo VI = LV.getVarInfo(curr.second); - MachineBasicBlock::iterator PI = VI.DefInst; - TII->copyRegToReg(*VI.DefInst->getParent(), PI, t, + MachineBasicBlock::iterator PI = MRI.getVRegDef(curr.second); + TII->copyRegToReg(*PI->getParent(), PI, t, curr.second, RC, RC); // Push temporary on Stacks From resistor at mac.com Wed Jan 9 19:41:43 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 9 Jan 2008 19:41:43 -0600 Subject: [llvm-commits] [llvm] r45799 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <86537C11-8206-4E37-8640-93A90A77EFE0@apple.com> References: <200801100047.m0A0l2OL007469@zion.cs.uiuc.edu> <86537C11-8206-4E37-8640-93A90A77EFE0@apple.com> Message-ID: <861E913C-2222-459F-A494-37F04AE99199@mac.com> There's more in the pipeline too. --Owen On Jan 9, 2008, at 7:15 PM, Tanya Lattner wrote: > Nice! > > On Jan 9, 2008, at 4:47 PM, Owen Anderson wrote: > >> Author: resistor >> Date: Wed Jan 9 18:47:01 2008 >> New Revision: 45799 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45799&view=rev >> Log: >> Add more comments explaining the basics of how the decision of when >> to rename and when to insert >> copies is made. >> >> Modified: >> llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> >> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ >> StrongPHIElimination.cpp?rev=45799&r1=45798&r2=45799&view=diff >> >> = >> ===================================================================== >> ======== >> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) >> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 >> 18:47:01 2008 >> @@ -390,7 +390,10 @@ >> return interference; >> } >> >> -/// processBlock - Eliminate PHIs in the given block >> +/// processBlock - Determine how to break up PHIs in the current >> block. Each >> +/// PHI is broken up by some combination of renaming its operands >> and inserting >> +/// copies. This method is responsible for determining which >> operands receive >> +/// which treatment. >> void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { >> LiveVariables& LV = getAnalysis(); >> >> @@ -398,21 +401,37 @@ >> // before the current one. >> std::set ProcessedNames; >> >> + // Iterate over all the PHI nodes in this block >> MachineBasicBlock::iterator P = MBB->begin(); >> while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { >> LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand >> (0).getReg()); >> >> unsigned DestReg = P->getOperand(0).getReg(); >> >> - // Hold the names that are currently in the candidate set. >> + // PHIUnion is the set of incoming registers to the PHI node >> that >> + // are going to be renames rather than having copies >> inserted. This set >> + // is refinded over the course of this function. >> UnionedBlocks is the set >> + // of corresponding MBBs. >> std::set PHIUnion; >> std::set UnionedBlocks; >> >> + // Iterate over the operands of the PHI node >> for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { >> unsigned SrcReg = P->getOperand(i-1).getReg(); >> LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg); >> >> - // Check for trivial interferences >> + // Check for trivial interferences via liveness information, >> allowing us >> + // to avoid extra work later. Any registers that interfere >> cannot both >> + // be in the renaming set, so choose one and add copies for >> it instead. >> + // The conditions are: >> + // 1) if the operand is live into the PHI node's block OR >> + // 2) if the PHI node is live out of the operand's >> defining block OR >> + // 3) if the operand is itself a PHI node and the original >> PHI is >> + // live into the operand's defining block OR >> + // 4) if the operand is already being renamed for another >> PHI node >> + // in this block OR >> + // 5) if any two operands are defined in the same block, >> insert copies >> + // for one of them >> if (isLiveIn(SrcInfo, P->getParent()) || >> isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) || >> ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI && >> @@ -420,24 +439,32 @@ >> ProcessedNames.count(SrcReg) || >> UnionedBlocks.count(SrcInfo.DefInst->getParent())) { >> >> - // add a copy from a_i to p in Waiting[From[a_i]] >> + // Add a copy for the selected register >> MachineBasicBlock* From = P->getOperand(i).getMBB(); >> Waiting[From].insert(std::make_pair(SrcReg, DestReg)); >> UsedByAnother.insert(SrcReg); >> } else { >> + // Otherwise, add it to the renaming set >> PHIUnion.insert(SrcReg); >> UnionedBlocks.insert(SrcInfo.DefInst->getParent()); >> } >> } >> >> + // Compute the dominator forest for the renaming set. This is >> a forest >> + // where the nodes are the registers and the edges represent >> dominance >> + // relations between the defining blocks of the registers >> std::vector DF = >> >> computeDomForest(PHIUnion); >> >> - // Walk DomForest to resolve interferences >> + // Walk DomForest to resolve interferences at an inter-block >> level. This >> + // will remove registers from the renaming set (and insert >> copies for them) >> + // if interferences are found. >> std::vector > localInterferences; >> processPHIUnion(P, PHIUnion, DF, localInterferences); >> >> - // Check for local interferences >> + // The dominator forest walk may have returned some register >> pairs whose >> + // interference cannot be determines from dominator analysis. >> We now >> + // examine these pairs for local interferences. >> for (std::vector >::iterator I = >> localInterferences.begin(), E = localInterferences.end(); >> I != E; ++I) { >> std::pair p = *I; >> @@ -481,10 +508,13 @@ >> } >> } >> >> - // Cache renaming information >> + // Add the renaming set for this PHI node to our overal >> renaming information >> RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), >> PHIUnion)); >> >> + // Remember which registers are already renamed, so that we >> don't try to >> + // rename them for another PHI node in this block >> ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end()); >> + >> ++P; >> } >> } >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/5e07e671/attachment.bin From evan.cheng at apple.com Wed Jan 9 19:55:37 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 9 Jan 2008 17:55:37 -0800 Subject: [llvm-commits] [llvm] r45799 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <86537C11-8206-4E37-8640-93A90A77EFE0@apple.com> References: <200801100047.m0A0l2OL007469@zion.cs.uiuc.edu> <86537C11-8206-4E37-8640-93A90A77EFE0@apple.com> Message-ID: <069DDF59-D6B5-413B-B4AE-AF0381A6633B@apple.com> Geeze. I asked for comments and was ignored. Tanya asks for it and she gets it right away. :-) Evan On Jan 9, 2008, at 5:15 PM, Tanya Lattner wrote: > Nice! > > On Jan 9, 2008, at 4:47 PM, Owen Anderson wrote: > >> Author: resistor >> Date: Wed Jan 9 18:47:01 2008 >> New Revision: 45799 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45799&view=rev >> Log: >> Add more comments explaining the basics of how the decision of when >> to rename and when to insert >> copies is made. >> >> Modified: >> llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> >> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ >> StrongPHIElimination.cpp?rev=45799&r1=45798&r2=45799&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) >> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 >> 18:47:01 2008 >> @@ -390,7 +390,10 @@ >> return interference; >> } >> >> -/// processBlock - Eliminate PHIs in the given block >> +/// processBlock - Determine how to break up PHIs in the current >> block. Each >> +/// PHI is broken up by some combination of renaming its operands >> and inserting >> +/// copies. This method is responsible for determining which >> operands receive >> +/// which treatment. >> void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { >> LiveVariables& LV = getAnalysis(); >> >> @@ -398,21 +401,37 @@ >> // before the current one. >> std::set ProcessedNames; >> >> + // Iterate over all the PHI nodes in this block >> MachineBasicBlock::iterator P = MBB->begin(); >> while (P != MBB->end() && P->getOpcode() == >> TargetInstrInfo::PHI) { >> LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand >> (0).getReg()); >> >> unsigned DestReg = P->getOperand(0).getReg(); >> >> - // Hold the names that are currently in the candidate set. >> + // PHIUnion is the set of incoming registers to the PHI node >> that >> + // are going to be renames rather than having copies >> inserted. This set >> + // is refinded over the course of this function. >> UnionedBlocks is the set >> + // of corresponding MBBs. >> std::set PHIUnion; >> std::set UnionedBlocks; >> >> + // Iterate over the operands of the PHI node >> for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { >> unsigned SrcReg = P->getOperand(i-1).getReg(); >> LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg); >> >> - // Check for trivial interferences >> + // Check for trivial interferences via liveness information, >> allowing us >> + // to avoid extra work later. Any registers that interfere >> cannot both >> + // be in the renaming set, so choose one and add copies for >> it instead. >> + // The conditions are: >> + // 1) if the operand is live into the PHI node's block OR >> + // 2) if the PHI node is live out of the operand's >> defining block OR >> + // 3) if the operand is itself a PHI node and the original >> PHI is >> + // live into the operand's defining block OR >> + // 4) if the operand is already being renamed for another >> PHI node >> + // in this block OR >> + // 5) if any two operands are defined in the same block, >> insert copies >> + // for one of them >> if (isLiveIn(SrcInfo, P->getParent()) || >> isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) || >> ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI && >> @@ -420,24 +439,32 @@ >> ProcessedNames.count(SrcReg) || >> UnionedBlocks.count(SrcInfo.DefInst->getParent())) { >> >> - // add a copy from a_i to p in Waiting[From[a_i]] >> + // Add a copy for the selected register >> MachineBasicBlock* From = P->getOperand(i).getMBB(); >> Waiting[From].insert(std::make_pair(SrcReg, DestReg)); >> UsedByAnother.insert(SrcReg); >> } else { >> + // Otherwise, add it to the renaming set >> PHIUnion.insert(SrcReg); >> UnionedBlocks.insert(SrcInfo.DefInst->getParent()); >> } >> } >> >> + // Compute the dominator forest for the renaming set. This is >> a forest >> + // where the nodes are the registers and the edges represent >> dominance >> + // relations between the defining blocks of the registers >> std::vector DF = >> >> computeDomForest(PHIUnion); >> >> - // Walk DomForest to resolve interferences >> + // Walk DomForest to resolve interferences at an inter-block >> level. This >> + // will remove registers from the renaming set (and insert >> copies for them) >> + // if interferences are found. >> std::vector > localInterferences; >> processPHIUnion(P, PHIUnion, DF, localInterferences); >> >> - // Check for local interferences >> + // The dominator forest walk may have returned some register >> pairs whose >> + // interference cannot be determines from dominator analysis. >> We now >> + // examine these pairs for local interferences. >> for (std::vector >::iterator I = >> localInterferences.begin(), E = localInterferences.end(); >> I != E; ++I) { >> std::pair p = *I; >> @@ -481,10 +508,13 @@ >> } >> } >> >> - // Cache renaming information >> + // Add the renaming set for this PHI node to our overal >> renaming information >> RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), >> PHIUnion)); >> >> + // Remember which registers are already renamed, so that we >> don't try to >> + // rename them for another PHI node in this block >> ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end()); >> + >> ++P; >> } >> } >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Wed Jan 9 19:57:10 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Jan 2008 17:57:10 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45804 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm.h objc/objc-act.c In-Reply-To: <200801100128.m0A1SPD1010358@zion.cs.uiuc.edu> References: <200801100128.m0A1SPD1010358@zion.cs.uiuc.edu> Message-ID: <77BC5242-44E7-4676-A152-EE40AC807CB9@apple.com> On Jan 9, 2008, at 5:28 PM, Bill Wendling wrote: > Author: void > Date: Wed Jan 9 19:28:25 2008 > New Revision: 45804 > > URL: http://llvm.org/viewvc/llvm-project?rev=45804&view=rev > Log: > We're creating incorrect metadata. LLVM gives this for class > references: Hey Bill, Is it possible to avoid having the llvm-front-end called on the objc metadata before its fully formed? Alternatively, perhaps the objc front-end should set the early version of the metadata as being an extern instead of definition? -Chris > > L_OBJC_CLASS_REFERENCES_0: > .space 4 > .. > L_OBJC_CLASS_NAME_0: > ... > > while GCC gives: > > L_OBJC_CLASS_REFERENCES_0: > .long L_OBJC_CLASS_NAME_0 > .. > L_OBJC_CLASS_NAME_0: > ... > > which is correct. What's happening is that the reference is being > created and > LLVM is setting it's initializer to "null" because it's not pointing > to > something at that time. But then reference is modified to point to > some > object. However, LLVM wasn't updating its initializer information at > that point. > > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp > llvm-gcc-4.2/trunk/gcc/llvm.h > llvm-gcc-4.2/trunk/gcc/objc/objc-act.c > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=45804&r1=45803&r2=45804&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Jan 9 19:28:25 2008 > @@ -798,6 +798,17 @@ > } > } > > +/// reset_initializer_llvm - Change the initializer for a global > variable. > +void reset_initializer_llvm(tree decl) { > + // Get or create the global variable now. > + GlobalVariable *GV = cast(DECL_LLVM(decl)); > + > + // Convert the initializer over. > + Constant *Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl)); > + > + // Set the initializer. > + GV->setInitializer(Init); > +} > > /// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate > CONST_DECL to > /// LLVM as a global variable. This function implements the end of > > Modified: llvm-gcc-4.2/trunk/gcc/llvm.h > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm.h?rev=45804&r1=45803&r2=45804&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm.h (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm.h Wed Jan 9 19:28:25 2008 > @@ -44,12 +44,15 @@ > /* make_decl_llvm - This is also defined in tree.h and used by > macros there. */ > void make_decl_llvm(union tree_node*); > > +/* reset_initializer_llvm - Change the initializer for a global > variable. */ > +void reset_initializer_llvm(union tree_node*); > + > /* emit_global_to_llvm - Emit the specified VAR_DECL to LLVM as a > global > * variable. > */ > void emit_global_to_llvm(union tree_node*); > > -/* emit_global_to_llvm - Emit the specified alias to LLVM > +/* emit_alias_to_llvm - Emit the specified alias to LLVM > */ > void emit_alias_to_llvm(union tree_node*, union tree_node*, union > tree_node*); > > > Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=45804&r1=45803&r2=45804&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) > +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Wed Jan 9 19:28:25 2008 > @@ -76,6 +76,9 @@ > #include "langhooks-def.h" > /* APPLE LOCAL optimization pragmas 3124235/3420242 */ > #include "opts.h" > +#ifdef ENABLE_LLVM > +#include "llvm.h" /* for reset_initializer_llvm */ > +#endif > > #define OBJC_VOID_AT_END void_list_node > > @@ -5541,6 +5544,13 @@ > { > decl = TREE_PURPOSE (chain); > finish_var_decl (decl, expr); > + /* APPLE LOCAL LLVM begin - radar 5676233 */ > +#ifdef ENABLE_LLVM > + /* Reset the initializer for this reference as it most > likely > + changed. */ > + reset_initializer_llvm(decl); > +#endif > + /* APPLE LOCAL LLVM end - radar 5676233 */ > } > else > { > @@ -18172,8 +18182,16 @@ > for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) > { > handle_class_ref (chain); > - if (TREE_PURPOSE (chain)) > + /* APPLE LOCAL LLVM begin - radar 5676233 */ > + if (TREE_PURPOSE (chain)) { > generate_classref_translation_entry (chain); > +#ifdef ENABLE_LLVM > + /* Reset the initializer for this reference as it most likely > + changed. */ > + reset_initializer_llvm(TREE_PURPOSE (chain)); > +#endif > + } > + /* APPLE LOCAL LLVM end - radar 5676233 */ > } > > for (impent = imp_list; impent; impent = impent->next) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Wed Jan 9 20:03:30 2008 From: dalej at apple.com (Dale Johannesen) Date: Thu, 10 Jan 2008 02:03:30 -0000 Subject: [llvm-commits] [llvm] r45811 - in /llvm/trunk: include/llvm/Target/TargetAsmInfo.h lib/CodeGen/DwarfWriter.cpp lib/Target/PowerPC/PPCTargetAsmInfo.cpp lib/Target/TargetAsmInfo.cpp lib/Target/X86/X86TargetAsmInfo.cpp Message-ID: <200801100203.m0A23Ufb013168@zion.cs.uiuc.edu> Author: johannes Date: Wed Jan 9 20:03:30 2008 New Revision: 45811 URL: http://llvm.org/viewvc/llvm-project?rev=45811&view=rev Log: Emit unused EH frames for weak definitions on Darwin, because assembler/linker can't cope with weak absolutes. PR 1880. Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h llvm/trunk/lib/CodeGen/DwarfWriter.cpp llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp llvm/trunk/lib/Target/TargetAsmInfo.cpp llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=45811&r1=45810&r2=45811&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Wed Jan 9 20:03:30 2008 @@ -309,6 +309,10 @@ /// const char *GlobalEHDirective; // Defaults to NULL. + /// SupportsWeakEmptyEHFrame - True if target assembler and linker will + /// handle a weak_definition of constant 0 for an omitted EH frame. + bool SupportsWeakOmittedEHFrame; // Defaults to true. + /// DwarfSectionOffsetDirective - Special section offset directive. const char* DwarfSectionOffsetDirective; // Defaults to NULL @@ -585,6 +589,9 @@ const char *getGlobalEHDirective() const { return GlobalEHDirective; } + bool getSupportsWeakOmittedEHFrame() const { + return SupportsWeakOmittedEHFrame; + } const char *getDwarfSectionOffsetDirective() const { return DwarfSectionOffsetDirective; } Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=45811&r1=45810&r2=45811&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Wed Jan 9 20:03:30 2008 @@ -2877,18 +2877,25 @@ O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; } - // If there are no calls then you can't unwind. - if (!EHFrameInfo.hasCalls) { + // If corresponding function is weak definition, this should be too. + if ((EHFrameInfo.linkage == Function::WeakLinkage || + EHFrameInfo.linkage == Function::LinkOnceLinkage) && + TAI->getWeakDefDirective()) + O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; + + // If there are no calls then you can't unwind. This may mean we can + // omit the EH Frame, but some environments do not handle weak absolute + // symbols. + if (!EHFrameInfo.hasCalls && + ((EHFrameInfo.linkage != Function::WeakLinkage && + EHFrameInfo.linkage != Function::LinkOnceLinkage) || + !TAI->getWeakDefDirective() || + TAI->getSupportsWeakOmittedEHFrame())) + { O << EHFrameInfo.FnName << " = 0\n"; } else { O << EHFrameInfo.FnName << ":\n"; - // If corresponding function is weak definition, this should be too. - if ((EHFrameInfo.linkage == Function::WeakLinkage || - EHFrameInfo.linkage == Function::LinkOnceLinkage) && - TAI->getWeakDefDirective()) - O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; - // EH frame header. EmitDifference("eh_frame_end", EHFrameInfo.Number, "eh_frame_begin", EHFrameInfo.Number, true); Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=45811&r1=45810&r2=45811&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Wed Jan 9 20:03:30 2008 @@ -51,8 +51,8 @@ StaticDtorsSection = ".mod_term_func"; } UsedDirective = "\t.no_dead_strip\t"; - WeakDefDirective = "\t.weak_definition\t"; - WeakRefDirective = "\t.weak_reference\t"; + WeakDefDirective = "\t.weak_definition "; + WeakRefDirective = "\t.weak_reference "; HiddenDirective = "\t.private_extern\t"; SupportsExceptionHandling = true; NeedsIndirectEncoding = true; @@ -62,12 +62,13 @@ DwarfEHFrameSection = ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; DwarfExceptionSection = ".section __DATA,__gcc_except_tab"; + GlobalEHDirective = "\t.globl\t"; + SupportsWeakOmittedEHFrame = false; DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; - GlobalEHDirective = "\t.globl\t"; DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=45811&r1=45810&r2=45811&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Wed Jan 9 20:03:30 2008 @@ -86,6 +86,7 @@ SupportsExceptionHandling(false), DwarfRequiresFrameSection(true), GlobalEHDirective(0), + SupportsWeakOmittedEHFrame(true), DwarfSectionOffsetDirective(0), DwarfAbbrevSection(".debug_abbrev"), DwarfInfoSection(".debug_info"), Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=45811&r1=45810&r2=45811&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Wed Jan 9 20:03:30 2008 @@ -76,8 +76,8 @@ SetDirective = "\t.set"; PCSymbol = "."; UsedDirective = "\t.no_dead_strip\t"; - WeakDefDirective = "\t.weak_definition\t"; - WeakRefDirective = "\t.weak_reference\t"; + WeakDefDirective = "\t.weak_definition "; + WeakRefDirective = "\t.weak_reference "; HiddenDirective = "\t.private_extern\t"; // In non-PIC modes, emit a special label before jump tables so that the @@ -93,7 +93,6 @@ DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; - GlobalEHDirective = "\t.globl\t"; DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; @@ -105,6 +104,8 @@ // Exceptions handling if (!Subtarget->is64Bit()) SupportsExceptionHandling = true; + GlobalEHDirective = "\t.globl\t"; + SupportsWeakOmittedEHFrame = false; AbsoluteEHSectionOffsets = false; DwarfEHFrameSection = ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; From resistor at mac.com Wed Jan 9 20:05:23 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 9 Jan 2008 20:05:23 -0600 Subject: [llvm-commits] [llvm] r45799 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp In-Reply-To: <069DDF59-D6B5-413B-B4AE-AF0381A6633B@apple.com> References: <200801100047.m0A0l2OL007469@zion.cs.uiuc.edu> <86537C11-8206-4E37-8640-93A90A77EFE0@apple.com> <069DDF59-D6B5-413B-B4AE-AF0381A6633B@apple.com> Message-ID: What can I say, she's scarier than you. :-p --Owen On Jan 9, 2008, at 7:55 PM, Evan Cheng wrote: > Geeze. I asked for comments and was ignored. Tanya asks for it and > she gets it right away. :-) > > Evan > On Jan 9, 2008, at 5:15 PM, Tanya Lattner wrote: > >> Nice! >> >> On Jan 9, 2008, at 4:47 PM, Owen Anderson wrote: >> >>> Author: resistor >>> Date: Wed Jan 9 18:47:01 2008 >>> New Revision: 45799 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=45799&view=rev >>> Log: >>> Add more comments explaining the basics of how the decision of when >>> to rename and when to insert >>> copies is made. >>> >>> Modified: >>> llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >>> >>> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ >>> StrongPHIElimination.cpp?rev=45799&r1=45798&r2=45799&view=diff >>> >>> = >>> ==================================================================== >>> = >>> ======== >>> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) >>> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Wed Jan 9 >>> 18:47:01 2008 >>> @@ -390,7 +390,10 @@ >>> return interference; >>> } >>> >>> -/// processBlock - Eliminate PHIs in the given block >>> +/// processBlock - Determine how to break up PHIs in the current >>> block. Each >>> +/// PHI is broken up by some combination of renaming its operands >>> and inserting >>> +/// copies. This method is responsible for determining which >>> operands receive >>> +/// which treatment. >>> void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { >>> LiveVariables& LV = getAnalysis(); >>> >>> @@ -398,21 +401,37 @@ >>> // before the current one. >>> std::set ProcessedNames; >>> >>> + // Iterate over all the PHI nodes in this block >>> MachineBasicBlock::iterator P = MBB->begin(); >>> while (P != MBB->end() && P->getOpcode() == >>> TargetInstrInfo::PHI) { >>> LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand >>> (0).getReg()); >>> >>> unsigned DestReg = P->getOperand(0).getReg(); >>> >>> - // Hold the names that are currently in the candidate set. >>> + // PHIUnion is the set of incoming registers to the PHI node >>> that >>> + // are going to be renames rather than having copies >>> inserted. This set >>> + // is refinded over the course of this function. >>> UnionedBlocks is the set >>> + // of corresponding MBBs. >>> std::set PHIUnion; >>> std::set UnionedBlocks; >>> >>> + // Iterate over the operands of the PHI node >>> for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { >>> unsigned SrcReg = P->getOperand(i-1).getReg(); >>> LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg); >>> >>> - // Check for trivial interferences >>> + // Check for trivial interferences via liveness information, >>> allowing us >>> + // to avoid extra work later. Any registers that interfere >>> cannot both >>> + // be in the renaming set, so choose one and add copies for >>> it instead. >>> + // The conditions are: >>> + // 1) if the operand is live into the PHI node's block OR >>> + // 2) if the PHI node is live out of the operand's >>> defining block OR >>> + // 3) if the operand is itself a PHI node and the original >>> PHI is >>> + // live into the operand's defining block OR >>> + // 4) if the operand is already being renamed for another >>> PHI node >>> + // in this block OR >>> + // 5) if any two operands are defined in the same block, >>> insert copies >>> + // for one of them >>> if (isLiveIn(SrcInfo, P->getParent()) || >>> isLiveOut(PHIInfo, SrcInfo.DefInst->getParent()) || >>> ( PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI && >>> @@ -420,24 +439,32 @@ >>> ProcessedNames.count(SrcReg) || >>> UnionedBlocks.count(SrcInfo.DefInst->getParent())) { >>> >>> - // add a copy from a_i to p in Waiting[From[a_i]] >>> + // Add a copy for the selected register >>> MachineBasicBlock* From = P->getOperand(i).getMBB(); >>> Waiting[From].insert(std::make_pair(SrcReg, DestReg)); >>> UsedByAnother.insert(SrcReg); >>> } else { >>> + // Otherwise, add it to the renaming set >>> PHIUnion.insert(SrcReg); >>> UnionedBlocks.insert(SrcInfo.DefInst->getParent()); >>> } >>> } >>> >>> + // Compute the dominator forest for the renaming set. This is >>> a forest >>> + // where the nodes are the registers and the edges represent >>> dominance >>> + // relations between the defining blocks of the registers >>> std::vector DF = >>> >>> computeDomForest(PHIUnion); >>> >>> - // Walk DomForest to resolve interferences >>> + // Walk DomForest to resolve interferences at an inter-block >>> level. This >>> + // will remove registers from the renaming set (and insert >>> copies for them) >>> + // if interferences are found. >>> std::vector > localInterferences; >>> processPHIUnion(P, PHIUnion, DF, localInterferences); >>> >>> - // Check for local interferences >>> + // The dominator forest walk may have returned some register >>> pairs whose >>> + // interference cannot be determines from dominator analysis. >>> We now >>> + // examine these pairs for local interferences. >>> for (std::vector >::iterator I = >>> localInterferences.begin(), E = localInterferences.end(); >>> I != E; ++I) { >>> std::pair p = *I; >>> @@ -481,10 +508,13 @@ >>> } >>> } >>> >>> - // Cache renaming information >>> + // Add the renaming set for this PHI node to our overal >>> renaming information >>> RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), >>> PHIUnion)); >>> >>> + // Remember which registers are already renamed, so that we >>> don't try to >>> + // rename them for another PHI node in this block >>> ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end()); >>> + >>> ++P; >>> } >>> } >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/43755f17/attachment.bin From evan.cheng at apple.com Wed Jan 9 20:18:37 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 02:18:37 -0000 Subject: [llvm-commits] [llvm] r45812 - /llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Message-ID: <200801100218.m0A2IbXn014122@zion.cs.uiuc.edu> Author: evancheng Date: Wed Jan 9 20:18:37 2008 New Revision: 45812 URL: http://llvm.org/viewvc/llvm-project?rev=45812&view=rev Log: Add a isImmutable bit to StackObject. Fixed stack objects are immutable (in the function) unless specified otherwise. Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=45812&r1=45811&r2=45812&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Wed Jan 9 20:18:37 2008 @@ -86,8 +86,13 @@ // the function. This field has no meaning for a variable sized element. int64_t SPOffset; - StackObject(uint64_t Sz, unsigned Al, int64_t SP) - : Size(Sz), Alignment(Al), SPOffset(SP) {} + // isImmutable - If true, the value of the stack object does not change + // in this function. By default, fixed objects are immutable unless marked + // otherwise. + bool isImmutable; + + StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM = false) + : Size(Sz), Alignment(Al), SPOffset(SP), isImmutable(IM) {} }; /// Objects - The list of stack objects allocated... @@ -255,11 +260,13 @@ /// CreateFixedObject - Create a new object at a fixed location on the stack. /// All fixed objects should be created before other objects are created for - /// efficiency. This returns an index with a negative value. + /// efficiency. By default, fixed objects are immutable. This returns an + /// index with a negative value. /// - int CreateFixedObject(uint64_t Size, int64_t SPOffset) { + int CreateFixedObject(uint64_t Size, int64_t SPOffset, + bool Immutable = true) { assert(Size != 0 && "Cannot allocate zero size fixed stack objects!"); - Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset)); + Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset, Immutable)); return -++NumFixedObjects; } @@ -269,6 +276,12 @@ return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects); } + /// isImmutableObjectIndex - Returns true if the specified index corresponds + /// to an immutable object. + bool isImmutableObjectIndex(int ObjectIdx) const { + return Objects[ObjectIdx+NumFixedObjects].isImmutable; + } + /// CreateStackObject - Create a new statically sized stack object, returning /// a postive identifier to represent it. /// From evan.cheng at apple.com Wed Jan 9 20:24:25 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 02:24:25 -0000 Subject: [llvm-commits] [llvm] r45813 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801100224.m0A2OPul014550@zion.cs.uiuc.edu> Author: evancheng Date: Wed Jan 9 20:24:25 2008 New Revision: 45813 URL: http://llvm.org/viewvc/llvm-project?rev=45813&view=rev Log: Mark byval parameter stack objects mutable for now. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45813&r1=45812&r2=45813&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Jan 9 20:24:25 2008 @@ -1012,16 +1012,17 @@ MachineFrameInfo *MFI, SDOperand Root, unsigned i) { // Create the nodes corresponding to a load from this parameter slot. + unsigned Flags = cast(Op.getOperand(3 + i))->getValue(); + bool isByVal = Flags & ISD::ParamFlags::ByVal; + + // FIXME: For now, all byval parameter objects are marked mutable. This + // can be changed with more analysis. int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8, - VA.getLocMemOffset()); + VA.getLocMemOffset(), !isByVal); SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy()); - - unsigned Flags = cast(Op.getOperand(3 + i))->getValue(); - - if (Flags & ISD::ParamFlags::ByVal) + if (isByVal) return FIN; - else - return DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0); + return DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0); } SDOperand From evan.cheng at apple.com Wed Jan 9 20:54:41 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 02:54:41 -0000 Subject: [llvm-commits] [llvm] r45814 - /llvm/trunk/test/CodeGen/X86/pr1505b.ll Message-ID: <200801100254.m0A2sfD4016252@zion.cs.uiuc.edu> Author: evancheng Date: Wed Jan 9 20:54:40 2008 New Revision: 45814 URL: http://llvm.org/viewvc/llvm-project?rev=45814&view=rev Log: Codegen improvement has reduced one spill. Modified: llvm/trunk/test/CodeGen/X86/pr1505b.ll Modified: llvm/trunk/test/CodeGen/X86/pr1505b.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr1505b.ll?rev=45814&r1=45813&r2=45814&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/pr1505b.ll (original) +++ llvm/trunk/test/CodeGen/X86/pr1505b.ll Wed Jan 9 20:54:40 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -mcpu=i486 | grep fstpl | count 4 +; RUN: llvm-as < %s | llc -mcpu=i486 | grep fstpl | count 3 ; RUN: llvm-as < %s | llc -mcpu=i486 | grep fstps | count 3 ; ModuleID = '' From resistor at mac.com Wed Jan 9 21:12:56 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 10 Jan 2008 03:12:56 -0000 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> Author: resistor Date: Wed Jan 9 21:12:54 2008 New Revision: 45815 URL: http://llvm.org/viewvc/llvm-project?rev=45815&view=rev Log: Don't use LiveVariables::VarInfo::DefInst. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=45815&r1=45814&r2=45815&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Jan 9 21:12:54 2008 @@ -309,7 +309,14 @@ // are actually two values in the live interval. Because of this we // need to take the LiveRegion that defines this register and split it // into two values. - unsigned DefIndex = getDefIndex(getInstructionIndex(vi.DefInst)); + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); + unsigned lowIndex = ~0U; + for (MachineRegisterInfo::def_iterator DI = MRI.def_begin(interval.reg), + DE = MRI.def_end(); DI != DE; ++DI) + if (getInstructionIndex(&*DI) < lowIndex) + lowIndex = getInstructionIndex(&*DI); + + unsigned DefIndex = getDefIndex(lowIndex); unsigned RedefIndex = getDefIndex(MIIdx); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1); From clattner at apple.com Wed Jan 9 22:08:13 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Jan 2008 20:08:13 -0800 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> Message-ID: > URL: http://llvm.org/viewvc/llvm-project?rev=45815&view=rev > Log: > Don't use LiveVariables::VarInfo::DefInst. Cool, question though: > +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Jan 9 > 21:12:54 2008 > @@ -309,7 +309,14 @@ > // are actually two values in the live interval. Because of > this we > // need to take the LiveRegion that defines this register and > split it > // into two values. > - unsigned DefIndex = > getDefIndex(getInstructionIndex(vi.DefInst)); In the old code, when it introduces multiple definitions of a vreg, did it clear DefInst? If so, this code can only be triggered for vregs with a single def. > > + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); I think that MRI should become and ivar in liveintervalanalysis. > > + unsigned lowIndex = ~0U; > + for (MachineRegisterInfo::def_iterator DI = > MRI.def_begin(interval.reg), > + DE = MRI.def_end(); DI != DE; ++DI) > + if (getInstructionIndex(&*DI) < lowIndex) > + lowIndex = getInstructionIndex(&*DI); > + > + unsigned DefIndex = getDefIndex(lowIndex); It would be really nice if you could drop the loop. It's unclear why it's right anyway, the numbering is not necessarily contiguous across code... -Chris From clattner at apple.com Wed Jan 9 22:12:18 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Jan 2008 20:12:18 -0800 Subject: [llvm-commits] [llvm] r45812 - /llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h In-Reply-To: <200801100218.m0A2IbXn014122@zion.cs.uiuc.edu> References: <200801100218.m0A2IbXn014122@zion.cs.uiuc.edu> Message-ID: <067622C0-ECCD-4508-9AD4-284B7655F799@apple.com> On Jan 9, 2008, at 6:18 PM, Evan Cheng wrote: > Author: evancheng > Date: Wed Jan 9 20:18:37 2008 > New Revision: 45812 > > URL: http://llvm.org/viewvc/llvm-project?rev=45812&view=rev > Log: > Add a isImmutable bit to StackObject. Fixed stack objects are > immutable (in the function) unless specified otherwise. Hi Evan, please describe what "immutable" means more clearly. The definition you have is "If true, the value of the stack object does not change in this function". Please say something like "If true, the value is set before the function is entered, and we know the function never modifies the stack slot." or something like this. Thanks! I'll make the x86 backend check this predicate. -Chris > > Modified: > llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h > > Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=45812&r1=45811&r2=45812&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original) > +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Wed Jan 9 > 20:18:37 2008 > @@ -86,8 +86,13 @@ > // the function. This field has no meaning for a variable sized > element. > int64_t SPOffset; > > - StackObject(uint64_t Sz, unsigned Al, int64_t SP) > - : Size(Sz), Alignment(Al), SPOffset(SP) {} > + // isImmutable - If true, the value of the stack object does > not change > + // in this function. By default, fixed objects are immutable > unless marked > + // otherwise. > + bool isImmutable; > + > + StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM = > false) > + : Size(Sz), Alignment(Al), SPOffset(SP), isImmutable(IM) {} > }; > > /// Objects - The list of stack objects allocated... > @@ -255,11 +260,13 @@ > > /// CreateFixedObject - Create a new object at a fixed location on > the stack. > /// All fixed objects should be created before other objects are > created for > - /// efficiency. This returns an index with a negative value. > + /// efficiency. By default, fixed objects are immutable. This > returns an > + /// index with a negative value. > /// > - int CreateFixedObject(uint64_t Size, int64_t SPOffset) { > + int CreateFixedObject(uint64_t Size, int64_t SPOffset, > + bool Immutable = true) { > assert(Size != 0 && "Cannot allocate zero size fixed stack > objects!"); > - Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset)); > + Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset, > Immutable)); > return -++NumFixedObjects; > } > > @@ -269,6 +276,12 @@ > return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects); > } > > + /// isImmutableObjectIndex - Returns true if the specified index > corresponds > + /// to an immutable object. > + bool isImmutableObjectIndex(int ObjectIdx) const { > + return Objects[ObjectIdx+NumFixedObjects].isImmutable; > + } > + > /// CreateStackObject - Create a new statically sized stack > object, returning > /// a postive identifier to represent it. > /// > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Jan 9 22:16:34 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 04:16:34 -0000 Subject: [llvm-commits] [llvm] r45816 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200801100416.m0A4GYpq022851@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 22:16:31 2008 New Revision: 45816 URL: http://llvm.org/viewvc/llvm-project?rev=45816&view=rev Log: verify that the frame index is immutable before remat'ing (still disabled) or being side-effect free. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45816&r1=45815&r2=45816&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Jan 9 22:16:31 2008 @@ -749,10 +749,11 @@ // values. #if 0 // FIXME: This is disabled due to a remat bug. rdar://5671644 - MachineFunction *MF = MI->getParent()->getParent(); - if (MI->getOperand(1).isFI() && - MF->getFrameInfo()->isFixedObjectIndex(MI->getOperand(1).getIndex())) - return true; + if (MI->getOperand(1).isFI()) { + const MachineFrameInfo &MFI=*MI->getParent()->getParent()->getFrameInfo(); + int Idx = MI->getOperand(1).getIndex(); + return MFI.isFixedObjectIndex(Idx) && MFI.isImmutableObjectIndex(Idx); + } #endif return false; @@ -805,9 +806,11 @@ // invariant across the whole function, because we don't redefine argument // values. MachineFunction *MF = MI->getParent()->getParent(); - if (MI->getOperand(1).isFI() && - MF->getFrameInfo()->isFixedObjectIndex(MI->getOperand(1).getIndex())) - return true; + if (MI->getOperand(1).isFI()) { + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + int Idx = MI->getOperand(1).getIndex(); + return MFI.isFixedObjectIndex(Idx) && MFI.isImmutableObjectIndex(Idx); + } return false; } From sabre at nondot.org Wed Jan 9 22:38:57 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 04:38:57 -0000 Subject: [llvm-commits] [llvm] r45817 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp CodeGenTarget.h InstrInfoEmitter.cpp Message-ID: <200801100438.m0A4cwmW024280@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 22:38:57 2008 New Revision: 45817 URL: http://llvm.org/viewvc/llvm-project?rev=45817&view=rev Log: realize that instructions who match intrinsics that read memory read memory. Also, instructions with any nodes that are SDNPMayLoad also read memory. Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenTarget.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=45817&r1=45816&r2=45817&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Wed Jan 9 22:38:57 2008 @@ -319,6 +319,8 @@ Properties |= 1 << SDNPOptInFlag; } else if (PropList[i]->getName() == "SDNPMayStore") { Properties |= 1 << SDNPMayStore; + } else if (PropList[i]->getName() == "SDNPMayLoad") { + Properties |= 1 << SDNPMayLoad; } else { cerr << "Unknown SD Node property '" << PropList[i]->getName() << "' on node '" << R->getName() << "'!\n"; Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=45817&r1=45816&r2=45817&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Wed Jan 9 22:38:57 2008 @@ -37,6 +37,7 @@ SDNPOutFlag, SDNPInFlag, SDNPOptInFlag, + SDNPMayLoad, SDNPMayStore }; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45817&r1=45816&r2=45817&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Wed Jan 9 22:38:57 2008 @@ -174,12 +174,21 @@ const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); // If node writes to memory, it obviously stores to memory. - if (OpInfo.hasProperty(SDNPMayStore)) { + if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true; - } else if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { + + // If it reads memory, remember this. + if (OpInfo.hasProperty(SDNPMayLoad)) + mayLoad = true; + + if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. - if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) + if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) { mayStore = true;// Intrinsics that can write to memory are 'mayStore'. + } + + if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem) + mayLoad = true;// These may also load memory. } } From sabre at nondot.org Wed Jan 9 22:44:32 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 04:44:32 -0000 Subject: [llvm-commits] [llvm] r45818 - /llvm/trunk/lib/Target/TargetSelectionDAG.td Message-ID: <200801100444.m0A4iWRd024726@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 22:44:32 2008 New Revision: 45818 URL: http://llvm.org/viewvc/llvm-project?rev=45818&view=rev Log: add SDNPMayLoad to the 'load' sdnode definition. This is enough to get all the x86 instructions (with patterns) that load memory marked, for example. Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=45818&r1=45817&r2=45818&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/lib/Target/TargetSelectionDAG.td Wed Jan 9 22:44:32 2008 @@ -190,6 +190,7 @@ def SDNPInFlag : SDNodeProperty; // Read a flag operand def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. +def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. //===----------------------------------------------------------------------===// // Selection DAG Node definitions. @@ -313,7 +314,8 @@ // Do not use ld, st directly. Use load, extload, sextload, zextload, store, // and truncst (see below). -def ld : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; +def ld : SDNode<"ISD::LOAD" , SDTLoad, + [SDNPHasChain, SDNPMayLoad]>; def st : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain, SDNPMayStore]>; def ist : SDNode<"ISD::STORE" , SDTIStore, From resistor at mac.com Wed Jan 9 22:44:35 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 9 Jan 2008 22:44:35 -0600 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> Message-ID: <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> You really need to address these to Evan. I asked him what to do for LiveIntervalAnalysis, and this is what he told me :-) --Owen On Jan 9, 2008, at 10:08 PM, Chris Lattner wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=45815&view=rev >> Log: >> Don't use LiveVariables::VarInfo::DefInst. > > Cool, question though: > >> +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Jan 9 >> 21:12:54 2008 >> @@ -309,7 +309,14 @@ >> // are actually two values in the live interval. Because of >> this we >> // need to take the LiveRegion that defines this register and >> split it >> // into two values. >> - unsigned DefIndex = >> getDefIndex(getInstructionIndex(vi.DefInst)); > > In the old code, when it introduces multiple definitions of a vreg, > did it clear DefInst? If so, this code can only be triggered for > vregs with a single def. > >> >> + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); > > I think that MRI should become and ivar in liveintervalanalysis. > >> >> + unsigned lowIndex = ~0U; >> + for (MachineRegisterInfo::def_iterator DI = >> MRI.def_begin(interval.reg), >> + DE = MRI.def_end(); DI != DE; ++DI) >> + if (getInstructionIndex(&*DI) < lowIndex) >> + lowIndex = getInstructionIndex(&*DI); >> + >> + unsigned DefIndex = getDefIndex(lowIndex); > > It would be really nice if you could drop the loop. It's unclear why > it's right anyway, the numbering is not necessarily contiguous across > code... > > -Chris > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/232b130a/attachment.bin From sabre at nondot.org Wed Jan 9 22:44:48 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 04:44:48 -0000 Subject: [llvm-commits] [llvm] r45819 - /llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200801100444.m0A4imeC024754@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 22:44:48 2008 New Revision: 45819 URL: http://llvm.org/viewvc/llvm-project?rev=45819&view=rev Log: Infer mayload Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45819&r1=45818&r2=45819&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Wed Jan 9 22:44:48 2008 @@ -205,7 +205,7 @@ InstAnalyzer(CDP, mayStore, mayLoad,NeverHasSideEffects).Analyze(Inst.TheDef); - // InstAnalyzer only correctly analyzes mayStore so far. + // InstAnalyzer only correctly analyzes mayStore/mayLoad so far. if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it. // If we decided that this is a store from the pattern, then the .td file // entry is redundant. @@ -217,8 +217,18 @@ mayStore = true; } - // These two override everything. - mayLoad = Inst.mayLoad; + if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it. + // If we decided that this is a load from the pattern, then the .td file + // entry is redundant. + if (mayLoad) + fprintf(stderr, + "Warning: mayLoad flag explicitly set on instruction '%s'" + " but flag already inferred from pattern.\n", + Inst.TheDef->getName().c_str()); + mayLoad = true; + } + + NeverHasSideEffects = Inst.neverHasSideEffects; #if 0 From resistor at mac.com Wed Jan 9 22:48:28 2008 From: resistor at mac.com (Owen Anderson) Date: Wed, 9 Jan 2008 22:48:28 -0600 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> Message-ID: Oh, and it did pass SPEC2000 and SPEC2006, so it can't be too wrong, can it? --Owen On Jan 9, 2008, at 10:44 PM, Owen Anderson wrote: > You really need to address these to Evan. I asked him what to do > for LiveIntervalAnalysis, and this is what he told me :-) > > --Owen > > On Jan 9, 2008, at 10:08 PM, Chris Lattner wrote: > >>> URL: http://llvm.org/viewvc/llvm-project?rev=45815&view=rev >>> Log: >>> Don't use LiveVariables::VarInfo::DefInst. >> >> Cool, question though: >> >>> +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Jan 9 >>> 21:12:54 2008 >>> @@ -309,7 +309,14 @@ >>> // are actually two values in the live interval. Because of >>> this we >>> // need to take the LiveRegion that defines this register and >>> split it >>> // into two values. >>> - unsigned DefIndex = >>> getDefIndex(getInstructionIndex(vi.DefInst)); >> >> In the old code, when it introduces multiple definitions of a vreg, >> did it clear DefInst? If so, this code can only be triggered for >> vregs with a single def. >> >>> >>> + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); >> >> I think that MRI should become and ivar in liveintervalanalysis. >> >>> >>> + unsigned lowIndex = ~0U; >>> + for (MachineRegisterInfo::def_iterator DI = >>> MRI.def_begin(interval.reg), >>> + DE = MRI.def_end(); DI != DE; ++DI) >>> + if (getInstructionIndex(&*DI) < lowIndex) >>> + lowIndex = getInstructionIndex(&*DI); >>> + >>> + unsigned DefIndex = getDefIndex(lowIndex); >> >> It would be really nice if you could drop the loop. It's unclear why >> it's right anyway, the numbering is not necessarily contiguous across >> code... >> >> -Chris >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/b085df3a/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/b085df3a/attachment.bin From sabre at nondot.org Wed Jan 9 23:12:37 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 05:12:37 -0000 Subject: [llvm-commits] [llvm] r45821 - in /llvm/trunk/lib/Target: ARM/ARMInstrInfo.td ARM/ARMInstrThumb.td ARM/ARMInstrVFP.td Alpha/AlphaInstrInfo.td PowerPC/PPCInstrInfo.td X86/X86InstrFPStack.td X86/X86InstrInfo.td Message-ID: <200801100512.m0A5CcrN026154@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 23:12:37 2008 New Revision: 45821 URL: http://llvm.org/viewvc/llvm-project?rev=45821&view=rev Log: get def use info more correct. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrVFP.td llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Jan 9 23:12:37 2008 @@ -809,7 +809,7 @@ [(set GPR:$dst, (load addrmode2:$addr))]>; // Special LDR for loads from non-pc-relative constpools. -let isSimpleLoad = 1, isReMaterializable = 1 in +let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1 in def LDRcp : AI2<0x0, (outs GPR:$dst), (ins addrmode2:$addr), LdFrm, "ldr", " $dst, $addr", []>; @@ -831,6 +831,7 @@ "ldr", "sb $dst, $addr", [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>; +let mayLoad = 1 in { // Load doubleword def LDRD : AI3<0xD, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm, "ldr", "d $dst, $addr", @@ -876,6 +877,7 @@ def LDRSB_POST: AI3po<0xD, (outs GPR:$dst, GPR:$base_wb), (ins GPR:$base,am3offset:$offset), LdFrm, "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>; +} // Store def STR : AI2<0x0, (outs), (ins GPR:$src, addrmode2:$addr), StFrm, @@ -939,6 +941,7 @@ // // FIXME: $dst1 should be a def. +let mayLoad = 1 in def LDM : AXI4<0x0, (outs), (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), LdFrm, "ldm${p}${addr:submode} $addr, $dst1", Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Wed Jan 9 23:12:37 2008 @@ -265,7 +265,7 @@ // Special instruction for restore. It cannot clobber condition register // when it's expanded by eliminateCallFramePseudoInstr(). -let isSimpleLoad = 1 in +let isSimpleLoad = 1, mayLoad = 1 in def tRestore : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), "ldr $dst, $addr", []>; @@ -276,7 +276,7 @@ [(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; // Special LDR for loads from non-pc-relative constpools. -let isSimpleLoad = 1, isReMaterializable = 1 in +let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1 in def tLDRcp : TIs<(outs GPR:$dst), (ins i32imm:$addr), "ldr $dst, $addr", []>; @@ -309,6 +309,7 @@ // TODO: A7-44: LDMIA - load multiple +let mayLoad = 1 in def tPOP : TI<(outs reglist:$dst1, variable_ops), (ins), "pop $dst1", []>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Wed Jan 9 23:12:37 2008 @@ -110,6 +110,7 @@ // Load / store multiple Instructions. // +let mayLoad = 1 in { def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1, variable_ops), "fldm${addr:submode}d${p} ${addr:base}, $dst1", @@ -119,6 +120,7 @@ variable_ops), "fldm${addr:submode}s${p} ${addr:base}, $dst1", []>; +} let mayStore = 1 in { def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1, Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td Wed Jan 9 23:12:37 2008 @@ -24,7 +24,7 @@ def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>; def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>; def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>; -def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>; +def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, [SDNPMayLoad]>; def retflag : SDNode<"AlphaISD::RET_FLAG", SDTRet, [SDNPHasChain, SDNPOptInFlag]>; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Jan 9 23:12:37 2008 @@ -120,7 +120,8 @@ def PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr, [SDNPHasChain, SDNPOptInFlag]>; -def PPClbrx : SDNode<"PPCISD::LBRX", SDT_PPClbrx, [SDNPHasChain]>; +def PPClbrx : SDNode<"PPCISD::LBRX", SDT_PPClbrx, + [SDNPHasChain, SDNPMayLoad]>; def PPCstbrx : SDNode<"PPCISD::STBRX", SDT_PPCstbrx, [SDNPHasChain, SDNPMayStore]>; Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Wed Jan 9 23:12:37 2008 @@ -36,13 +36,13 @@ def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet, [SDNPHasChain, SDNPOutFlag]>; def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, - [SDNPHasChain]>; + [SDNPHasChain, SDNPMayLoad]>; def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, - [SDNPHasChain, SDNPInFlag]>; + [SDNPHasChain, SDNPInFlag, SDNPMayStore]>; def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, - [SDNPHasChain]>; + [SDNPHasChain, SDNPMayLoad]>; def X86fildflag : SDNode<"X86ISD::FILD_FLAG",SDTX86Fild, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>; def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem, [SDNPHasChain]>; def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45821&r1=45820&r2=45821&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Jan 9 23:12:37 2008 @@ -86,9 +86,10 @@ [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore]>; def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore, + SDNPMayLoad]>; def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, [SDNPHasChain, SDNPOutFlag]>; From clattner at apple.com Wed Jan 9 23:12:54 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Jan 2008 21:12:54 -0800 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> Message-ID: <2896938C-3BB9-48B4-87A8-B0005C136BE9@apple.com> On Jan 9, 2008, at 8:48 PM, Owen Anderson wrote: > Oh, and it did pass SPEC2000 and SPEC2006, so it can't be too wrong, > can it? Heh, ok, well I'm still concerned with it being overkill :) -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080109/5683b9e3/attachment.html From sabre at nondot.org Wed Jan 9 23:39:30 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 05:39:30 -0000 Subject: [llvm-commits] [llvm] r45822 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp CodeGenTarget.h InstrInfoEmitter.cpp InstrInfoEmitter.h Message-ID: <200801100539.m0A5dUgm027858@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 23:39:30 2008 New Revision: 45822 URL: http://llvm.org/viewvc/llvm-project?rev=45822&view=rev Log: start inferring 'no side effects'. Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenTarget.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp llvm/trunk/utils/TableGen/InstrInfoEmitter.h Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=45822&r1=45821&r2=45822&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Wed Jan 9 23:39:30 2008 @@ -321,6 +321,8 @@ Properties |= 1 << SDNPMayStore; } else if (PropList[i]->getName() == "SDNPMayLoad") { Properties |= 1 << SDNPMayLoad; + } else if (PropList[i]->getName() == "SDNPSideEffect") { + Properties |= 1 << SDNPSideEffect; } else { cerr << "Unknown SD Node property '" << PropList[i]->getName() << "' on node '" << R->getName() << "'!\n"; Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=45822&r1=45821&r2=45822&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Wed Jan 9 23:39:30 2008 @@ -38,7 +38,8 @@ SDNPInFlag, SDNPOptInFlag, SDNPMayLoad, - SDNPMayStore + SDNPMayStore, + SDNPSideEffect }; /// getValueType - Return the MVT::ValueType that the specified TableGen record Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45822&r1=45821&r2=45822&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Wed Jan 9 23:39:30 2008 @@ -145,20 +145,17 @@ const CodeGenDAGPatterns &CDP; bool &mayStore; bool &mayLoad; - bool &NeverHasSideEffects; + bool &HasSideEffects; public: InstAnalyzer(const CodeGenDAGPatterns &cdp, - bool &maystore, bool &mayload, bool &nhse) - : CDP(cdp), mayStore(maystore), mayLoad(mayload), NeverHasSideEffects(nhse){ + bool &maystore, bool &mayload, bool &hse) + : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){ } void Analyze(Record *InstRecord) { const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern(); if (Pattern == 0) return; // No pattern. - // Assume there is no side-effect unless we see one. - NeverHasSideEffects = true; - // FIXME: Assume only the first tree is the pattern. The others are clobber // nodes. AnalyzeNode(Pattern->getTree(0)); @@ -169,73 +166,85 @@ if (N->isLeaf()) return; - if (N->getOperator()->getName() != "set") { - // Get information about the SDNode for the operator. - const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); - - // If node writes to memory, it obviously stores to memory. - if (OpInfo.hasProperty(SDNPMayStore)) - mayStore = true; - - // If it reads memory, remember this. - if (OpInfo.hasProperty(SDNPMayLoad)) - mayLoad = true; - - if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { - // If this is an intrinsic, analyze it. - if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) { - mayStore = true;// Intrinsics that can write to memory are 'mayStore'. - } - - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem) - mayLoad = true;// These may also load memory. - } - } - + // Analyze children. for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) AnalyzeNode(N->getChild(i)); + + // Ignore set nodes, which are not SDNodes. + if (N->getOperator()->getName() == "set") + return; + + // Get information about the SDNode for the operator. + const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); + + // If node writes to memory, it obviously stores to memory. + if (OpInfo.hasProperty(SDNPMayStore)) + mayStore = true; + + // If it reads memory, remember this. + if (OpInfo.hasProperty(SDNPMayLoad)) + mayLoad = true; + + // If it reads memory, remember this. + if (OpInfo.hasProperty(SDNPSideEffect)) + HasSideEffects = true; + + if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { + // If this is an intrinsic, analyze it. + if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem) + mayLoad = true;// These may load memory. + + if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem) + mayStore = true;// Intrinsics that can write to memory are 'mayStore'. + + if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem) + // WriteMem intrinsics can have other strange effects. + HasSideEffects = true; + } } }; void InstrInfoEmitter::InferFromPattern(const CodeGenInstruction &Inst, - bool &mayStore, bool &mayLoad, - bool &NeverHasSideEffects) { - mayStore = mayLoad = NeverHasSideEffects = false; + bool &MayStore, bool &MayLoad, + bool &HasSideEffects) { + MayStore = MayLoad = HasSideEffects = false; - InstAnalyzer(CDP, mayStore, mayLoad,NeverHasSideEffects).Analyze(Inst.TheDef); + InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef); // InstAnalyzer only correctly analyzes mayStore/mayLoad so far. if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it. // If we decided that this is a store from the pattern, then the .td file // entry is redundant. - if (mayStore) + if (MayStore) fprintf(stderr, "Warning: mayStore flag explicitly set on instruction '%s'" " but flag already inferred from pattern.\n", Inst.TheDef->getName().c_str()); - mayStore = true; + MayStore = true; } if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it. // If we decided that this is a load from the pattern, then the .td file // entry is redundant. - if (mayLoad) + if (MayLoad) fprintf(stderr, "Warning: mayLoad flag explicitly set on instruction '%s'" " but flag already inferred from pattern.\n", Inst.TheDef->getName().c_str()); - mayLoad = true; + MayLoad = true; } - - NeverHasSideEffects = Inst.neverHasSideEffects; - -#if 0 - // If the .td file explicitly says there is no side effect, believe it. - if (Inst.neverHasSideEffects) - NeverHasSideEffects = true; -#endif + if (Inst.neverHasSideEffects) { + // If we already decided that this instruction has no side effects, then the + // .td file entry is redundant. + if (!HasSideEffects) + fprintf(stderr, + "Warning: neverHasSideEffects flag explicitly set on instruction" + " '%s' but flag already inferred from pattern.\n", + Inst.TheDef->getName().c_str()); + HasSideEffects = false; + } } @@ -299,14 +308,8 @@ const OperandInfoMapTy &OpInfo, std::ostream &OS) { // Determine properties of the instruction from its pattern. - bool mayStore, mayLoad, NeverHasSideEffects; - InferFromPattern(Inst, mayStore, mayLoad, NeverHasSideEffects); - - if (NeverHasSideEffects && Inst.mayHaveSideEffects) { - std::cerr << "error: Instruction '" << Inst.TheDef->getName() - << "' is marked with 'mayHaveSideEffects', but it can never have them!\n"; - exit(1); - } + bool mayStore, mayLoad, HasSideEffects; + InferFromPattern(Inst, mayStore, mayLoad, HasSideEffects); int MinOperands = 0; if (!Inst.OperandList.empty()) @@ -341,7 +344,7 @@ OS << "|(1< Author: lattner Date: Wed Jan 9 23:40:54 2008 New Revision: 45823 URL: http://llvm.org/viewvc/llvm-project?rev=45823&view=rev Log: if an instr lacks a pattern, assume it has side effects (unless never has s-e is true). Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45823&r1=45822&r2=45823&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Wed Jan 9 23:40:54 2008 @@ -154,7 +154,10 @@ void Analyze(Record *InstRecord) { const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern(); - if (Pattern == 0) return; // No pattern. + if (Pattern == 0) { + HasSideEffects = 1; + return; // No pattern. + } // FIXME: Assume only the first tree is the pattern. The others are clobber // nodes. From sabre at nondot.org Wed Jan 9 23:45:40 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 05:45:40 -0000 Subject: [llvm-commits] [llvm] r45824 - in /llvm/trunk/lib/Target: PowerPC/PPCInstrInfo.td X86/X86InstrFPStack.td X86/X86InstrInfo.td X86/X86InstrMMX.td X86/X86InstrSSE.td X86/X86InstrX86-64.td Message-ID: <200801100545.m0A5jegA028220@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 23:45:39 2008 New Revision: 45824 URL: http://llvm.org/viewvc/llvm-project?rev=45824&view=rev Log: remove explicit sets of 'neverHasSideEffects' that can now be inferred from the instr patterns. Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrMMX.td llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/lib/Target/X86/X86InstrX86-64.td Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=45824&r1=45823&r2=45824&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Jan 9 23:45:39 2008 @@ -695,7 +695,7 @@ "subfic $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (subc immSExt16:$imm, GPRC:$rA))]>; -let isReMaterializable = 1, neverHasSideEffects = 1 in { +let isReMaterializable = 1 in { def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), "li $rD, $imm", IntGeneral, [(set GPRC:$rD, immSExt16:$imm)]>; Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=45824&r1=45823&r2=45824&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Wed Jan 9 23:45:39 2008 @@ -466,7 +466,7 @@ def XCH_F : FPI<0xC8, AddRegFrm, (outs), (ins RST:$op), "fxch\t$op">, D9; // Floating point constant loads. -let isReMaterializable = 1, neverHasSideEffects = 1 in { +let isReMaterializable = 1 in { def LD_Fp032 : FpIf32<(outs RFP32:$dst), (ins), ZeroArgFP, [(set RFP32:$dst, fpimm0)]>; def LD_Fp132 : FpIf32<(outs RFP32:$dst), (ins), ZeroArgFP, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45824&r1=45823&r2=45824&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Jan 9 23:45:39 2008 @@ -566,7 +566,7 @@ "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; -let isReMaterializable = 1, neverHasSideEffects = 1 in { +let isReMaterializable = 1 in { def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src), "mov{b}\t{$src, $dst|$dst, $src}", [(set GR8:$dst, imm:$src)]>; @@ -2466,7 +2466,7 @@ // Alias instructions that map movr0 to xor. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. -let Defs = [EFLAGS], isReMaterializable = 1, neverHasSideEffects = 1 in { +let Defs = [EFLAGS], isReMaterializable = 1 in { def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins), "xor{b}\t$dst, $dst", [(set GR8:$dst, 0)]>; Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=45824&r1=45823&r2=45824&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Wed Jan 9 23:45:39 2008 @@ -487,7 +487,7 @@ //===----------------------------------------------------------------------===// // Alias instructions that map zero vector to pxor. -let isReMaterializable = 1, neverHasSideEffects = 1 in { +let isReMaterializable = 1 in { def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (outs VR64:$dst), (ins), "pxor\t$dst, $dst", [(set VR64:$dst, (v2i32 immAllZerosV))]>; Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=45824&r1=45823&r2=45824&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Jan 9 23:45:39 2008 @@ -445,7 +445,7 @@ // start with 'Fs'. // Alias instructions that map fld0 to pxor for sse. -let isReMaterializable = 1, neverHasSideEffects = 1 in +let isReMaterializable = 1 in def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins), "pxor\t$dst, $dst", [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>, TB, OpSize; @@ -940,7 +940,7 @@ "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>; // Alias instructions that map zero vector to pxor / xorp* for sse. -let isReMaterializable = 1, neverHasSideEffects = 1 in +let isReMaterializable = 1 in def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "xorps\t$dst, $dst", [(set VR128:$dst, (v4i32 immAllZerosV))]>; @@ -1141,7 +1141,7 @@ // start with 'Fs'. // Alias instructions that map fld0 to pxor for sse. -let isReMaterializable = 1, neverHasSideEffects = 1 in +let isReMaterializable = 1 in def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins), "pxor\t$dst, $dst", [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>, TB, OpSize; @@ -2119,7 +2119,7 @@ // Alias instructions that map zero vector to pxor / xorp* for sse. -let isReMaterializable = 1, neverHasSideEffects = 1 in +let isReMaterializable = 1 in def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "pcmpeqd\t$dst, $dst", [(set VR128:$dst, (v4i32 immAllOnesV))]>; Modified: llvm/trunk/lib/Target/X86/X86InstrX86-64.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrX86-64.td?rev=45824&r1=45823&r2=45824&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td Wed Jan 9 23:45:39 2008 @@ -201,7 +201,7 @@ def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), "mov{q}\t{$src, $dst|$dst, $src}", []>; -let isReMaterializable = 1, neverHasSideEffects = 1 in { +let isReMaterializable = 1 in { def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src), "movabs{q}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, imm:$src)]>; @@ -1105,14 +1105,13 @@ // FIXME: remove when we can teach regalloc that xor reg, reg is ok. // FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove // when we have a better way to specify isel priority. -let Defs = [EFLAGS], AddedComplexity = 1, isReMaterializable = 1, - neverHasSideEffects = 1 in +let Defs = [EFLAGS], AddedComplexity = 1, isReMaterializable = 1 in def MOV64r0 : RI<0x31, MRMInitReg, (outs GR64:$dst), (ins), "xor{l}\t${dst:subreg32}, ${dst:subreg32}", [(set GR64:$dst, 0)]>; // Materialize i64 constant where top 32-bits are zero. -let AddedComplexity = 1, isReMaterializable = 1, neverHasSideEffects = 1 in +let AddedComplexity = 1, isReMaterializable = 1 in def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src), "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}", [(set GR64:$dst, i64immZExt32:$src)]>; From sabre at nondot.org Wed Jan 9 23:48:24 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 05:48:24 -0000 Subject: [llvm-commits] [llvm] r45825 - /llvm/trunk/lib/Target/TargetSelectionDAG.td Message-ID: <200801100548.m0A5mObh028356@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 23:48:23 2008 New Revision: 45825 URL: http://llvm.org/viewvc/llvm-project?rev=45825&view=rev Log: add SDNPSideEffect node property declaration Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=45825&r1=45824&r2=45825&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/lib/Target/TargetSelectionDAG.td Wed Jan 9 23:48:23 2008 @@ -191,6 +191,7 @@ def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. +def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. //===----------------------------------------------------------------------===// // Selection DAG Node definitions. From sabre at nondot.org Wed Jan 9 23:50:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 05:50:42 -0000 Subject: [llvm-commits] [llvm] r45826 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.td X86InstrX86-64.td Message-ID: <200801100550.m0A5ogYU028490@zion.cs.uiuc.edu> Author: lattner Date: Wed Jan 9 23:50:42 2008 New Revision: 45826 URL: http://llvm.org/viewvc/llvm-project?rev=45826&view=rev Log: rename X86InstrX86-64.td -> X86Instr64bit.td Added: llvm/trunk/lib/Target/X86/X86Instr64bit.td - copied, changed from r45824, llvm/trunk/lib/Target/X86/X86InstrX86-64.td Removed: llvm/trunk/lib/Target/X86/X86InstrX86-64.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td Copied: llvm/trunk/lib/Target/X86/X86Instr64bit.td (from r45824, llvm/trunk/lib/Target/X86/X86InstrX86-64.td) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?p2=llvm/trunk/lib/Target/X86/X86Instr64bit.td&p1=llvm/trunk/lib/Target/X86/X86InstrX86-64.td&r1=45824&r2=45826&rev=45826&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Wed Jan 9 23:50:42 2008 @@ -1,4 +1,4 @@ -//====- X86InstrX86-64.td - Describe the X86 Instr. Set ----*- tablegen -*-===// +//====- X86Instr64bit.td - Describe X86-64 Instructions ----*- tablegen -*-===// // // The LLVM Compiler Infrastructure // @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// Operand Definitions... +// Operand Definitions. // // 64-bits but only 32 bits are significant. @@ -33,14 +33,14 @@ } //===----------------------------------------------------------------------===// -// Complex Pattern Definitions... +// Complex Pattern Definitions. // def lea64addr : ComplexPattern; //===----------------------------------------------------------------------===// -// Pattern fragments... +// Pattern fragments. // def i64immSExt32 : PatLeaf<(i64 imm), [{ Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45826&r1=45825&r2=45826&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Jan 9 23:50:42 2008 @@ -2711,7 +2711,7 @@ // X86-64 Support //===----------------------------------------------------------------------===// -include "X86InstrX86-64.td" +include "X86Instr64bit.td" //===----------------------------------------------------------------------===// // MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2) Removed: llvm/trunk/lib/Target/X86/X86InstrX86-64.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrX86-64.td?rev=45825&view=auto ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrX86-64.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrX86-64.td (removed) @@ -1,1276 +0,0 @@ -//====- X86InstrX86-64.td - Describe the X86 Instr. Set ----*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file describes the X86-64 instruction set, defining the instructions, -// and properties of the instructions which are needed for code generation, -// machine code emission, and analysis. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Operand Definitions... -// - -// 64-bits but only 32 bits are significant. -def i64i32imm : Operand; -// 64-bits but only 8 bits are significant. -def i64i8imm : Operand; - -def lea64mem : Operand { - let PrintMethod = "printi64mem"; - let MIOperandInfo = (ops GR64, i8imm, GR64, i32imm); -} - -def lea64_32mem : Operand { - let PrintMethod = "printlea64_32mem"; - let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm); -} - -//===----------------------------------------------------------------------===// -// Complex Pattern Definitions... -// -def lea64addr : ComplexPattern; - -//===----------------------------------------------------------------------===// -// Pattern fragments... -// - -def i64immSExt32 : PatLeaf<(i64 imm), [{ - // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit - // sign extended field. - return (int64_t)N->getValue() == (int32_t)N->getValue(); -}]>; - -def i64immZExt32 : PatLeaf<(i64 imm), [{ - // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit - // unsignedsign extended field. - return (uint64_t)N->getValue() == (uint32_t)N->getValue(); -}]>; - -def i64immSExt8 : PatLeaf<(i64 imm), [{ - // i64immSExt8 predicate - True if the 64-bit immediate fits in a 8-bit - // sign extended field. - return (int64_t)N->getValue() == (int8_t)N->getValue(); -}]>; - -def sextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (sextloadi1 node:$ptr))>; -def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>; -def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>; -def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>; - -def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>; -def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>; -def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>; -def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>; - -def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>; -def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>; -def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>; -def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>; - -//===----------------------------------------------------------------------===// -// Instruction list... -// - -let isImplicitDef = 1 in -def IMPLICIT_DEF_GR64 : I<0, Pseudo, (outs GR64:$dst), (ins), - "#IMPLICIT_DEF $dst", - [(set GR64:$dst, (undef))]>; - -//===----------------------------------------------------------------------===// -// Call Instructions... -// -let isCall = 1 in - // All calls clobber the non-callee saved registers... - let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, - FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, - MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, - XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS] in { - def CALL64pcrel32 : I<0xE8, RawFrm, (outs), (ins i64imm:$dst, variable_ops), - "call\t${dst:call}", []>; - def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops), - "call\t{*}$dst", [(X86call GR64:$dst)]>; - def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops), - "call\t{*}$dst", []>; - } - - - -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in -def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset), - "#TC_RETURN $dst $offset", - []>; - -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in -def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset), - "#TC_RETURN $dst $offset", - []>; - - -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in - def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst # TAILCALL", - []>; - -// Branches -let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { - def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst", - [(brind GR64:$dst)]>; - def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst", - [(brind (loadi64 addr:$dst))]>; -} - -//===----------------------------------------------------------------------===// -// Miscellaneous Instructions... -// -let Defs = [RBP,RSP], Uses = [RBP,RSP] in -def LEAVE64 : I<0xC9, RawFrm, - (outs), (ins), "leave", []>; -let Defs = [RSP], Uses = [RSP] in { -def POP64r : I<0x58, AddRegFrm, - (outs GR64:$reg), (ins), "pop{q}\t$reg", []>; -def PUSH64r : I<0x50, AddRegFrm, - (outs), (ins GR64:$reg), "push{q}\t$reg", []>; -} - -let Defs = [RSP, EFLAGS], Uses = [RSP] in -def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W; -let Defs = [RSP], Uses = [RSP, EFLAGS] in -def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>; - -def LEA64_32r : I<0x8D, MRMSrcMem, - (outs GR32:$dst), (ins lea64_32mem:$src), - "lea{l}\t{$src|$dst}, {$dst|$src}", - [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>; - -def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src), - "lea{q}\t{$src|$dst}, {$dst|$src}", - [(set GR64:$dst, lea64addr:$src)]>; - -let isTwoAddress = 1 in -def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src), - "bswap{q}\t$dst", - [(set GR64:$dst, (bswap GR64:$src))]>, TB; -// Exchange -def XCHG64rr : RI<0x87, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), - "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG64mr : RI<0x87, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), - "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG64rm : RI<0x87, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), - "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; - -// Bit scan instructions. -let Defs = [EFLAGS] in { -def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), - "bsf{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (X86bsf GR64:$src)), (implicit EFLAGS)]>, TB; -def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), - "bsf{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (X86bsf (loadi64 addr:$src))), - (implicit EFLAGS)]>, TB; - -def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), - "bsr{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (X86bsr GR64:$src)), (implicit EFLAGS)]>, TB; -def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), - "bsr{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (X86bsr (loadi64 addr:$src))), - (implicit EFLAGS)]>, TB; -} // Defs = [EFLAGS] - -// Repeat string ops -let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI] in -def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}", - [(X86rep_movs i64)]>, REP; -let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI] in -def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}", - [(X86rep_stos i64)]>, REP; - -//===----------------------------------------------------------------------===// -// Move Instructions... -// - -def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), - "mov{q}\t{$src, $dst|$dst, $src}", []>; - -let isReMaterializable = 1 in { -def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src), - "movabs{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, imm:$src)]>; -def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src), - "mov{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, i64immSExt32:$src)]>; -} - -let isSimpleLoad = 1 in -def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), - "mov{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (load addr:$src))]>; - -def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), - "mov{q}\t{$src, $dst|$dst, $src}", - [(store GR64:$src, addr:$dst)]>; -def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src), - "mov{q}\t{$src, $dst|$dst, $src}", - [(store i64immSExt32:$src, addr:$dst)]>; - -// Sign/Zero extenders - -def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src), - "movs{bq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (sext GR8:$src))]>, TB; -def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src), - "movs{bq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB; -def MOVSX64rr16: RI<0xBF, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src), - "movs{wq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (sext GR16:$src))]>, TB; -def MOVSX64rm16: RI<0xBF, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src), - "movs{wq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB; -def MOVSX64rr32: RI<0x63, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src), - "movs{lq|xd}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (sext GR32:$src))]>; -def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src), - "movs{lq|xd}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (sextloadi64i32 addr:$src))]>; - -def MOVZX64rr8 : RI<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src), - "movz{bq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (zext GR8:$src))]>, TB; -def MOVZX64rm8 : RI<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src), - "movz{bq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB; -def MOVZX64rr16: RI<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src), - "movz{wq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (zext GR16:$src))]>, TB; -def MOVZX64rm16: RI<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src), - "movz{wq|x}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB; - -let Defs = [RAX], Uses = [EAX] in -def CDQE : RI<0x98, RawFrm, (outs), (ins), - "{cltq|cdqe}", []>; // RAX = signext(EAX) - -let Defs = [RAX,RDX], Uses = [RAX] in -def CQO : RI<0x99, RawFrm, (outs), (ins), - "{cqto|cqo}", []>; // RDX:RAX = signext(RAX) - -//===----------------------------------------------------------------------===// -// Arithmetic Instructions... -// - -let Defs = [EFLAGS] in { -let isTwoAddress = 1 in { -let isConvertibleToThreeAddress = 1 in { -let isCommutable = 1 in -def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, GR64:$src2))]>; - -def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2))]>; -def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2))]>; -} // isConvertibleToThreeAddress - -def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, (load addr:$src2)))]>; -} // isTwoAddress - -def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR64:$src2), addr:$dst)]>; -def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>; -def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2), - "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; - -let Uses = [EFLAGS] in { -let isTwoAddress = 1 in { -let isCommutable = 1 in -def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>; - -def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>; - -def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>; -def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>; -} // isTwoAddress - -def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>; -def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; -def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2), - "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; -} // Uses = [EFLAGS] - -let isTwoAddress = 1 in { -def SUB64rr : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>; - -def SUB64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sub GR64:$src1, (load addr:$src2)))]>; - -def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sub GR64:$src1, i64immSExt32:$src2))]>; -def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sub GR64:$src1, i64immSExt8:$src2))]>; -} // isTwoAddress - -def SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(store (sub (load addr:$dst), GR64:$src2), addr:$dst)]>; -def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(store (sub (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>; -def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm :$src2), - "sub{q}\t{$src2, $dst|$dst, $src2}", - [(store (sub (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; - -let Uses = [EFLAGS] in { -let isTwoAddress = 1 in { -def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>; - -def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>; - -def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>; -def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>; -} // isTwoAddress - -def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>; -def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>; -def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2), - "sbb{q}\t{$src2, $dst|$dst, $src2}", - [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; -} // Uses = [EFLAGS] -} // Defs = [EFLAGS] - -// Unsigned multiplication -let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in { -def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src), - "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64 -def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src), - "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64] - -// Signed multiplication -def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), - "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64 -def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src), - "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64] -} - -let Defs = [EFLAGS] in { -let isTwoAddress = 1 in { -let isCommutable = 1 in -def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "imul{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>, TB; - -def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "imul{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (mul GR64:$src1, (load addr:$src2)))]>, TB; -} // isTwoAddress - -// Suprisingly enough, these are not two address instructions! -def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32 - (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", - [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2))]>; -def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8 - (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", - [(set GR64:$dst, (mul GR64:$src1, i64immSExt8:$src2))]>; -def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32 - (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2), - "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", - [(set GR64:$dst, (mul (load addr:$src1), i64immSExt32:$src2))]>; -def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8 - (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2), - "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", - [(set GR64:$dst, (mul (load addr:$src1), i64immSExt8:$src2))]>; -} // Defs = [EFLAGS] - -// Unsigned division / remainder -let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in { -def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX - "div{q}\t$src", []>; -def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX - "div{q}\t$src", []>; - -// Signed division / remainder -def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX - "idiv{q}\t$src", []>; -def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX - "idiv{q}\t$src", []>; -} - -// Unary instructions -let Defs = [EFLAGS], CodeSize = 2 in { -let isTwoAddress = 1 in -def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst", - [(set GR64:$dst, (ineg GR64:$src))]>; -def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst", - [(store (ineg (loadi64 addr:$dst)), addr:$dst)]>; - -let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in -def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src), "inc{q}\t$dst", - [(set GR64:$dst, (add GR64:$src, 1))]>; -def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst", - [(store (add (loadi64 addr:$dst), 1), addr:$dst)]>; - -let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in -def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src), "dec{q}\t$dst", - [(set GR64:$dst, (add GR64:$src, -1))]>; -def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst", - [(store (add (loadi64 addr:$dst), -1), addr:$dst)]>; - -// In 64-bit mode, single byte INC and DEC cannot be encoded. -let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in { -// Can transform into LEA. -def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src), "inc{w}\t$dst", - [(set GR16:$dst, (add GR16:$src, 1))]>, - OpSize, Requires<[In64BitMode]>; -def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src), "inc{l}\t$dst", - [(set GR32:$dst, (add GR32:$src, 1))]>, - Requires<[In64BitMode]>; -def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src), "dec{w}\t$dst", - [(set GR16:$dst, (add GR16:$src, -1))]>, - OpSize, Requires<[In64BitMode]>; -def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src), "dec{l}\t$dst", - [(set GR32:$dst, (add GR32:$src, -1))]>, - Requires<[In64BitMode]>; -} // isConvertibleToThreeAddress - -// These are duplicates of their 32-bit counterparts. Only needed so X86 knows -// how to unfold them. -let isTwoAddress = 0, CodeSize = 2 in { - def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst", - [(store (add (loadi16 addr:$dst), 1), addr:$dst)]>, - OpSize, Requires<[In64BitMode]>; - def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst", - [(store (add (loadi32 addr:$dst), 1), addr:$dst)]>, - Requires<[In64BitMode]>; - def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst", - [(store (add (loadi16 addr:$dst), -1), addr:$dst)]>, - OpSize, Requires<[In64BitMode]>; - def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst", - [(store (add (loadi32 addr:$dst), -1), addr:$dst)]>, - Requires<[In64BitMode]>; -} -} // Defs = [EFLAGS], CodeSize - - -let Defs = [EFLAGS] in { -// Shift instructions -let isTwoAddress = 1 in { -let Uses = [CL] in -def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src), - "shl{q}\t{%cl, $dst|$dst, %CL}", - [(set GR64:$dst, (shl GR64:$src, CL))]>; -let isConvertibleToThreeAddress = 1 in // Can transform into LEA. -def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), - "shl{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>; -def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1), - "shl{q}\t$dst", []>; -} // isTwoAddress - -let Uses = [CL] in -def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst), - "shl{q}\t{%cl, $dst|$dst, %CL}", - [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>; -def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src), - "shl{q}\t{$src, $dst|$dst, $src}", - [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>; -def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst), - "shl{q}\t$dst", - [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>; - -let isTwoAddress = 1 in { -let Uses = [CL] in -def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src), - "shr{q}\t{%cl, $dst|$dst, %CL}", - [(set GR64:$dst, (srl GR64:$src, CL))]>; -def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), - "shr{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>; -def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1), - "shr{q}\t$dst", - [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>; -} // isTwoAddress - -let Uses = [CL] in -def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst), - "shr{q}\t{%cl, $dst|$dst, %CL}", - [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>; -def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src), - "shr{q}\t{$src, $dst|$dst, $src}", - [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>; -def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst), - "shr{q}\t$dst", - [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>; - -let isTwoAddress = 1 in { -let Uses = [CL] in -def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src), - "sar{q}\t{%cl, $dst|$dst, %CL}", - [(set GR64:$dst, (sra GR64:$src, CL))]>; -def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), - "sar{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>; -def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1), - "sar{q}\t$dst", - [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>; -} // isTwoAddress - -let Uses = [CL] in -def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst), - "sar{q}\t{%cl, $dst|$dst, %CL}", - [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>; -def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src), - "sar{q}\t{$src, $dst|$dst, $src}", - [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>; -def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst), - "sar{q}\t$dst", - [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>; - -// Rotate instructions -let isTwoAddress = 1 in { -let Uses = [CL] in -def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src), - "rol{q}\t{%cl, $dst|$dst, %CL}", - [(set GR64:$dst, (rotl GR64:$src, CL))]>; -def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), - "rol{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>; -def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1), - "rol{q}\t$dst", - [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>; -} // isTwoAddress - -let Uses = [CL] in -def ROL64mCL : I<0xD3, MRM0m, (outs), (ins i64mem:$dst), - "rol{q}\t{%cl, $dst|$dst, %CL}", - [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>; -def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src), - "rol{q}\t{$src, $dst|$dst, $src}", - [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>; -def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst), - "rol{q}\t$dst", - [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>; - -let isTwoAddress = 1 in { -let Uses = [CL] in -def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src), - "ror{q}\t{%cl, $dst|$dst, %CL}", - [(set GR64:$dst, (rotr GR64:$src, CL))]>; -def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), - "ror{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>; -def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1), - "ror{q}\t$dst", - [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>; -} // isTwoAddress - -let Uses = [CL] in -def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst), - "ror{q}\t{%cl, $dst|$dst, %CL}", - [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>; -def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src), - "ror{q}\t{$src, $dst|$dst, $src}", - [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>; -def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst), - "ror{q}\t$dst", - [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>; - -// Double shift instructions (generalizations of rotate) -let isTwoAddress = 1 in { -let Uses = [CL] in { -def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", - [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>, TB; -def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", - [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>, TB; -} - -let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction -def SHLD64rri8 : RIi8<0xA4, MRMDestReg, - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3), - "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, - (i8 imm:$src3)))]>, - TB; -def SHRD64rri8 : RIi8<0xAC, MRMDestReg, - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3), - "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, - (i8 imm:$src3)))]>, - TB; -} // isCommutable -} // isTwoAddress - -let Uses = [CL] in { -def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), - "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", - [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL), - addr:$dst)]>, TB; -def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), - "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", - [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL), - addr:$dst)]>, TB; -} -def SHLD64mri8 : RIi8<0xA4, MRMDestMem, - (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3), - "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(store (X86shld (loadi64 addr:$dst), GR64:$src2, - (i8 imm:$src3)), addr:$dst)]>, - TB; -def SHRD64mri8 : RIi8<0xAC, MRMDestMem, - (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3), - "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, - (i8 imm:$src3)), addr:$dst)]>, - TB; -} // Defs = [EFLAGS] - -//===----------------------------------------------------------------------===// -// Logical Instructions... -// - -let isTwoAddress = 1 in -def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst", - [(set GR64:$dst, (not GR64:$src))]>; -def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst", - [(store (not (loadi64 addr:$dst)), addr:$dst)]>; - -let Defs = [EFLAGS] in { -let isTwoAddress = 1 in { -let isCommutable = 1 in -def AND64rr : RI<0x21, MRMDestReg, - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "and{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>; -def AND64rm : RI<0x23, MRMSrcMem, - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "and{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (and GR64:$src1, (load addr:$src2)))]>; -def AND64ri32 : RIi32<0x81, MRM4r, - (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "and{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (and GR64:$src1, i64immSExt32:$src2))]>; -def AND64ri8 : RIi8<0x83, MRM4r, - (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "and{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (and GR64:$src1, i64immSExt8:$src2))]>; -} // isTwoAddress - -def AND64mr : RI<0x21, MRMDestMem, - (outs), (ins i64mem:$dst, GR64:$src), - "and{q}\t{$src, $dst|$dst, $src}", - [(store (and (load addr:$dst), GR64:$src), addr:$dst)]>; -def AND64mi32 : RIi32<0x81, MRM4m, - (outs), (ins i64mem:$dst, i64i32imm:$src), - "and{q}\t{$src, $dst|$dst, $src}", - [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst)]>; -def AND64mi8 : RIi8<0x83, MRM4m, - (outs), (ins i64mem:$dst, i64i8imm :$src), - "and{q}\t{$src, $dst|$dst, $src}", - [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst)]>; - -let isTwoAddress = 1 in { -let isCommutable = 1 in -def OR64rr : RI<0x09, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "or{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>; -def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "or{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (or GR64:$src1, (load addr:$src2)))]>; -def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "or{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2))]>; -def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "or{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2))]>; -} // isTwoAddress - -def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), - "or{q}\t{$src, $dst|$dst, $src}", - [(store (or (load addr:$dst), GR64:$src), addr:$dst)]>; -def OR64mi32 : RIi32<0x81, MRM1m, (outs), (ins i64mem:$dst, i64i32imm:$src), - "or{q}\t{$src, $dst|$dst, $src}", - [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst)]>; -def OR64mi8 : RIi8<0x83, MRM1m, (outs), (ins i64mem:$dst, i64i8imm:$src), - "or{q}\t{$src, $dst|$dst, $src}", - [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst)]>; - -let isTwoAddress = 1 in { -let isCommutable = 1 in -def XOR64rr : RI<0x31, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "xor{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>; -def XOR64rm : RI<0x33, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "xor{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (xor GR64:$src1, (load addr:$src2)))]>; -def XOR64ri32 : RIi32<0x81, MRM6r, - (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "xor{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (xor GR64:$src1, i64immSExt32:$src2))]>; -def XOR64ri8 : RIi8<0x83, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), - "xor{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (xor GR64:$src1, i64immSExt8:$src2))]>; -} // isTwoAddress - -def XOR64mr : RI<0x31, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), - "xor{q}\t{$src, $dst|$dst, $src}", - [(store (xor (load addr:$dst), GR64:$src), addr:$dst)]>; -def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src), - "xor{q}\t{$src, $dst|$dst, $src}", - [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst)]>; -def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src), - "xor{q}\t{$src, $dst|$dst, $src}", - [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst)]>; -} // Defs = [EFLAGS] - -//===----------------------------------------------------------------------===// -// Comparison Instructions... -// - -// Integer comparison -let Defs = [EFLAGS] in { -let isCommutable = 1 in -def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR64:$src1, GR64:$src2), 0), - (implicit EFLAGS)]>; -def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0), - (implicit EFLAGS)]>; -def TEST64ri32 : RIi32<0xF7, MRM0r, (outs), - (ins GR64:$src1, i64i32imm:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0), - (implicit EFLAGS)]>; -def TEST64mi32 : RIi32<0xF7, MRM0m, (outs), - (ins i64mem:$src1, i64i32imm:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0), - (implicit EFLAGS)]>; - -def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, GR64:$src2), - (implicit EFLAGS)]>; -def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi64 addr:$src1), GR64:$src2), - (implicit EFLAGS)]>; -def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, (loadi64 addr:$src2)), - (implicit EFLAGS)]>; -def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, i64immSExt32:$src2), - (implicit EFLAGS)]>; -def CMP64mi32 : RIi32<0x81, MRM7m, (outs), - (ins i64mem:$src1, i64i32imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2), - (implicit EFLAGS)]>; -def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2), - (implicit EFLAGS)]>; -def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(X86cmp GR64:$src1, i64immSExt8:$src2), - (implicit EFLAGS)]>; -} // Defs = [EFLAGS] - -// Conditional moves -let Uses = [EFLAGS], isTwoAddress = 1 in { -let isCommutable = 1 in { -def CMOVB64rr : RI<0x42, MRMSrcReg, // if , TB; -def CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovae\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_AE, EFLAGS))]>, TB; -def CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmove\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_E, EFLAGS))]>, TB; -def CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovne\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_NE, EFLAGS))]>, TB; -def CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovbe\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_BE, EFLAGS))]>, TB; -def CMOVA64rr : RI<0x47, MRMSrcReg, // if >u, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmova\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_A, EFLAGS))]>, TB; -def CMOVL64rr : RI<0x4C, MRMSrcReg, // if , TB; -def CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovge\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_GE, EFLAGS))]>, TB; -def CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovle\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_LE, EFLAGS))]>, TB; -def CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovg\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_G, EFLAGS))]>, TB; -def CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovs\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_S, EFLAGS))]>, TB; -def CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovns\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_NS, EFLAGS))]>, TB; -def CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovp\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_P, EFLAGS))]>, TB; -def CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, GR64 = GR64 - (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), - "cmovnp\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2, - X86_COND_NP, EFLAGS))]>, TB; -} // isCommutable = 1 - -def CMOVB64rm : RI<0x42, MRMSrcMem, // if , TB; -def CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovae\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_AE, EFLAGS))]>, TB; -def CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmove\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_E, EFLAGS))]>, TB; -def CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovne\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_NE, EFLAGS))]>, TB; -def CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovbe\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_BE, EFLAGS))]>, TB; -def CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmova\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_A, EFLAGS))]>, TB; -def CMOVL64rm : RI<0x4C, MRMSrcMem, // if , TB; -def CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovge\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_GE, EFLAGS))]>, TB; -def CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovle\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_LE, EFLAGS))]>, TB; -def CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovg\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_G, EFLAGS))]>, TB; -def CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovs\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_S, EFLAGS))]>, TB; -def CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovns\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_NS, EFLAGS))]>, TB; -def CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovp\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_P, EFLAGS))]>, TB; -def CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64] - (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), - "cmovnp\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2), - X86_COND_NP, EFLAGS))]>, TB; -} // isTwoAddress - -//===----------------------------------------------------------------------===// -// Conversion Instructions... -// - -// f64 -> signed i64 -def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src), - "cvtsd2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, - (int_x86_sse2_cvtsd2si64 VR128:$src))]>; -def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src), - "cvtsd2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (int_x86_sse2_cvtsd2si64 - (load addr:$src)))]>; -def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src), - "cvttsd2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (fp_to_sint FR64:$src))]>; -def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src), - "cvttsd2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>; -def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src), - "cvttsd2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, - (int_x86_sse2_cvttsd2si64 VR128:$src))]>; -def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src), - "cvttsd2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, - (int_x86_sse2_cvttsd2si64 - (load addr:$src)))]>; - -// Signed i64 -> f64 -def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src), - "cvtsi2sd{q}\t{$src, $dst|$dst, $src}", - [(set FR64:$dst, (sint_to_fp GR64:$src))]>; -def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src), - "cvtsi2sd{q}\t{$src, $dst|$dst, $src}", - [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>; -let isTwoAddress = 1 in { -def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), - "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (int_x86_sse2_cvtsi642sd VR128:$src1, - GR64:$src2))]>; -def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), - "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (int_x86_sse2_cvtsi642sd VR128:$src1, - (loadi64 addr:$src2)))]>; -} // isTwoAddress - -// Signed i64 -> f32 -def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR64:$src), - "cvtsi2ss{q}\t{$src, $dst|$dst, $src}", - [(set FR32:$dst, (sint_to_fp GR64:$src))]>; -def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src), - "cvtsi2ss{q}\t{$src, $dst|$dst, $src}", - [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>; -let isTwoAddress = 1 in { -def Int_CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - []>; // TODO: add intrinsic -def Int_CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - []>; // TODO: add intrinsic -} // isTwoAddress - -// f32 -> signed i64 -def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src), - "cvtss2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, - (int_x86_sse_cvtss2si64 VR128:$src))]>; -def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src), - "cvtss2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (int_x86_sse_cvtss2si64 - (load addr:$src)))]>; -def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src), - "cvttss2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (fp_to_sint FR32:$src))]>; -def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src), - "cvttss2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>; -def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src), - "cvttss2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, - (int_x86_sse_cvttss2si64 VR128:$src))]>; -def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src), - "cvttss2si{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, - (int_x86_sse_cvttss2si64 (load addr:$src)))]>; - -let isTwoAddress = 1 in { - def Int_CVTSI642SSrr : RSSI<0x2A, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (int_x86_sse_cvtsi642ss VR128:$src1, - GR64:$src2))]>; - def Int_CVTSI642SSrm : RSSI<0x2A, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (int_x86_sse_cvtsi642ss VR128:$src1, - (loadi64 addr:$src2)))]>; -} - -//===----------------------------------------------------------------------===// -// Alias Instructions -//===----------------------------------------------------------------------===// - -// Zero-extension -// TODO: Remove this after proper i32 -> i64 zext support. -def PsMOVZX64rr32: I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src), - "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}", - [(set GR64:$dst, (zext GR32:$src))]>; -def PsMOVZX64rm32: I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src), - "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}", - [(set GR64:$dst, (zextloadi64i32 addr:$src))]>; - - -// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's -// equivalent due to implicit zero-extending, and it sometimes has a smaller -// encoding. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. -// FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove -// when we have a better way to specify isel priority. -let Defs = [EFLAGS], AddedComplexity = 1, isReMaterializable = 1 in -def MOV64r0 : RI<0x31, MRMInitReg, (outs GR64:$dst), (ins), - "xor{l}\t${dst:subreg32}, ${dst:subreg32}", - [(set GR64:$dst, 0)]>; - -// Materialize i64 constant where top 32-bits are zero. -let AddedComplexity = 1, isReMaterializable = 1 in -def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src), - "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}", - [(set GR64:$dst, i64immZExt32:$src)]>; - -//===----------------------------------------------------------------------===// -// Non-Instruction Patterns -//===----------------------------------------------------------------------===// - -// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable -def : Pat<(i64 (X86Wrapper tconstpool :$dst)), - (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>; -def : Pat<(i64 (X86Wrapper tjumptable :$dst)), - (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>; -def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), - (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>; -def : Pat<(i64 (X86Wrapper texternalsym:$dst)), - (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>; - -def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst), - (MOV64mi32 addr:$dst, tconstpool:$src)>, - Requires<[SmallCode, HasLow4G, IsStatic]>; -def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst), - (MOV64mi32 addr:$dst, tjumptable:$src)>, - Requires<[SmallCode, HasLow4G, IsStatic]>; -def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst), - (MOV64mi32 addr:$dst, tglobaladdr:$src)>, - Requires<[SmallCode, HasLow4G, IsStatic]>; -def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst), - (MOV64mi32 addr:$dst, texternalsym:$src)>, - Requires<[SmallCode, HasLow4G, IsStatic]>; - -// Calls -// Direct PC relative function call for small code model. 32-bit displacement -// sign extended to 64-bit. -def : Pat<(X86call (i64 tglobaladdr:$dst)), - (CALL64pcrel32 tglobaladdr:$dst)>; -def : Pat<(X86call (i64 texternalsym:$dst)), - (CALL64pcrel32 texternalsym:$dst)>; - -def : Pat<(X86tailcall (i64 tglobaladdr:$dst)), - (CALL64pcrel32 tglobaladdr:$dst)>; -def : Pat<(X86tailcall (i64 texternalsym:$dst)), - (CALL64pcrel32 texternalsym:$dst)>; - -def : Pat<(X86tailcall GR64:$dst), - (CALL64r GR64:$dst)>; - - -// tailcall stuff -def : Pat<(X86tailcall GR32:$dst), - (TAILCALL)>; -def : Pat<(X86tailcall (i64 tglobaladdr:$dst)), - (TAILCALL)>; -def : Pat<(X86tailcall (i64 texternalsym:$dst)), - (TAILCALL)>; - -def : Pat<(X86tcret GR64:$dst, imm:$off), - (TCRETURNri64 GR64:$dst, imm:$off)>; - -def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), - (TCRETURNdi64 texternalsym:$dst, imm:$off)>; - -def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), - (TCRETURNdi64 texternalsym:$dst, imm:$off)>; - -// Comparisons. - -// TEST R,R is smaller than CMP R,0 -def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)), - (TEST64rr GR64:$src1, GR64:$src1)>; - -// {s|z}extload bool -> {s|z}extload byte -def : Pat<(sextloadi64i1 addr:$src), (MOVSX64rm8 addr:$src)>; -def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>; - -// extload -def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>; -def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>; -def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>; -def : Pat<(extloadi64i32 addr:$src), (PsMOVZX64rm32 addr:$src)>; - -// anyext -> zext -def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>; -def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>; -def : Pat<(i64 (anyext GR32:$src)), (PsMOVZX64rr32 GR32:$src)>; -def : Pat<(i64 (anyext (loadi8 addr:$src))), (MOVZX64rm8 addr:$src)>; -def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>; -def : Pat<(i64 (anyext (loadi32 addr:$src))), (PsMOVZX64rm32 addr:$src)>; - -//===----------------------------------------------------------------------===// -// Some peepholes -//===----------------------------------------------------------------------===// - -// (shl x, 1) ==> (add x, x) -def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>; - -// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c) -def : Pat<(or (srl GR64:$src1, CL:$amt), - (shl GR64:$src2, (sub 64, CL:$amt))), - (SHRD64rrCL GR64:$src1, GR64:$src2)>; - -def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt), - (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst), - (SHRD64mrCL addr:$dst, GR64:$src2)>; - -// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c) -def : Pat<(or (shl GR64:$src1, CL:$amt), - (srl GR64:$src2, (sub 64, CL:$amt))), - (SHLD64rrCL GR64:$src1, GR64:$src2)>; - -def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt), - (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst), - (SHLD64mrCL addr:$dst, GR64:$src2)>; - -// X86 specific add which produces a flag. -def : Pat<(addc GR64:$src1, GR64:$src2), - (ADD64rr GR64:$src1, GR64:$src2)>; -def : Pat<(addc GR64:$src1, (load addr:$src2)), - (ADD64rm GR64:$src1, addr:$src2)>; -def : Pat<(addc GR64:$src1, i64immSExt32:$src2), - (ADD64ri32 GR64:$src1, imm:$src2)>; -def : Pat<(addc GR64:$src1, i64immSExt8:$src2), - (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>; - -def : Pat<(subc GR64:$src1, GR64:$src2), - (SUB64rr GR64:$src1, GR64:$src2)>; -def : Pat<(subc GR64:$src1, (load addr:$src2)), - (SUB64rm GR64:$src1, addr:$src2)>; -def : Pat<(subc GR64:$src1, imm:$src2), - (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>; -def : Pat<(subc GR64:$src1, i64immSExt8:$src2), - (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>; - - -//===----------------------------------------------------------------------===// -// X86-64 SSE Instructions -//===----------------------------------------------------------------------===// - -// Move instructions... - -def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", - [(set VR128:$dst, - (v2i64 (scalar_to_vector GR64:$src)))]>; -def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (vector_extract (v2i64 VR128:$src), - (iPTR 0)))]>; - -def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", - [(set FR64:$dst, (bitconvert GR64:$src))]>; -def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", - [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>; - -def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, (bitconvert FR64:$src))]>; -def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src), - "mov{d|q}\t{$src, $dst|$dst, $src}", - [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>; From isanbard at gmail.com Thu Jan 10 00:41:03 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 9 Jan 2008 22:41:03 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45804 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm.h objc/objc-act.c In-Reply-To: <77BC5242-44E7-4676-A152-EE40AC807CB9@apple.com> References: <200801100128.m0A1SPD1010358@zion.cs.uiuc.edu> <77BC5242-44E7-4676-A152-EE40AC807CB9@apple.com> Message-ID: <9707B0E5-13EE-466C-8E4A-BA438E04742B@gmail.com> On Jan 9, 2008, at 5:57 PM, Chris Lattner wrote: > > On Jan 9, 2008, at 5:28 PM, Bill Wendling wrote: > >> Author: void >> Date: Wed Jan 9 19:28:25 2008 >> New Revision: 45804 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45804&view=rev >> Log: >> We're creating incorrect metadata. LLVM gives this for class >> references: > > Hey Bill, > > Is it possible to avoid having the llvm-front-end called on the objc > metadata before its fully formed? It might be possible. I'm just not sure how much work it will take. The LLVM front end is called a lot during metadata creation. Though in the end it would probably be the best thing to do. > Alternatively, perhaps the objc > front-end should set the early version of the metadata as being an > extern instead of definition? > I can try this and see if it has the same effect. -bw > -Chris > >> >> L_OBJC_CLASS_REFERENCES_0: >> .space 4 >> .. >> L_OBJC_CLASS_NAME_0: >> ... >> >> while GCC gives: >> >> L_OBJC_CLASS_REFERENCES_0: >> .long L_OBJC_CLASS_NAME_0 >> .. >> L_OBJC_CLASS_NAME_0: >> ... >> >> which is correct. What's happening is that the reference is being >> created and >> LLVM is setting it's initializer to "null" because it's not pointing >> to >> something at that time. But then reference is modified to point to >> some >> object. However, LLVM wasn't updating its initializer information at >> that point. >> >> >> Modified: >> llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp >> llvm-gcc-4.2/trunk/gcc/llvm.h >> llvm-gcc-4.2/trunk/gcc/objc/objc-act.c >> >> Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=45804&r1=45803&r2=45804&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> === >> =================================================================== >> --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Jan 9 19:28:25 2008 >> @@ -798,6 +798,17 @@ >> } >> } >> >> +/// reset_initializer_llvm - Change the initializer for a global >> variable. >> +void reset_initializer_llvm(tree decl) { >> + // Get or create the global variable now. >> + GlobalVariable *GV = cast(DECL_LLVM(decl)); >> + >> + // Convert the initializer over. >> + Constant *Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl)); >> + >> + // Set the initializer. >> + GV->setInitializer(Init); >> +} >> >> /// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate >> CONST_DECL to >> /// LLVM as a global variable. This function implements the end of >> >> Modified: llvm-gcc-4.2/trunk/gcc/llvm.h >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm.h?rev=45804&r1=45803&r2=45804&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> === >> =================================================================== >> --- llvm-gcc-4.2/trunk/gcc/llvm.h (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm.h Wed Jan 9 19:28:25 2008 >> @@ -44,12 +44,15 @@ >> /* make_decl_llvm - This is also defined in tree.h and used by >> macros there. */ >> void make_decl_llvm(union tree_node*); >> >> +/* reset_initializer_llvm - Change the initializer for a global >> variable. */ >> +void reset_initializer_llvm(union tree_node*); >> + >> /* emit_global_to_llvm - Emit the specified VAR_DECL to LLVM as a >> global >> * variable. >> */ >> void emit_global_to_llvm(union tree_node*); >> >> -/* emit_global_to_llvm - Emit the specified alias to LLVM >> +/* emit_alias_to_llvm - Emit the specified alias to LLVM >> */ >> void emit_alias_to_llvm(union tree_node*, union tree_node*, union >> tree_node*); >> >> >> Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=45804&r1=45803&r2=45804&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> === >> =================================================================== >> --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) >> +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Wed Jan 9 19:28:25 2008 >> @@ -76,6 +76,9 @@ >> #include "langhooks-def.h" >> /* APPLE LOCAL optimization pragmas 3124235/3420242 */ >> #include "opts.h" >> +#ifdef ENABLE_LLVM >> +#include "llvm.h" /* for reset_initializer_llvm */ >> +#endif >> >> #define OBJC_VOID_AT_END void_list_node >> >> @@ -5541,6 +5544,13 @@ >> { >> decl = TREE_PURPOSE (chain); >> finish_var_decl (decl, expr); >> + /* APPLE LOCAL LLVM begin - radar 5676233 */ >> +#ifdef ENABLE_LLVM >> + /* Reset the initializer for this reference as it most >> likely >> + changed. */ >> + reset_initializer_llvm(decl); >> +#endif >> + /* APPLE LOCAL LLVM end - radar 5676233 */ >> } >> else >> { >> @@ -18172,8 +18182,16 @@ >> for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) >> { >> handle_class_ref (chain); >> - if (TREE_PURPOSE (chain)) >> + /* APPLE LOCAL LLVM begin - radar 5676233 */ >> + if (TREE_PURPOSE (chain)) { >> generate_classref_translation_entry (chain); >> +#ifdef ENABLE_LLVM >> + /* Reset the initializer for this reference as it most >> likely >> + changed. */ >> + reset_initializer_llvm(TREE_PURPOSE (chain)); >> +#endif >> + } >> + /* APPLE LOCAL LLVM end - radar 5676233 */ >> } >> >> for (impent = imp_list; impent; impent = impent->next) >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Thu Jan 10 01:01:55 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 07:01:55 -0000 Subject: [llvm-commits] [llvm] r45827 - /llvm/trunk/utils/TableGen/TGParser.cpp Message-ID: <200801100701.m0A71trl032330@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 10 01:01:53 2008 New Revision: 45827 URL: http://llvm.org/viewvc/llvm-project?rev=45827&view=rev Log: Fix a crash on code like: let x = 1 {x Modified: llvm/trunk/utils/TableGen/TGParser.cpp Modified: llvm/trunk/utils/TableGen/TGParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=45827&r1=45826&r2=45827&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.cpp (original) +++ llvm/trunk/utils/TableGen/TGParser.cpp Thu Jan 10 01:01:53 2008 @@ -290,7 +290,10 @@ /// RangePiece ::= INTVAL '-' INTVAL /// RangePiece ::= INTVAL INTVAL bool TGParser::ParseRangePiece(std::vector &Ranges) { - assert(Lex.getCode() == tgtok::IntVal && "Invalid range"); + if (Lex.getCode() != tgtok::IntVal) { + TokError("expected integer or bitrange"); + return true; + } int Start = Lex.getCurIntVal(); int End; From evan.cheng at apple.com Thu Jan 10 01:19:43 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 07:19:43 -0000 Subject: [llvm-commits] [llvm] r45828 - /llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Message-ID: <200801100719.m0A7JiqX000738@zion.cs.uiuc.edu> Author: evancheng Date: Thu Jan 10 01:19:43 2008 New Revision: 45828 URL: http://llvm.org/viewvc/llvm-project?rev=45828&view=rev Log: Clearify the meaning of immutable StackObject. Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=45828&r1=45827&r2=45828&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Thu Jan 10 01:19:43 2008 @@ -86,9 +86,9 @@ // the function. This field has no meaning for a variable sized element. int64_t SPOffset; - // isImmutable - If true, the value of the stack object does not change - // in this function. By default, fixed objects are immutable unless marked - // otherwise. + // isImmutable - If true, the value of the stack object is set before + // entering the function and is not modified inside the function. By + // default, fixed objects are immutable unless marked otherwise. bool isImmutable; StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM = false) From evan.cheng at apple.com Thu Jan 10 01:41:02 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 9 Jan 2008 23:41:02 -0800 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> Message-ID: <541B5B00-A86B-4E55-B9A3-1849C7A8FEDD@apple.com> On Jan 9, 2008, at 8:44 PM, Owen Anderson wrote: > You really need to address these to Evan. I asked him what to do > for LiveIntervalAnalysis, and this is what he told me :-) > > --Owen > > On Jan 9, 2008, at 10:08 PM, Chris Lattner wrote: > >>> URL: http://llvm.org/viewvc/llvm-project?rev=45815&view=rev >>> Log: >>> Don't use LiveVariables::VarInfo::DefInst. >> >> Cool, question though: >> >>> +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Jan 9 >>> 21:12:54 2008 >>> @@ -309,7 +309,14 @@ >>> // are actually two values in the live interval. Because of >>> this we >>> // need to take the LiveRegion that defines this register and >>> split it >>> // into two values. >>> - unsigned DefIndex = >>> getDefIndex(getInstructionIndex(vi.DefInst)); >> >> In the old code, when it introduces multiple definitions of a vreg, >> did it clear DefInst? If so, this code can only be triggered for >> vregs with a single def. It does change DefInst. This code is triggered when a two-address instruction redefines a vreg so it can only be triggered for vregs with multiple def's. >> >>> >>> + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); >> >> I think that MRI should become and ivar in liveintervalanalysis. Yes, there is an ivar mri_. >> >>> >>> + unsigned lowIndex = ~0U; >>> + for (MachineRegisterInfo::def_iterator DI = >>> MRI.def_begin(interval.reg), >>> + DE = MRI.def_end(); DI != DE; ++DI) >>> + if (getInstructionIndex(&*DI) < lowIndex) >>> + lowIndex = getInstructionIndex(&*DI); >>> + >>> + unsigned DefIndex = getDefIndex(lowIndex); >> >> It would be really nice if you could drop the loop. It's unclear why >> it's right anyway, the numbering is not necessarily contiguous across >> code... Yes, I think it' can probably be simplified. But it's probably correct. This is before coalescing: v1024 = v1025 v1024 = v1024 op ? So there must be two def's of v1024 in the same BB and we want the first one. Evan >> >> -Chris >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Thu Jan 10 01:59:24 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 07:59:24 -0000 Subject: [llvm-commits] [llvm] r45829 - in /llvm/trunk: lib/Target/Target.td lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrFPStack.td lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86InstrMMX.td lib/Target/X86/X86InstrSSE.td utils/TableGen/CodeGenInstruction.cpp utils/TableGen/CodeGenInstruction.h utils/TableGen/CodeGenTarget.cpp utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200801100759.m0A7xPD3002223@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 10 01:59:24 2008 New Revision: 45829 URL: http://llvm.org/viewvc/llvm-project?rev=45829&view=rev Log: Start inferring side effect information more aggressively, and fix many bugs in the x86 backend where instructions were not marked maystore/mayload, and perf issues where instructions were not marked neverHasSideEffects. It would be really nice if we could write patterns for copy instructions. I have audited all the x86 instructions down to MOVDQAmr. The flags on others and on other targets are probably not right in all cases, but no clients currently use this info that are enabled by default. Modified: llvm/trunk/lib/Target/Target.td llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrMMX.td llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/utils/TableGen/CodeGenInstruction.cpp llvm/trunk/utils/TableGen/CodeGenInstruction.h llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/lib/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.td?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/lib/Target/Target.td (original) +++ llvm/trunk/lib/Target/Target.td Thu Jan 10 01:59:24 2008 @@ -204,19 +204,20 @@ bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? - // Side effect flags - If neither of these flags is set, then the instruction - // *always* has side effects. When set, the flags have these meanings: + // Side effect flags - When set, the flags have these meanings: // - // neverHasSideEffects - The instruction has no side effects that are not - // captured by any operands of the instruction or other flags, and when - // *all* instances of the instruction of that opcode have no side effects. + // hasSideEffects - The instruction has side effects that are not + // captured by any operands of the instruction or other flags. // mayHaveSideEffects - Some instances of the instruction can have side // effects. The virtual method "isReallySideEffectFree" is called to // determine this. Load instructions are an example of where this is // useful. In general, loads always have side effects. However, loads from // constant pools don't. Individual back ends make this determination. - bit neverHasSideEffects = 0; + // neverHasSideEffects - Set on an instruction with no pattern if it has no + // side effects. + bit hasSideEffects = 0; bit mayHaveSideEffects = 0; + bit neverHasSideEffects = 0; InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. @@ -343,12 +344,14 @@ let InOperandList = (ops variable_ops); let AsmString = ""; let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; } def INSERT_SUBREG : Instruction { let OutOperandList = (ops variable_ops); let InOperandList = (ops variable_ops); let AsmString = ""; let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Thu Jan 10 01:59:24 2008 @@ -131,19 +131,21 @@ //===----------------------------------------------------------------------===// // Miscellaneous Instructions... // -let Defs = [RBP,RSP], Uses = [RBP,RSP] in +let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>; -let Defs = [RSP], Uses = [RSP] in { +let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in { +let mayLoad = 1 in def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>; +let mayStore = 1 in def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>; } -let Defs = [RSP, EFLAGS], Uses = [RSP] in +let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W; -let Defs = [RSP], Uses = [RSP, EFLAGS] in +let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>; def LEA64_32r : I<0x8D, MRMSrcMem, @@ -160,12 +162,16 @@ "bswap{q}\t$dst", [(set GR64:$dst, (bswap GR64:$src))]>, TB; // Exchange +let neverHasSideEffects = 1 in { def XCHG64rr : RI<0x87, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; +let mayLoad = 1, mayStore = 1 in { def XCHG64mr : RI<0x87, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; def XCHG64rm : RI<0x87, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; +} +} // Bit scan instructions. let Defs = [EFLAGS] in { @@ -198,6 +204,7 @@ // Move Instructions... // +let neverHasSideEffects = 1 in def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), "mov{q}\t{$src, $dst|$dst, $src}", []>; @@ -256,13 +263,15 @@ "movz{wq|x}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB; -let Defs = [RAX], Uses = [EAX] in -def CDQE : RI<0x98, RawFrm, (outs), (ins), - "{cltq|cdqe}", []>; // RAX = signext(EAX) - -let Defs = [RAX,RDX], Uses = [RAX] in -def CQO : RI<0x99, RawFrm, (outs), (ins), - "{cqto|cqo}", []>; // RDX:RAX = signext(RAX) +let neverHasSideEffects = 1 in { + let Defs = [RAX], Uses = [EAX] in + def CDQE : RI<0x98, RawFrm, (outs), (ins), + "{cltq|cdqe}", []>; // RAX = signext(EAX) + + let Defs = [RAX,RDX], Uses = [RAX] in + def CQO : RI<0x99, RawFrm, (outs), (ins), + "{cqto|cqo}", []>; // RDX:RAX = signext(RAX) +} //===----------------------------------------------------------------------===// // Arithmetic Instructions... @@ -387,15 +396,17 @@ } // Defs = [EFLAGS] // Unsigned multiplication -let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in { +let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in { def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src), "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64 +let mayLoad = 1 in def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src), "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64] // Signed multiplication def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64 +let mayLoad = 1 in def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src), "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64] } @@ -432,18 +443,21 @@ } // Defs = [EFLAGS] // Unsigned division / remainder +let neverHasSideEffects = 1 in { let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in { def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX "div{q}\t$src", []>; -def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX - "div{q}\t$src", []>; - // Signed division / remainder def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX "idiv{q}\t$src", []>; +let mayLoad = 1 in { +def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX + "div{q}\t$src", []>; def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX "idiv{q}\t$src", []>; } +} +} // Unary instructions let Defs = [EFLAGS], CodeSize = 2 in { @@ -1035,11 +1049,12 @@ def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src), "cvtsi2ss{q}\t{$src, $dst|$dst, $src}", [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>; -let isTwoAddress = 1 in { +let isTwoAddress = 1, neverHasSideEffects = 1 in { def Int_CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", []>; // TODO: add intrinsic +let mayLoad = 1 in def Int_CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Thu Jan 10 01:59:24 2008 @@ -32,25 +32,25 @@ def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet, - [SDNPHasChain, SDNPOutFlag]>; -def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, - [SDNPHasChain, SDNPMayLoad]>; -def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, - [SDNPHasChain, SDNPInFlag, SDNPMayStore]>; -def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, - [SDNPHasChain, SDNPMayLoad]>; -def X86fildflag : SDNode<"X86ISD::FILD_FLAG",SDTX86Fild, - [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>; + [SDNPHasChain, SDNPOutFlag]>; +def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, + [SDNPHasChain, SDNPMayLoad]>; +def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, + [SDNPHasChain, SDNPInFlag, SDNPMayStore]>; +def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, + [SDNPHasChain, SDNPMayLoad]>; +def X86fildflag : SDNode<"X86ISD::FILD_FLAG", SDTX86Fild, + [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>; def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem, - [SDNPHasChain]>; + [SDNPHasChain, SDNPMayStore]>; def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem, - [SDNPHasChain]>; + [SDNPHasChain, SDNPMayStore]>; def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem, - [SDNPHasChain]>; + [SDNPHasChain, SDNPMayStore]>; def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m", SDTX86CwdStore, - [SDNPHasChain]>; + [SDNPHasChain, SDNPMayStore, SDNPSideEffect]>; //===----------------------------------------------------------------------===// // FPStack pattern fragments @@ -208,9 +208,9 @@ [(set RFP80:$dst, (OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>; def _F32m : FPI<0xD8, fp, (outs), (ins f32mem:$src), - !strconcat("f", !strconcat(asmstring, "{s}\t$src"))>; + !strconcat("f", !strconcat(asmstring, "{s}\t$src"))> { let mayLoad = 1; } def _F64m : FPI<0xDC, fp, (outs), (ins f64mem:$src), - !strconcat("f", !strconcat(asmstring, "{l}\t$src"))>; + !strconcat("f", !strconcat(asmstring, "{l}\t$src"))> { let mayLoad = 1; } // ST(0) = ST(0) + [memint] def _FpI16m32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, i16mem:$src2), OneArgFPRW, [(set RFP32:$dst, (OpNode RFP32:$src1, @@ -231,9 +231,9 @@ [(set RFP80:$dst, (OpNode RFP80:$src1, (X86fild addr:$src2, i32)))]>; def _FI16m : FPI<0xDE, fp, (outs), (ins i16mem:$src), - !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))>; + !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))> { let mayLoad = 1; } def _FI32m : FPI<0xDA, fp, (outs), (ins i32mem:$src), - !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))>; + !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))> { let mayLoad = 1; } } defm ADD : FPBinary_rr; @@ -392,13 +392,16 @@ [(truncstoref64 RFP80:$src, addr:$op)]>; // FST does not support 80-bit memory target; FSTP must be used. +let mayStore = 1 in { def ST_FpP32m : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, []>; def ST_FpP64m32 : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>; def ST_FpP64m : FpIf64<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>; def ST_FpP80m32 : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>; def ST_FpP80m64 : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>; +} def ST_FpP80m : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP, [(store RFP80:$src, addr:$op)]>; +let mayStore = 1 in { def IST_Fp16m32 : FpIf32<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>; def IST_Fp32m32 : FpIf32<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>; def IST_Fp64m32 : FpIf32<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>; @@ -408,13 +411,17 @@ def IST_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>; def IST_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>; def IST_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>; +} +let mayLoad = 1 in { def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">; def LD_F64m : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src">; def LD_F80m : FPI<0xDB, MRM5m, (outs), (ins f80mem:$src), "fld{t}\t$src">; def ILD_F16m : FPI<0xDF, MRM0m, (outs), (ins i16mem:$src), "fild{s}\t$src">; def ILD_F32m : FPI<0xDB, MRM0m, (outs), (ins i32mem:$src), "fild{l}\t$src">; def ILD_F64m : FPI<0xDF, MRM5m, (outs), (ins i64mem:$src), "fild{ll}\t$src">; +} +let mayStore = 1 in { def ST_F32m : FPI<0xD9, MRM2m, (outs), (ins f32mem:$dst), "fst{s}\t$dst">; def ST_F64m : FPI<0xDD, MRM2m, (outs), (ins f64mem:$dst), "fst{l}\t$dst">; def ST_FP32m : FPI<0xD9, MRM3m, (outs), (ins f32mem:$dst), "fstp{s}\t$dst">; @@ -425,6 +432,7 @@ def IST_FP16m : FPI<0xDF, MRM3m, (outs), (ins i16mem:$dst), "fistp{s}\t$dst">; def IST_FP32m : FPI<0xDB, MRM3m, (outs), (ins i32mem:$dst), "fistp{l}\t$dst">; def IST_FP64m : FPI<0xDF, MRM7m, (outs), (ins i64mem:$dst), "fistp{ll}\t$dst">; +} // FISTTP requires SSE3 even though it's a FPStack op. def ISTT_Fp16m32 : FpI_<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, @@ -455,9 +463,11 @@ [(X86fp_to_i64mem RFP80:$src, addr:$op)]>, Requires<[HasSSE3]>; +let mayStore = 1 in { def ISTT_FP16m : FPI<0xDF, MRM1m, (outs), (ins i16mem:$dst), "fisttp{s}\t$dst">; def ISTT_FP32m : FPI<0xDB, MRM1m, (outs), (ins i32mem:$dst), "fisttp{l}\t$dst">; def ISTT_FP64m : FPI<0xDD, MRM1m, (outs), (ins i64mem:$dst), "fisttp{ll}\t$dst">; +} // FP Stack manipulation instructions. def LD_Frr : FPI<0xC0, AddRegFrm, (outs), (ins RST:$op), "fld\t$op">, D9; @@ -531,6 +541,8 @@ def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world (outs), (ins i16mem:$dst), "fnstcw\t$dst", [(X86fp_cwd_get16 addr:$dst)]>; + +let mayLoad = 1 in def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] (outs), (ins i16mem:$dst), "fldcw\t$dst", []>; Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Jan 10 01:59:24 2008 @@ -92,7 +92,7 @@ SDNPMayLoad]>; def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>; def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>; @@ -266,6 +266,7 @@ def IMPLICIT_USE : I<0, Pseudo, (outs), (ins variable_ops), "#IMPLICIT_USE", []>; let isImplicitDef = 1 in { +let neverHasSideEffects = 1 in def IMPLICIT_DEF : I<0, Pseudo, (outs variable_ops), (ins), "#IMPLICIT_DEF", []>; def IMPLICIT_DEF_GR8 : I<0, Pseudo, (outs GR8:$dst), (ins), @@ -280,13 +281,13 @@ } // Nop -def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>; +let neverHasSideEffects = 1 in + def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>; // PIC base -let neverHasSideEffects = 1, isNotDuplicable = 1 in { -def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label), - "call\t$label\n\tpop{l}\t$reg", []>; -} +let neverHasSideEffects = 1, isNotDuplicable = 1 in + def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label), + "call\t$label\n\tpop{l}\t$reg", []>; //===----------------------------------------------------------------------===// // Control Flow Instructions... @@ -399,19 +400,21 @@ //===----------------------------------------------------------------------===// // Miscellaneous Instructions... // -let Defs = [EBP, ESP], Uses = [EBP, ESP] in +let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, neverHasSideEffects=1 in def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>; -let Defs = [ESP], Uses = [ESP] in { +let Defs = [ESP], Uses = [ESP], neverHasSideEffects=1 in { +let mayLoad = 1 in def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>; +let mayStore = 1 in def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>; } -let Defs = [ESP, EFLAGS], Uses = [ESP] in +let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, neverHasSideEffects=1 in def POPFD : I<0x9D, RawFrm, (outs), (ins), "popf", []>; -let Defs = [ESP], Uses = [ESP, EFLAGS] in +let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, neverHasSideEffects=1 in def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushf", []>; let isTwoAddress = 1 in // GR32 = bswap GR32 @@ -483,6 +486,7 @@ (implicit EFLAGS)]>, TB; } // Defs = [EFLAGS] +let neverHasSideEffects = 1 in def LEA16r : I<0x8D, MRMSrcMem, (outs GR16:$dst), (ins i32mem:$src), "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize; @@ -560,12 +564,14 @@ //===----------------------------------------------------------------------===// // Move Instructions... // +let neverHasSideEffects = 1 in { def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src), "mov{b}\t{$src, $dst|$dst, $src}", []>; def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; +} let isReMaterializable = 1 in { def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src), "mov{b}\t{$src, $dst|$dst, $src}", @@ -633,13 +639,16 @@ // This probably ought to be moved to a def : Pat<> if the // syntax can be accepted. [(set AL, (mul AL, (loadi8 addr:$src)))]>; // AL,AH = AL*[mem8] +let mayLoad = 1, neverHasSideEffects = 1 in { let Defs = [AX,DX,EFLAGS], Uses = [AX] in def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src), "mul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16] let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src), "mul{l}\t$src", []>; // EAX,EDX = EAX*[mem32] +} +let neverHasSideEffects = 1 in { let Defs = [AL,AH,EFLAGS], Uses = [AL] in def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>; // AL,AH = AL*GR8 @@ -649,6 +658,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>; // EAX,EDX = EAX*GR32 +let mayLoad = 1 in { let Defs = [AL,AH,EFLAGS], Uses = [AL] in def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src), "imul{b}\t$src", []>; // AL,AH = AL*[mem8] @@ -658,6 +668,7 @@ let Defs = [EAX,EDX], Uses = [EAX] in def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src), "imul{l}\t$src", []>; // EAX,EDX = EAX*[mem32] +} // unsigned division/remainder let Defs = [AX,EFLAGS], Uses = [AL,AH] in @@ -669,6 +680,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX "div{l}\t$src", []>; +let mayLoad = 1 in { let Defs = [AX,EFLAGS], Uses = [AL,AH] in def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH "div{b}\t$src", []>; @@ -678,6 +690,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX "div{l}\t$src", []>; +} // Signed division/remainder. let Defs = [AX,EFLAGS], Uses = [AL,AH] in @@ -689,6 +702,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX "idiv{l}\t$src", []>; +let mayLoad = 1, mayLoad = 1 in { let Defs = [AX,EFLAGS], Uses = [AL,AH] in def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH "idiv{b}\t$src", []>; @@ -698,10 +712,11 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX "idiv{l}\t$src", []>; - +} +} // neverHasSideEffects //===----------------------------------------------------------------------===// -// Two address Instructions... +// Two address Instructions. // let isTwoAddress = 1 in { @@ -2161,9 +2176,9 @@ // Condition code ops, incl. set if equal/not equal/... -let Defs = [EFLAGS], Uses = [AH] in +let Defs = [EFLAGS], Uses = [AH], neverHasSideEffects = 1 in def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>; // flags = AH -let Defs = [AH], Uses = [EFLAGS] in +let Defs = [AH], Uses = [EFLAGS], neverHasSideEffects = 1 in def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>; // AH = flags let Uses = [EFLAGS] in { @@ -2445,20 +2460,21 @@ "movz{wl|x}\t{$src, $dst|$dst, $src}", [(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB; -let Defs = [AX], Uses = [AL] in -def CBW : I<0x98, RawFrm, (outs), (ins), - "{cbtw|cbw}", []>, OpSize; // AX = signext(AL) -let Defs = [EAX], Uses = [AX] in -def CWDE : I<0x98, RawFrm, (outs), (ins), - "{cwtl|cwde}", []>; // EAX = signext(AX) - -let Defs = [AX,DX], Uses = [AX] in -def CWD : I<0x99, RawFrm, (outs), (ins), - "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX) -let Defs = [EAX,EDX], Uses = [EAX] in -def CDQ : I<0x99, RawFrm, (outs), (ins), - "{cltd|cdq}", []>; // EDX:EAX = signext(EAX) - +let neverHasSideEffects = 1 in { + let Defs = [AX], Uses = [AL] in + def CBW : I<0x98, RawFrm, (outs), (ins), + "{cbtw|cbw}", []>, OpSize; // AX = signext(AL) + let Defs = [EAX], Uses = [AX] in + def CWDE : I<0x98, RawFrm, (outs), (ins), + "{cwtl|cwde}", []>; // EAX = signext(AX) + + let Defs = [AX,DX], Uses = [AX] in + def CWD : I<0x99, RawFrm, (outs), (ins), + "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX) + let Defs = [EAX,EDX], Uses = [EAX] in + def CDQ : I<0x99, RawFrm, (outs), (ins), + "{cltd|cdq}", []>; // EDX:EAX = signext(EAX) +} //===----------------------------------------------------------------------===// // Alias Instructions @@ -2480,25 +2496,30 @@ // Basic operations on GR16 / GR32 subclasses GR16_ and GR32_ which contains only // those registers that have GR8 sub-registers (i.e. AX - DX, EAX - EDX). +let neverHasSideEffects = 1 in { def MOV16to16_ : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32to32_ : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; - + def MOV16_rr : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16_:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32_rr : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32_:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { +} // neverHasSideEffects + +let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { def MOV16_rm : I<0x8B, MRMSrcMem, (outs GR16_:$dst), (ins i16mem:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32_rm : I<0x8B, MRMSrcMem, (outs GR32_:$dst), (ins i32mem:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; } +let mayStore = 1, neverHasSideEffects = 1 in { def MOV16_mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16_:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; +} //===----------------------------------------------------------------------===// // Thread Local Storage Instructions Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Thu Jan 10 01:59:24 2008 @@ -156,17 +156,21 @@ //===----------------------------------------------------------------------===// // Data Transfer Instructions +let neverHasSideEffects = 1 in def MMX_MOVD64rr : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR32:$src), "movd\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in def MMX_MOVD64rm : MMXI<0x6E, MRMSrcMem, (outs VR64:$dst), (ins i32mem:$src), "movd\t{$src, $dst|$dst, $src}", []>; +let mayStore = 1 in def MMX_MOVD64mr : MMXI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR64:$src), "movd\t{$src, $dst|$dst, $src}", []>; +let neverHasSideEffects = 1 in def MMX_MOVD64to64rr : MMXRI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src), "movd\t{$src, $dst|$dst, $src}", []>; +let neverHasSideEffects = 1 in def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src), "movq\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in @@ -417,35 +421,44 @@ MMX_PSHUFW_shuffle_mask:$src2)))]>; // -- Conversion Instructions +let neverHasSideEffects = 1 in { def MMX_CVTPD2PIrr : MMX2I<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src), "cvtpd2pi\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def MMX_CVTPD2PIrm : MMX2I<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src), "cvtpd2pi\t{$src, $dst|$dst, $src}", []>; def MMX_CVTPI2PDrr : MMX2I<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src), "cvtpi2pd\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def MMX_CVTPI2PDrm : MMX2I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src), "cvtpi2pd\t{$src, $dst|$dst, $src}", []>; def MMX_CVTPI2PSrr : MMXI<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src), "cvtpi2ps\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def MMX_CVTPI2PSrm : MMXI<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src), "cvtpi2ps\t{$src, $dst|$dst, $src}", []>; def MMX_CVTPS2PIrr : MMXI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src), "cvtps2pi\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def MMX_CVTPS2PIrm : MMXI<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src), "cvtps2pi\t{$src, $dst|$dst, $src}", []>; def MMX_CVTTPD2PIrr : MMX2I<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src), "cvttpd2pi\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def MMX_CVTTPD2PIrm : MMX2I<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src), "cvttpd2pi\t{$src, $dst|$dst, $src}", []>; def MMX_CVTTPS2PIrr : MMXI<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src), "cvttps2pi\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def MMX_CVTTPS2PIrm : MMXI<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src), "cvttps2pi\t{$src, $dst|$dst, $src}", []>; +} // end neverHasSideEffects + // Extract / Insert def MMX_X86pextrw : SDNode<"X86ISD::PEXTRW", SDTypeProfile<1, 2, []>, []>; Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Thu Jan 10 01:59:24 2008 @@ -42,7 +42,7 @@ // SSE 'Special' Instructions //===----------------------------------------------------------------------===// -let isImplicitDef = 1 in +let isImplicitDef = 1 in { def IMPLICIT_DEF_VR128 : I<0, Pseudo, (outs VR128:$dst), (ins), "#IMPLICIT_DEF $dst", [(set VR128:$dst, (v4f32 (undef)))]>, @@ -53,6 +53,7 @@ def IMPLICIT_DEF_FR64 : I<0, Pseudo, (outs FR64:$dst), (ins), "#IMPLICIT_DEF $dst", [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>; +} //===----------------------------------------------------------------------===// // SSE Complex Patterns @@ -62,9 +63,9 @@ // the top elements. These are used for the SSE 'ss' and 'sd' instruction // forms. def sse_load_f32 : ComplexPattern; + [SDNPHasChain, SDNPMayLoad]>; def sse_load_f64 : ComplexPattern; + [SDNPHasChain, SDNPMayLoad]>; def ssmem : Operand { let PrintMethod = "printf32mem"; @@ -452,6 +453,7 @@ // Alias instruction to do FR32 reg-to-reg copy using movaps. Upper bits are // disregarded. +let neverHasSideEffects = 1 in def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src), "movaps\t{$src, $dst|$dst, $src}", []>; @@ -488,14 +490,17 @@ "xorps\t{$src2, $dst|$dst, $src2}", [(set FR32:$dst, (X86fxor FR32:$src1, (memopfsf32 addr:$src2)))]>; - +let neverHasSideEffects = 1 in { def FsANDNPSrr : PSI<0x55, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2), "andnps\t{$src2, $dst|$dst, $src2}", []>; + +let mayLoad = 1 in def FsANDNPSrm : PSI<0x55, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1, f128mem:$src2), "andnps\t{$src2, $dst|$dst, $src2}", []>; } +} /// basic_sse1_fp_binop_rm - SSE1 binops come in both scalar and vector forms. /// @@ -632,6 +637,7 @@ // SSE packed FP Instructions // Move Instructions +let neverHasSideEffects = 1 in def MOVAPSrr : PSI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movaps\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in @@ -1148,6 +1154,7 @@ // Alias instruction to do FR64 reg-to-reg copy using movapd. Upper bits are // disregarded. +let neverHasSideEffects = 1 in def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src), "movapd\t{$src, $dst|$dst, $src}", []>; @@ -1185,13 +1192,16 @@ [(set FR64:$dst, (X86fxor FR64:$src1, (memopfsf64 addr:$src2)))]>; +let neverHasSideEffects = 1 in { def FsANDNPDrr : PDI<0x55, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2), "andnpd\t{$src2, $dst|$dst, $src2}", []>; +let mayLoad = 1 in def FsANDNPDrm : PDI<0x55, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1, f128mem:$src2), "andnpd\t{$src2, $dst|$dst, $src2}", []>; } +} /// basic_sse2_fp_binop_rm - SSE2 binops come in both scalar and vector forms. /// @@ -1328,6 +1338,7 @@ // SSE packed FP Instructions // Move Instructions +let neverHasSideEffects = 1 in def MOVAPDrr : PDI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movapd\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in @@ -2117,7 +2128,6 @@ def MFENCE : I<0xAE, MRM6m, (outs), (ins), "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>; - // Alias instructions that map zero vector to pxor / xorp* for sse. let isReMaterializable = 1 in def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Thu Jan 10 01:59:24 2008 @@ -97,14 +97,14 @@ usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); hasCtrlDep = R->getValueAsBit("hasCtrlDep"); isNotDuplicable = R->getValueAsBit("isNotDuplicable"); + hasSideEffects = R->getValueAsBit("hasSideEffects"); mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); hasOptionalDef = false; isVariadic = false; - if (mayHaveSideEffects && neverHasSideEffects) - throw R->getName() + - ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!"; + if (mayHaveSideEffects + neverHasSideEffects + hasSideEffects > 1) + throw R->getName() + ": multiple conflicting side-effect flags set!"; DagInit *DI; try { Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Thu Jan 10 01:59:24 2008 @@ -103,8 +103,7 @@ bool hasCtrlDep; bool isNotDuplicable; bool hasOptionalDef; - bool mayHaveSideEffects; - bool neverHasSideEffects; + bool hasSideEffects, mayHaveSideEffects, neverHasSideEffects; /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", /// where $foo is a whole operand and $foo.bar refers to a suboperand. Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Thu Jan 10 01:59:24 2008 @@ -340,6 +340,12 @@ Properties |= 1 << SDNPHasChain; } else if (PropList[i]->getName() == "SDNPOptInFlag") { Properties |= 1 << SDNPOptInFlag; + } else if (PropList[i]->getName() == "SDNPMayStore") { + Properties |= 1 << SDNPMayStore; + } else if (PropList[i]->getName() == "SDNPMayLoad") { + Properties |= 1 << SDNPMayLoad; + } else if (PropList[i]->getName() == "SDNPSideEffect") { + Properties |= 1 << SDNPSideEffect; } else { cerr << "Unsupported SD Node property '" << PropList[i]->getName() << "' on ComplexPattern '" << R->getName() << "'!\n"; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45829&r1=45828&r2=45829&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Thu Jan 10 01:59:24 2008 @@ -152,22 +152,36 @@ : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){ } - void Analyze(Record *InstRecord) { + /// Analyze - Analyze the specified instruction, returning true if the + /// instruction had a pattern. + bool Analyze(Record *InstRecord) { const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern(); if (Pattern == 0) { HasSideEffects = 1; - return; // No pattern. + return false; // No pattern. } // FIXME: Assume only the first tree is the pattern. The others are clobber // nodes. AnalyzeNode(Pattern->getTree(0)); + return true; } private: void AnalyzeNode(const TreePatternNode *N) { - if (N->isLeaf()) + if (N->isLeaf()) { + if (DefInit *DI = dynamic_cast(N->getLeafValue())) { + Record *LeafRec = DI->getDef(); + // Handle ComplexPattern leaves. + if (LeafRec->isSubClassOf("ComplexPattern")) { + const ComplexPattern &CP = CDP.getComplexPattern(LeafRec); + if (CP.hasProperty(SDNPMayStore)) mayStore = true; + if (CP.hasProperty(SDNPMayLoad)) mayLoad = true; + if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true; + } + } return; + } // Analyze children. for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) @@ -180,17 +194,10 @@ // Get information about the SDNode for the operator. const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); - // If node writes to memory, it obviously stores to memory. - if (OpInfo.hasProperty(SDNPMayStore)) - mayStore = true; - - // If it reads memory, remember this. - if (OpInfo.hasProperty(SDNPMayLoad)) - mayLoad = true; - - // If it reads memory, remember this. - if (OpInfo.hasProperty(SDNPSideEffect)) - HasSideEffects = true; + // Notice properties of the node. + if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true; + if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true; + if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true; if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. @@ -213,7 +220,8 @@ bool &HasSideEffects) { MayStore = MayLoad = HasSideEffects = false; - InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef); + bool HadPattern = + InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef); // InstAnalyzer only correctly analyzes mayStore/mayLoad so far. if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it. @@ -239,15 +247,18 @@ } if (Inst.neverHasSideEffects) { - // If we already decided that this instruction has no side effects, then the - // .td file entry is redundant. - if (!HasSideEffects) - fprintf(stderr, - "Warning: neverHasSideEffects flag explicitly set on instruction" - " '%s' but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); + if (HadPattern) + fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' " + "which already has a pattern\n", Inst.TheDef->getName().c_str()); HasSideEffects = false; } + + if (Inst.hasSideEffects) { + if (HasSideEffects) + fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' " + "which already inferred this.\n", Inst.TheDef->getName().c_str()); + HasSideEffects = true; + } } From resistor at mac.com Thu Jan 10 02:12:38 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 10 Jan 2008 02:12:38 -0600 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: <541B5B00-A86B-4E55-B9A3-1849C7A8FEDD@apple.com> References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> <541B5B00-A86B-4E55-B9A3-1849C7A8FEDD@apple.com> Message-ID: On Jan 10, 2008, at 1:41 AM, Evan Cheng wrote: >>>> >>>> + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); >>> >>> I think that MRI should become and ivar in liveintervalanalysis. > > Yes, there is an ivar mri_. No, it doesn't. That's an MRegisterInfo, not a MachineRegisterInfo. No wonder you backend people are crazy... --Owen -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080110/0777a7cb/attachment.bin From evan.cheng at apple.com Thu Jan 10 02:22:10 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 08:22:10 -0000 Subject: [llvm-commits] [llvm] r45830 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200801100822.m0A8MAwX003193@zion.cs.uiuc.edu> Author: evancheng Date: Thu Jan 10 02:22:10 2008 New Revision: 45830 URL: http://llvm.org/viewvc/llvm-project?rev=45830&view=rev Log: Simplify some code. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=45830&r1=45829&r2=45830&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Jan 10 02:22:10 2008 @@ -309,14 +309,8 @@ // are actually two values in the live interval. Because of this we // need to take the LiveRegion that defines this register and split it // into two values. - MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); - unsigned lowIndex = ~0U; - for (MachineRegisterInfo::def_iterator DI = MRI.def_begin(interval.reg), - DE = MRI.def_end(); DI != DE; ++DI) - if (getInstructionIndex(&*DI) < lowIndex) - lowIndex = getInstructionIndex(&*DI); - - unsigned DefIndex = getDefIndex(lowIndex); + assert(interval.containsOneValue()); + unsigned DefIndex = getDefIndex(interval.getValNumInfo(0)->def); unsigned RedefIndex = getDefIndex(MIIdx); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1); From evan.cheng at apple.com Thu Jan 10 02:24:38 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 08:24:38 -0000 Subject: [llvm-commits] [llvm] r45831 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200801100824.m0A8Ocvn003339@zion.cs.uiuc.edu> Author: evancheng Date: Thu Jan 10 02:24:38 2008 New Revision: 45831 URL: http://llvm.org/viewvc/llvm-project?rev=45831&view=rev Log: Only remat loads from immutable stack slots. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=45831&r1=45830&r2=45831&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Jan 10 02:24:38 2008 @@ -624,7 +624,7 @@ int FrameIdx = 0; if (!tii_->isLoadFromStackSlot(MI, FrameIdx) || - !mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)) + !mf_->getFrameInfo()->isImmutableObjectIndex(FrameIdx)) return false; // This is a load from fixed stack slot. It can be rematerialized unless it's @@ -719,7 +719,7 @@ else LiveVariables::transferKillDeadInfo(MI, fmi, mri_); MachineBasicBlock &MBB = *MI->getParent(); - if (isSS && !mf_->getFrameInfo()->isFixedObjectIndex(Slot)) + if (isSS && !mf_->getFrameInfo()->isImmutableObjectIndex(Slot)) vrm.virtFolded(Reg, MI, fmi, (VirtRegMap::ModRef)MRInfo); vrm.transferSpillPts(MI, fmi); vrm.transferRestorePts(MI, fmi); From baldrick at free.fr Thu Jan 10 03:58:14 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 10 Jan 2008 09:58:14 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45832 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Message-ID: <200801100958.m0A9wJ4B016218@zion.cs.uiuc.edu> Author: baldrick Date: Thu Jan 10 03:58:07 2008 New Revision: 45832 URL: http://llvm.org/viewvc/llvm-project?rev=45832&view=rev Log: Fix the Ada build. Based on a patch by Dale Johannesen. Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=45832&r1=45831&r2=45832&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Jan 10 03:58:07 2008 @@ -1696,6 +1696,8 @@ TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE && TYPE_SIZE(TREE_TYPE(Field)) && DECL_SIZE(Field) && + TREE_CODE(DECL_SIZE(Field))==INTEGER_CST && + TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST && TREE_INT_CST_LOW(DECL_SIZE(Field)) < TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) TREE_TYPE(Field) = FixBaseClassField(Field); @@ -1739,7 +1741,9 @@ TREE_CODE(DECL_FIELD_OFFSET(Field))==INTEGER_CST && TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE && TYPE_SIZE(TREE_TYPE(Field)) && - DECL_SIZE(Field)) { + DECL_SIZE(Field) && + TREE_CODE(DECL_SIZE(Field))==INTEGER_CST && + TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST) { tree &oldTy = BaseTypesMap[TREE_TYPE(Field)]; if (oldTy) TREE_TYPE(Field) = oldTy; From baldrick at free.fr Thu Jan 10 04:28:34 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 10 Jan 2008 10:28:34 -0000 Subject: [llvm-commits] [llvm] r45833 - in /llvm/trunk: include/llvm/CodeGen/RuntimeLibcalls.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/PowerPC/PPCISelLowering.cpp test/CodeGen/X86/2008-01-09-LongDoubleSin.ll Message-ID: <200801101028.m0AASboK018109@zion.cs.uiuc.edu> Author: baldrick Date: Thu Jan 10 04:28:30 2008 New Revision: 45833 URL: http://llvm.org/viewvc/llvm-project?rev=45833&view=rev Log: Output sinl for a long double FSIN node, not sin. Likewise fix up a bunch of other libcalls. While there I remove NEG_F32 and NEG_F64 since they are not used anywhere. This fixes 9 Ada ACATS failures. Added: llvm/trunk/test/CodeGen/X86/2008-01-09-LongDoubleSin.ll Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h?rev=45833&r1=45832&r2=45833&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h (original) +++ llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h Thu Jan 10 04:28:30 2008 @@ -49,21 +49,24 @@ // FLOATING POINT ADD_F32, ADD_F64, + ADD_F80, ADD_PPCF128, SUB_F32, SUB_F64, + SUB_F80, SUB_PPCF128, MUL_F32, MUL_F64, + MUL_F80, MUL_PPCF128, DIV_F32, DIV_F64, + DIV_F80, DIV_PPCF128, REM_F32, REM_F64, + REM_F80, REM_PPCF128, - NEG_F32, - NEG_F64, POWI_F32, POWI_F64, POWI_F80, @@ -74,8 +77,12 @@ SQRT_PPCF128, SIN_F32, SIN_F64, + SIN_F80, + SIN_PPCF128, COS_F32, COS_F64, + COS_F80, + COS_PPCF128, POW_F32, POW_F64, POW_F80, Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=45833&r1=45832&r2=45833&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Jan 10 04:28:30 2008 @@ -737,6 +737,20 @@ return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size()); } +/// GetFPLibCall - Return the right libcall for the given floating point type. +static RTLIB::Libcall GetFPLibCall(MVT::ValueType VT, + RTLIB::Libcall Call_F32, + RTLIB::Libcall Call_F64, + RTLIB::Libcall Call_F80, + RTLIB::Libcall Call_PPCF128) { + return + VT == MVT::f32 ? Call_F32 : + VT == MVT::f64 ? Call_F64 : + VT == MVT::f80 ? Call_F80 : + VT == MVT::ppcf128 ? Call_PPCF128 : + RTLIB::UNKNOWN_LIBCALL; +} + /// LegalizeOp - We know that the specified value has a legal type, and /// that its operands are legal. Now ensure that the operation itself /// is legal, recursively ensuring that the operands' operations remain @@ -2774,11 +2788,8 @@ } break; case ISD::FPOW: - LC = VT == MVT::f32 ? RTLIB::POW_F32 : - VT == MVT::f64 ? RTLIB::POW_F64 : - VT == MVT::f80 ? RTLIB::POW_F80 : - VT == MVT::ppcf128 ? RTLIB::POW_PPCF128 : - RTLIB::UNKNOWN_LIBCALL; + LC = GetFPLibCall(VT, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80, + RTLIB::POW_PPCF128); break; default: break; } @@ -2996,8 +3007,8 @@ Result = LegalizeOp(UnrollVectorOp(Op)); } else { // Floating point mod -> fmod libcall. - RTLIB::Libcall LC = VT == MVT::f32 - ? RTLIB::REM_F32 : RTLIB::REM_F64; + RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::REM_F32, RTLIB::REM_F64, + RTLIB::REM_F80, RTLIB::REM_PPCF128); SDOperand Dummy; Result = ExpandLibCall(TLI.getLibcallName(LC), Node, false/*sign irrelevant*/, Dummy); @@ -3274,17 +3285,16 @@ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch(Node->getOpcode()) { case ISD::FSQRT: - LC = VT == MVT::f32 ? RTLIB::SQRT_F32 : - VT == MVT::f64 ? RTLIB::SQRT_F64 : - VT == MVT::f80 ? RTLIB::SQRT_F80 : - VT == MVT::ppcf128 ? RTLIB::SQRT_PPCF128 : - RTLIB::UNKNOWN_LIBCALL; + LC = GetFPLibCall(VT, RTLIB::SQRT_F32, RTLIB::SQRT_F64, + RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128); break; case ISD::FSIN: - LC = VT == MVT::f32 ? RTLIB::SIN_F32 : RTLIB::SIN_F64; + LC = GetFPLibCall(VT, RTLIB::SIN_F32, RTLIB::SIN_F64, + RTLIB::SIN_F80, RTLIB::SIN_PPCF128); break; case ISD::FCOS: - LC = VT == MVT::f32 ? RTLIB::COS_F32 : RTLIB::COS_F64; + LC = GetFPLibCall(VT, RTLIB::COS_F32, RTLIB::COS_F64, + RTLIB::COS_F80, RTLIB::COS_PPCF128); break; default: assert(0 && "Unreachable!"); } @@ -3307,12 +3317,8 @@ } // We always lower FPOWI into a libcall. No target support for it yet. - RTLIB::Libcall LC = - VT == MVT::f32 ? RTLIB::POWI_F32 : - VT == MVT::f64 ? RTLIB::POWI_F64 : - VT == MVT::f80 ? RTLIB::POWI_F80 : - VT == MVT::ppcf128 ? RTLIB::POWI_PPCF128 : - RTLIB::UNKNOWN_LIBCALL; + RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::POWI_F32, RTLIB::POWI_F64, + RTLIB::POWI_F80, RTLIB::POWI_PPCF128); SDOperand Dummy; Result = ExpandLibCall(TLI.getLibcallName(LC), Node, false/*sign irrelevant*/, Dummy); @@ -6067,35 +6073,31 @@ break; case ISD::FADD: - Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::ADD_F32 : - VT == MVT::f64 ? RTLIB::ADD_F64 : - VT == MVT::ppcf128 ? - RTLIB::ADD_PPCF128 : - RTLIB::UNKNOWN_LIBCALL), + Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::ADD_F32, + RTLIB::ADD_F64, + RTLIB::ADD_F80, + RTLIB::ADD_PPCF128)), Node, false, Hi); break; case ISD::FSUB: - Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::SUB_F32 : - VT == MVT::f64 ? RTLIB::SUB_F64 : - VT == MVT::ppcf128 ? - RTLIB::SUB_PPCF128 : - RTLIB::UNKNOWN_LIBCALL), + Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::SUB_F32, + RTLIB::SUB_F64, + RTLIB::SUB_F80, + RTLIB::SUB_PPCF128)), Node, false, Hi); break; case ISD::FMUL: - Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::MUL_F32 : - VT == MVT::f64 ? RTLIB::MUL_F64 : - VT == MVT::ppcf128 ? - RTLIB::MUL_PPCF128 : - RTLIB::UNKNOWN_LIBCALL), + Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::MUL_F32, + RTLIB::MUL_F64, + RTLIB::MUL_F80, + RTLIB::MUL_PPCF128)), Node, false, Hi); break; case ISD::FDIV: - Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::DIV_F32 : - VT == MVT::f64 ? RTLIB::DIV_F64 : - VT == MVT::ppcf128 ? - RTLIB::DIV_PPCF128 : - RTLIB::UNKNOWN_LIBCALL), + Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::DIV_F32, + RTLIB::DIV_F64, + RTLIB::DIV_F80, + RTLIB::DIV_PPCF128)), Node, false, Hi); break; case ISD::FP_EXTEND: @@ -6116,12 +6118,10 @@ Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPROUND_F64_F32),Node,true,Hi); break; case ISD::FPOWI: - Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32) ? RTLIB::POWI_F32 : - (VT == MVT::f64) ? RTLIB::POWI_F64 : - (VT == MVT::f80) ? RTLIB::POWI_F80 : - (VT == MVT::ppcf128) ? - RTLIB::POWI_PPCF128 : - RTLIB::UNKNOWN_LIBCALL), + Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::POWI_F32, + RTLIB::POWI_F64, + RTLIB::POWI_F80, + RTLIB::POWI_PPCF128)), Node, false, Hi); break; case ISD::FSQRT: @@ -6130,17 +6130,16 @@ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch(Node->getOpcode()) { case ISD::FSQRT: - LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 : - (VT == MVT::f64) ? RTLIB::SQRT_F64 : - (VT == MVT::f80) ? RTLIB::SQRT_F80 : - (VT == MVT::ppcf128) ? RTLIB::SQRT_PPCF128 : - RTLIB::UNKNOWN_LIBCALL; + LC = GetFPLibCall(VT, RTLIB::SQRT_F32, RTLIB::SQRT_F64, + RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128); break; case ISD::FSIN: - LC = (VT == MVT::f32) ? RTLIB::SIN_F32 : RTLIB::SIN_F64; + LC = GetFPLibCall(VT, RTLIB::SIN_F32, RTLIB::SIN_F64, + RTLIB::SIN_F80, RTLIB::SIN_PPCF128); break; case ISD::FCOS: - LC = (VT == MVT::f32) ? RTLIB::COS_F32 : RTLIB::COS_F64; + LC = GetFPLibCall(VT, RTLIB::COS_F32, RTLIB::COS_F64, + RTLIB::COS_F80, RTLIB::COS_PPCF128); break; default: assert(0 && "Unreachable!"); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=45833&r1=45832&r2=45833&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Jan 10 04:28:30 2008 @@ -48,21 +48,24 @@ Names[RTLIB::NEG_I64] = "__negdi2"; Names[RTLIB::ADD_F32] = "__addsf3"; Names[RTLIB::ADD_F64] = "__adddf3"; + Names[RTLIB::ADD_F80] = "__addxf3"; Names[RTLIB::ADD_PPCF128] = "__gcc_qadd"; Names[RTLIB::SUB_F32] = "__subsf3"; Names[RTLIB::SUB_F64] = "__subdf3"; + Names[RTLIB::SUB_F80] = "__subxf3"; Names[RTLIB::SUB_PPCF128] = "__gcc_qsub"; Names[RTLIB::MUL_F32] = "__mulsf3"; Names[RTLIB::MUL_F64] = "__muldf3"; + Names[RTLIB::MUL_F80] = "__mulxf3"; Names[RTLIB::MUL_PPCF128] = "__gcc_qmul"; Names[RTLIB::DIV_F32] = "__divsf3"; Names[RTLIB::DIV_F64] = "__divdf3"; + Names[RTLIB::DIV_F80] = "__divxf3"; Names[RTLIB::DIV_PPCF128] = "__gcc_qdiv"; Names[RTLIB::REM_F32] = "fmodf"; Names[RTLIB::REM_F64] = "fmod"; + Names[RTLIB::REM_F80] = "fmodl"; Names[RTLIB::REM_PPCF128] = "fmodl"; - Names[RTLIB::NEG_F32] = "__negsf2"; - Names[RTLIB::NEG_F64] = "__negdf2"; Names[RTLIB::POWI_F32] = "__powisf2"; Names[RTLIB::POWI_F64] = "__powidf2"; Names[RTLIB::POWI_F80] = "__powixf2"; @@ -73,8 +76,12 @@ Names[RTLIB::SQRT_PPCF128] = "sqrtl"; Names[RTLIB::SIN_F32] = "sinf"; Names[RTLIB::SIN_F64] = "sin"; + Names[RTLIB::SIN_F80] = "sinl"; + Names[RTLIB::SIN_PPCF128] = "sinl"; Names[RTLIB::COS_F32] = "cosf"; Names[RTLIB::COS_F64] = "cos"; + Names[RTLIB::COS_F80] = "cosl"; + Names[RTLIB::COS_PPCF128] = "cosl"; Names[RTLIB::POW_F32] = "powf"; Names[RTLIB::POW_F64] = "pow"; Names[RTLIB::POW_F80] = "powl"; Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=45833&r1=45832&r2=45833&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Thu Jan 10 04:28:30 2008 @@ -341,9 +341,11 @@ // Darwin long double math library functions have $LDBL128 appended. if (TM.getSubtarget().isDarwin()) { - setLibcallName(RTLIB::SQRT_PPCF128, "sqrtl$LDBL128"); + setLibcallName(RTLIB::COS_PPCF128, "cosl$LDBL128"); setLibcallName(RTLIB::POW_PPCF128, "powl$LDBL128"); setLibcallName(RTLIB::REM_PPCF128, "fmodl$LDBL128"); + setLibcallName(RTLIB::SIN_PPCF128, "sinl$LDBL128"); + setLibcallName(RTLIB::SQRT_PPCF128, "sqrtl$LDBL128"); } computeRegisterProperties(); Added: llvm/trunk/test/CodeGen/X86/2008-01-09-LongDoubleSin.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-01-09-LongDoubleSin.ll?rev=45833&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-01-09-LongDoubleSin.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-01-09-LongDoubleSin.ll Thu Jan 10 04:28:30 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -o - | grep sinl + +target triple = "i686-pc-linux-gnu" + +define x86_fp80 @f(x86_fp80 %x) nounwind { +entry: + %tmp2 = tail call x86_fp80 @sinl( x86_fp80 %x ) nounwind readonly ; [#uses=1] + ret x86_fp80 %tmp2 +} + +declare x86_fp80 @sinl(x86_fp80) nounwind readonly From jon at alacatialabs.com Thu Jan 10 08:49:06 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Thu, 10 Jan 2008 08:49:06 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/index.html Message-ID: <200801101449.m0AEn6QD031798@zion.cs.uiuc.edu> Changes in directory llvm-www/devmtg/current: index.html updated: 1.3 -> 1.4 --- Log message: Updated list of attendees for developer meeting. --- Diffs of the changes: (+10 -1) index.html | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm-www/devmtg/current/index.html diff -u llvm-www/devmtg/current/index.html:1.3 llvm-www/devmtg/current/index.html:1.4 --- llvm-www/devmtg/current/index.html:1.3 Wed Jan 9 12:37:54 2008 +++ llvm-www/devmtg/current/index.html Thu Jan 10 08:48:07 2008 @@ -37,14 +37,23 @@
    Unconfirmed Attendees
    NameOrganization
    Owen AndersonApple, Inc.
    Chandler Carruth
    Evan ChengApple, Inc.
    Robert HundtGoogle
    Dale JohannesenApple, Inc.
    Jonathan JohnsonAlacatia Labs, Inc.
    Ted Kremenek
    Chris LattnerApple, Inc.
    Steve NaroffApple, Inc.
    Ted Neward
    Devang PatelApple, Inc.
    Joseph RanieriAlacatia Labs, Inc.
    Chuck RoseAdobe Systems Incorporated
    Mike StumpApple, Inc.
    Bill WendlingApple, Inc.
    -

    Total unconfirmed: 7

    +

    Total unconfirmed: 15

    +

    If your name is mispelled, or organization affiliation isn't correct, please email us, and we'll correct it. \ No newline at end of file From sabre at nondot.org Thu Jan 10 12:25:41 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 18:25:41 -0000 Subject: [llvm-commits] [llvm] r45837 - /llvm/trunk/lib/Target/README.txt Message-ID: <200801101825.m0AIPfSQ015863@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 10 12:25:41 2008 New Revision: 45837 URL: http://llvm.org/viewvc/llvm-project?rev=45837&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=45837&r1=45836&r2=45837&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Jan 10 12:25:41 2008 @@ -545,3 +545,53 @@ instructions. //===---------------------------------------------------------------------===// + +DAG Combiner should try to combine small loads into larger loads when +profitable. For example, we compile this C++ example: + +struct THotKey { short Key; bool Control; bool Shift; bool Alt; }; +extern THotKey m_HotKey; +THotKey GetHotKey () { return m_HotKey; } + +into (-O3 -fno-exceptions -static -fomit-frame-pointer): + +__Z9GetHotKeyv: + pushl %esi + movl 8(%esp), %eax + movb _m_HotKey+3, %cl + movb _m_HotKey+4, %dl + movb _m_HotKey+2, %ch + movw _m_HotKey, %si + movw %si, (%eax) + movb %ch, 2(%eax) + movb %cl, 3(%eax) + movb %dl, 4(%eax) + popl %esi + ret $4 + +GCC produces: + +__Z9GetHotKeyv: + movl _m_HotKey, %edx + movl 4(%esp), %eax + movl %edx, (%eax) + movzwl _m_HotKey+4, %edx + movw %dx, 4(%eax) + ret $4 + +The LLVM IR contains the needed alignment info, so we should be able to +merge the loads and stores into 4-byte loads: + + %struct.THotKey = type { i16, i8, i8, i8 } +define void @_Z9GetHotKeyv(%struct.THotKey* sret %agg.result) nounwind { +... + %tmp2 = load i16* getelementptr (@m_HotKey, i32 0, i32 0), align 8 + %tmp5 = load i8* getelementptr (@m_HotKey, i32 0, i32 1), align 2 + %tmp8 = load i8* getelementptr (@m_HotKey, i32 0, i32 2), align 1 + %tmp11 = load i8* getelementptr (@m_HotKey, i32 0, i32 3), align 2 + +Alternatively, we should use a small amount of base-offset alias analysis +to make it so the scheduler doesn't need to hold all the loads in regs at +once. + +//===---------------------------------------------------------------------===// From clattner at apple.com Thu Jan 10 12:38:35 2008 From: clattner at apple.com (Chris Lattner) Date: Thu, 10 Jan 2008 10:38:35 -0800 Subject: [llvm-commits] [llvm] r45815 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp In-Reply-To: References: <200801100312.m0A3Cu5M018009@zion.cs.uiuc.edu> <77DC9F88-2B76-4DC6-BBA7-60C9FCFD29F9@mac.com> <541B5B00-A86B-4E55-B9A3-1849C7A8FEDD@apple.com> Message-ID: <524CD7E8-BB8B-4E36-ADE9-FCBBA94A9AEA@apple.com> On Jan 10, 2008, at 12:12 AM, Owen Anderson wrote: > > On Jan 10, 2008, at 1:41 AM, Evan Cheng wrote: >>>>> >>>>> + MachineRegisterInfo& MRI = mbb->getParent()->getRegInfo(); >>>> >>>> I think that MRI should become and ivar in liveintervalanalysis. >> >> Yes, there is an ivar mri_. > > No, it doesn't. That's an MRegisterInfo, not a > MachineRegisterInfo. No wonder you backend people are crazy... ... if only someone would rename MRegisterInfo -> TargetRegisterInfo the world would be a happier place :) -Chris From clattner at apple.com Thu Jan 10 12:40:19 2008 From: clattner at apple.com (Chris Lattner) Date: Thu, 10 Jan 2008 10:40:19 -0800 Subject: [llvm-commits] [llvm] r45833 - in /llvm/trunk: include/llvm/CodeGen/RuntimeLibcalls.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/PowerPC/PPCISelLowering.cpp test/CodeGen/X86/2008-01-09-LongDoubleSin.ll In-Reply-To: <200801101028.m0AASboK018109@zion.cs.uiuc.edu> References: <200801101028.m0AASboK018109@zion.cs.uiuc.edu> Message-ID: <15379BAD-1E0E-47B5-A1EC-8F94E5DE6947@apple.com> On Jan 10, 2008, at 2:28 AM, Duncan Sands wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=45833&view=rev > Log: > Output sinl for a long double FSIN node, not sin. > Likewise fix up a bunch of other libcalls. While > there I remove NEG_F32 and NEG_F64 since they are > not used anywhere. This fixes 9 Ada ACATS failures. > +/// GetFPLibCall - Return the right libcall for the given floating > point type. > +static RTLIB::Libcall GetFPLibCall(MVT::ValueType VT, > + RTLIB::Libcall Call_F32, > + RTLIB::Libcall Call_F64, > + RTLIB::Libcall Call_F80, > + RTLIB::Libcall Call_PPCF128) { Nice solution Duncan, -Chris From sabre at nondot.org Thu Jan 10 13:27:59 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 19:27:59 -0000 Subject: [llvm-commits] [llvm] r45838 - in /llvm/trunk/lib/Target/X86: X86CodeEmitter.cpp X86InstrInfo.td Message-ID: <200801101927.m0AJRxo3019983@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 10 13:27:54 2008 New Revision: 45838 URL: http://llvm.org/viewvc/llvm-project?rev=45838&view=rev Log: IMPLICIT_USE and IMPLICIT_DEF are dead, remove them. Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=45838&r1=45837&r2=45838&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Thu Jan 10 13:27:54 2008 @@ -603,8 +603,6 @@ assert(0 && "JIT does not support inline asm!\n"); case TargetInstrInfo::LABEL: assert(0 && "JIT does not support meta labels!\n"); - case X86::IMPLICIT_USE: - case X86::IMPLICIT_DEF: case X86::IMPLICIT_DEF_GR8: case X86::IMPLICIT_DEF_GR16: case X86::IMPLICIT_DEF_GR32: Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45838&r1=45837&r2=45838&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Jan 10 13:27:54 2008 @@ -263,12 +263,7 @@ "#ADJCALLSTACKUP", [(X86callseq_end imm:$amt1, imm:$amt2)]>; } -def IMPLICIT_USE : I<0, Pseudo, (outs), (ins variable_ops), - "#IMPLICIT_USE", []>; let isImplicitDef = 1 in { -let neverHasSideEffects = 1 in -def IMPLICIT_DEF : I<0, Pseudo, (outs variable_ops), (ins), - "#IMPLICIT_DEF", []>; def IMPLICIT_DEF_GR8 : I<0, Pseudo, (outs GR8:$dst), (ins), "#IMPLICIT_DEF $dst", [(set GR8:$dst, (undef))]>; From sabre at nondot.org Thu Jan 10 16:35:15 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 22:35:15 -0000 Subject: [llvm-commits] [llvm] r45841 - /llvm/trunk/lib/CodeGen/MachineSink.cpp Message-ID: <200801102235.m0AMZFSG032259@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 10 16:35:15 2008 New Revision: 45841 URL: http://llvm.org/viewvc/llvm-project?rev=45841&view=rev Log: Clamp down on sinking of lots of instructions. Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=45841&r1=45840&r2=45841&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSink.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSink.cpp Thu Jan 10 16:35:15 2008 @@ -130,6 +130,15 @@ /// SinkInstruction - Determine whether it is safe to sink the specified machine /// instruction out of its current block into a successor. bool MachineSinking::SinkInstruction(MachineInstr *MI) { + const TargetInstrDesc &TID = MI->getDesc(); + + // Ignore stuff that we obviously can't sink. + if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch()) + return false; + + if (TID.mayLoad()) + return false; + // Don't sink things with side-effects we don't understand. if (TII->hasUnmodelledSideEffects(MI)) return false; From sabre at nondot.org Thu Jan 10 17:08:24 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Jan 2008 23:08:24 -0000 Subject: [llvm-commits] [llvm] r45843 - in /llvm/trunk: include/llvm/Target/TargetInstrDesc.h include/llvm/Target/TargetInstrInfo.h lib/CodeGen/MachineLICM.cpp lib/CodeGen/MachineSink.cpp lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h utils/TableGen/InstrInfoEmitter.cpp Message-ID: <200801102308.m0AN8ObO001842@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 10 17:08:24 2008 New Revision: 45843 URL: http://llvm.org/viewvc/llvm-project?rev=45843&view=rev Log: Simplify the side effect stuff a bit more and make licm/sinking both work right according to the new flags. This removes the TII::isReallySideEffectFree predicate, and adds TII::isInvariantLoad. It removes NeverHasSideEffects+MayHaveSideEffects and adds UnmodeledSideEffects as machine instr flags. Now the clients can decide everything they need. I think isRematerializable can be implemented in terms of the flags we have now, though I will let others tackle that. Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/lib/CodeGen/MachineSink.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Thu Jan 10 17:08:24 2008 @@ -92,8 +92,7 @@ SimpleLoad, MayLoad, MayStore, - NeverHasSideEffects, - MayHaveSideEffects, + UnmodeledSideEffects, Commutable, ConvertibleTo3Addr, UsesCustomDAGSchedInserter, @@ -326,37 +325,21 @@ return Flags & (1 << TID::MayStore); } - /// hasNoSideEffects - Return true if all instances of this instruction are - /// guaranteed to have no side effects other than: - /// 1. The register operands that are def/used by the MachineInstr. - /// 2. Registers that are implicitly def/used by the MachineInstr. - /// 3. Memory Accesses captured by mayLoad() or mayStore(). - /// - /// Examples of other side effects would be calling a function, modifying - /// 'invisible' machine state like a control register, etc. - /// - /// If some instances of this instruction are side-effect free but others are - /// not, the hasConditionalSideEffects() property should return true, not this - /// one. - /// - /// Note that you should not call this method directly, instead, call the - /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis - /// of the machine instruction. - bool hasNoSideEffects() const { - return Flags & (1 << TID::NeverHasSideEffects); - } - - /// hasConditionalSideEffects - Return true if some instances of this - /// instruction are guaranteed to have no side effects other than those listed - /// for hasNoSideEffects(). To determine whether a specific machineinstr has - /// side effects, the TargetInstrInfo::isReallySideEffectFree virtual method - /// is invoked to decide. - /// - /// Note that you should not call this method directly, instead, call the - /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis - /// of the machine instruction. - bool hasConditionalSideEffects() const { - return Flags & (1 << TID::MayHaveSideEffects); + /// hasUnmodeledSideEffects - Return true if this instruction has side + /// effects that are not modeled by other flags. This does not return true + /// for instructions whose effects are captured by: + /// + /// 1. Their operand list and implicit definition/use list. Register use/def + /// info is explicit for instructions. + /// 2. Memory accesses. Use mayLoad/mayStore. + /// 3. Calling, branching, returning: use isCall/isReturn/isBranch. + /// + /// Examples of side effects would be modifying 'invisible' machine state like + /// a control register, flushing a cache, modifying a register invisible to + /// LLVM, etc. + /// + bool hasUnmodeledSideEffects() const { + return Flags & (1 << TID::UnmodeledSideEffects); } //===--------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Thu Jan 10 17:08:24 2008 @@ -69,15 +69,6 @@ isReallyTriviallyReMaterializable(MI); } - /// hasUnmodelledSideEffects - Returns true if the instruction has side - /// effects that are not captured by any operands of the instruction or other - /// flags. - bool hasUnmodelledSideEffects(MachineInstr *MI) const { - const TargetInstrDesc &TID = MI->getDesc(); - if (TID.hasNoSideEffects()) return false; - if (!TID.hasConditionalSideEffects()) return true; - return !isReallySideEffectFree(MI); // May have side effects - } protected: /// isReallyTriviallyReMaterializable - For instructions with opcodes for /// which the M_REMATERIALIZABLE flag is set, this function tests whether the @@ -91,15 +82,6 @@ return true; } - /// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this - /// method is called to determine if the specific instance of this - /// instruction has side effects. This is useful in cases of instructions, - /// like loads, which generally always have side effects. A load from a - /// constant pool doesn't have side effects, though. So we need to - /// differentiate it from the general case. - virtual bool isReallySideEffectFree(MachineInstr *MI) const { - return false; - } public: /// Return true if the instruction is a register to register move /// and leave the source and dest operands in the passed parameters. @@ -127,6 +109,17 @@ return 0; } + /// isInvariantLoad - Return true if the specified instruction (which is + /// marked mayLoad) is loading from a location whose value is invariant across + /// the function. For example, loading a value from the constant pool or from + /// from the argument area of a function if it does not change. This should + /// only return true of *all* loads the instruction does are invariant (if it + /// does multiple loads). + virtual bool isInvariantLoad(MachineInstr *MI) const { + return false; + } + + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target /// may be able to convert a two-address instruction into one or more true Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Thu Jan 10 17:08:24 2008 @@ -223,6 +223,26 @@ /// effects that aren't captured by the operands or other flags. /// bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { + const TargetInstrDesc &TID = I.getDesc(); + + // Ignore stuff that we obviously can't hoist. + if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() || + TID.hasUnmodeledSideEffects()) + return false; + + if (TID.mayLoad()) { + // Okay, this instruction does a load. As a refinement, allow the target + // to decide whether the loaded value is actually a constant. If so, we + // can actually use it as a load. + if (!TII->isInvariantLoad(&I)) { + // FIXME: we should be able to sink loads with no other side effects if + // there is nothing that can change memory from here until the end of + // block. This is a trivial form of alias analysis. + return false; + } + } + + DEBUG({ DOUT << "--- Checking if we can hoist " << I; if (I.getDesc().getImplicitUses()) { @@ -243,8 +263,8 @@ DOUT << " -> " << MRI->getName(*ImpDefs) << "\n"; } - if (TII->hasUnmodelledSideEffects(&I)) - DOUT << " * Instruction has side effects.\n"; + //if (TII->hasUnmodelledSideEffects(&I)) + //DOUT << " * Instruction has side effects.\n"; }); // The instruction is loop invariant if all of its operands are loop-invariant @@ -268,9 +288,6 @@ return false; } - // Don't hoist something that has unmodelled side effects. - if (TII->hasUnmodelledSideEffects(&I)) return false; - // If we got this far, the instruction is loop invariant! return true; } Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSink.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSink.cpp Thu Jan 10 17:08:24 2008 @@ -133,19 +133,21 @@ const TargetInstrDesc &TID = MI->getDesc(); // Ignore stuff that we obviously can't sink. - if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch()) + if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() || + TID.hasUnmodeledSideEffects()) return false; - if (TID.mayLoad()) - return false; - - // Don't sink things with side-effects we don't understand. - if (TII->hasUnmodelledSideEffects(MI)) - return false; - - // FIXME: we should be able to sink loads with no other side effects if there - // is nothing that can change memory from here until the end of block. This - // is a trivial form of alias analysis. + if (TID.mayLoad()) { + // Okay, this instruction does a load. As a refinement, allow the target + // to decide whether the loaded value is actually a constant. If so, we + // can actually use it as a load. + if (!TII->isInvariantLoad(MI)) { + // FIXME: we should be able to sink loads with no other side effects if + // there is nothing that can change memory from here until the end of + // block. This is a trivial form of alias analysis. + return false; + } + } // FIXME: This should include support for sinking instructions within the // block they are currently in to shorten the live ranges. We often get Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Thu Jan 10 17:08:24 2008 @@ -763,16 +763,19 @@ return true; } -/// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this -/// method is called to determine if the specific instance of this instruction -/// has side effects. This is useful in cases of instructions, like loads, which -/// generally always have side effects. A load from a constant pool doesn't have -/// side effects, though. So we need to differentiate it from the general case. -bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const { +/// isInvariantLoad - Return true if the specified instruction (which is marked +/// mayLoad) is loading from a location whose value is invariant across the +/// function. For example, loading a value from the constant pool or from +/// from the argument area of a function if it does not change. This should +/// only return true of *all* loads the instruction does are invariant (if it +/// does multiple loads). +bool X86InstrInfo::isInvariantLoad(MachineInstr *MI) const { + // FIXME: This should work with any X86 instruction that does a load, for + // example, all load+op instructions. switch (MI->getOpcode()) { default: break; case X86::MOV32rm: - // Loads from stubs of global addresses are side effect free. + // Loads from stubs of global addresses are invariant. if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && MI->getOperand(4).isGlobal() && @@ -794,7 +797,7 @@ case X86::MOVAPDrm: case X86::MMX_MOVD64rm: case X86::MMX_MOVQ64rm: - // Loads from constant pools are trivially rematerializable. + // Loads from constant pools are trivially invariant. if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && MI->getOperand(4).isCPI() && MI->getOperand(1).getReg() == 0 && @@ -815,8 +818,8 @@ return false; } - // All other instances of these instructions are presumed to have side - // effects. + // All other instances of these instructions are presumed to have other + // issues. return false; } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Thu Jan 10 17:08:24 2008 @@ -255,7 +255,7 @@ unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; bool isReallyTriviallyReMaterializable(MachineInstr *MI) const; - bool isReallySideEffectFree(MachineInstr *MI) const; + bool isInvariantLoad(MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45843&r1=45842&r2=45843&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Thu Jan 10 17:08:24 2008 @@ -357,8 +357,7 @@ if (Inst.usesCustomDAGSchedInserter) OS << "|(1< References: <200801101449.m0AEn6QD031798@zion.cs.uiuc.edu> Message-ID: On Jan 10, 2008, at 6:49 AM, Jonathan Johnson wrote: > +

    If your name is mispelled, or organization affiliation isn't > correct, please email us, and we'll correct it. mispelled -> misspelled ;-) -bw From dalej at apple.com Thu Jan 10 17:38:45 2008 From: dalej at apple.com (Dale Johannesen) Date: Thu, 10 Jan 2008 23:38:45 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45844 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200801102338.m0ANcjRN004280@zion.cs.uiuc.edu> Author: johannes Date: Thu Jan 10 17:38:45 2008 New Revision: 45844 URL: http://llvm.org/viewvc/llvm-project?rev=45844&view=rev Log: Prevent crashes on erroneous input. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=45844&r1=45843&r2=45844&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Thu Jan 10 17:38:45 2008 @@ -800,6 +800,11 @@ /// reset_initializer_llvm - Change the initializer for a global variable. void reset_initializer_llvm(tree decl) { + // If there were earlier errors we can get here when DECL_LLVM has not + // been set. Don't crash. + if ((errorcount || sorrycount) && !DECL_LLVM(decl)) + return; + // Get or create the global variable now. GlobalVariable *GV = cast(DECL_LLVM(decl)); From dalej at apple.com Thu Jan 10 18:54:37 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 11 Jan 2008 00:54:37 -0000 Subject: [llvm-commits] [llvm] r45848 - in /llvm/trunk/lib/Target: PowerPC/PPCAsmPrinter.cpp PowerPC/PPCTargetAsmInfo.cpp X86/X86AsmPrinter.cpp X86/X86TargetAsmInfo.cpp Message-ID: <200801110054.m0B0sbeH009251@zion.cs.uiuc.edu> Author: johannes Date: Thu Jan 10 18:54:37 2008 New Revision: 45848 URL: http://llvm.org/viewvc/llvm-project?rev=45848&view=rev Log: Weak things initialized to 0 don't go in bss on Darwin. Cosmetic changes to spacing to match gcc (some dejagnu tests actually care). Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Jan 10 18:54:37 2008 @@ -767,7 +767,7 @@ case Function::InternalLinkage: return TAI->getTextSection(); case Function::WeakLinkage: case Function::LinkOnceLinkage: - return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions"; + return "\t.section __TEXT,__textcoal_nt,coalesced,pure_instructions"; } } @@ -869,13 +869,13 @@ // Prime text sections so they are adjacent. This reduces the likelihood a // large data or debug section causes a branch to exceed 16M limit. - SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced," + SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced," "pure_instructions"); if (TM.getRelocationModel() == Reloc::PIC_) { - SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," + SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs," "pure_instructions,32"); } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { - SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," + SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs," "pure_instructions,16"); } SwitchToTextSection(TAI->getTextSection()); @@ -917,8 +917,7 @@ if (C->isNullValue() && /* FIXME: Verify correct */ !I->hasSection() && - (I->hasInternalLinkage() || I->hasWeakLinkage() || - I->hasLinkOnceLinkage() || I->hasExternalLinkage())) { + (I->hasInternalLinkage() || I->hasExternalLinkage())) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (I->hasExternalLinkage()) { O << "\t.globl " << name << '\n'; @@ -941,7 +940,7 @@ case GlobalValue::WeakLinkage: O << "\t.globl " << name << '\n' << "\t.weak_definition " << name << '\n'; - SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); + SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I); break; case GlobalValue::AppendingLinkage: // FIXME: appending linkage variables should go into a section of @@ -1008,7 +1007,7 @@ if (TM.getRelocationModel() == Reloc::PIC_) { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { - SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," + SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs," "pure_instructions,32"); EmitAlignment(4); O << "L" << *i << "$stub:\n"; @@ -1036,7 +1035,7 @@ } else { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { - SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," + SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs," "pure_instructions,16"); EmitAlignment(4); O << "L" << *i << "$stub:\n"; Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Thu Jan 10 18:54:37 2008 @@ -53,7 +53,7 @@ UsedDirective = "\t.no_dead_strip\t"; WeakDefDirective = "\t.weak_definition "; WeakRefDirective = "\t.weak_reference "; - HiddenDirective = "\t.private_extern\t"; + HiddenDirective = "\t.private_extern "; SupportsExceptionHandling = true; NeedsIndirectEncoding = true; NeedsSet = true; Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Thu Jan 10 18:54:37 2008 @@ -173,7 +173,7 @@ if (C->isNullValue() && !I->hasSection()) { if (I->hasExternalLinkage()) { if (const char *Directive = TAI->getZeroFillDirective()) { - O << "\t.globl\t" << name << "\n"; + O << "\t.globl " << name << "\n"; O << Directive << "__DATA__, __common, " << name << ", " << Size << ", " << Align << "\n"; continue; @@ -181,8 +181,9 @@ } if (!I->isThreadLocal() && - (I->hasInternalLinkage() || I->hasWeakLinkage() || - I->hasLinkOnceLinkage())) { + (I->hasInternalLinkage() || + (!Subtarget->isTargetDarwin() && + (I->hasWeakLinkage() || I->hasLinkOnceLinkage())))) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (!NoZerosInBSS && TAI->getBSSSection()) SwitchToDataSection(TAI->getBSSSection(), I); @@ -218,9 +219,9 @@ case GlobalValue::LinkOnceLinkage: case GlobalValue::WeakLinkage: if (Subtarget->isTargetDarwin()) { - O << "\t.globl\t" << name << "\n" + O << "\t.globl " << name << "\n" << TAI->getWeakDefDirective() << name << "\n"; - SwitchToDataSection(".section __DATA,__const_coal,coalesced", I); + SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I); } else if (Subtarget->isTargetCygMing()) { std::string SectionName(".section\t.data$linkonce." + name + @@ -244,7 +245,7 @@ // their name or something. For now, just emit them as external. case GlobalValue::ExternalLinkage: // If external or appending, declare as a global symbol - O << "\t.globl\t" << name << "\n"; + O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: { if (I->isConstant()) { @@ -348,7 +349,7 @@ unsigned j = 1; for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i, ++j) { - SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs," + SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," "self_modifying_code+pure_instructions,5", 0); O << "L" << *i << "$stub:\n"; O << "\t.indirect_symbol " << *i << "\n"; @@ -369,7 +370,7 @@ // Output stubs for external and common global variables. if (!GVStubs.empty()) SwitchToDataSection( - ".section __IMPORT,__pointers,non_lazy_symbol_pointers"); + "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers"); for (std::set::iterator i = GVStubs.begin(), e = GVStubs.end(); i != e; ++i) { O << "L" << *i << "$non_lazy_ptr:\n"; Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Thu Jan 10 18:54:37 2008 @@ -78,7 +78,7 @@ UsedDirective = "\t.no_dead_strip\t"; WeakDefDirective = "\t.weak_definition "; WeakRefDirective = "\t.weak_reference "; - HiddenDirective = "\t.private_extern\t"; + HiddenDirective = "\t.private_extern "; // In non-PIC modes, emit a special label before jump tables so that the // linker can perform more accurate dead code stripping. From evan.cheng at apple.com Thu Jan 10 18:59:08 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 16:59:08 -0800 Subject: [llvm-commits] [llvm] r45848 - in /llvm/trunk/lib/Target: PowerPC/PPCAsmPrinter.cpp PowerPC/PPCTargetAsmInfo.cpp X86/X86AsmPrinter.cpp X86/X86TargetAsmInfo.cpp In-Reply-To: <200801110054.m0B0sbeH009251@zion.cs.uiuc.edu> References: <200801110054.m0B0sbeH009251@zion.cs.uiuc.edu> Message-ID: How about ARM? Evan On Jan 10, 2008, at 4:54 PM, Dale Johannesen wrote: > Author: johannes > Date: Thu Jan 10 18:54:37 2008 > New Revision: 45848 > > URL: http://llvm.org/viewvc/llvm-project?rev=45848&view=rev > Log: > Weak things initialized to 0 don't go in bss on Darwin. > Cosmetic changes to spacing to match gcc (some dejagnu > tests actually care). > > > Modified: > llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp > llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp > llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp > llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp > > Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Jan 10 > 18:54:37 2008 > @@ -767,7 +767,7 @@ > case Function::InternalLinkage: return TAI->getTextSection(); > case Function::WeakLinkage: > case Function::LinkOnceLinkage: > - return ".section > __TEXT,__textcoal_nt,coalesced,pure_instructions"; > + return "\t.section > __TEXT,__textcoal_nt,coalesced,pure_instructions"; > } > } > > @@ -869,13 +869,13 @@ > > // Prime text sections so they are adjacent. This reduces the > likelihood a > // large data or debug section causes a branch to exceed 16M limit. > - SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced," > + SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced," > "pure_instructions"); > if (TM.getRelocationModel() == Reloc::PIC_) { > - SwitchToTextSection(".section > __TEXT,__picsymbolstub1,symbol_stubs," > + SwitchToTextSection("\t.section > __TEXT,__picsymbolstub1,symbol_stubs," > "pure_instructions,32"); > } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { > - SwitchToTextSection(".section > __TEXT,__symbol_stub1,symbol_stubs," > + SwitchToTextSection("\t.section > __TEXT,__symbol_stub1,symbol_stubs," > "pure_instructions,16"); > } > SwitchToTextSection(TAI->getTextSection()); > @@ -917,8 +917,7 @@ > > if (C->isNullValue() && /* FIXME: Verify correct */ > !I->hasSection() && > - (I->hasInternalLinkage() || I->hasWeakLinkage() || > - I->hasLinkOnceLinkage() || I->hasExternalLinkage())) { > + (I->hasInternalLinkage() || I->hasExternalLinkage())) { > if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid > it. > if (I->hasExternalLinkage()) { > O << "\t.globl " << name << '\n'; > @@ -941,7 +940,7 @@ > case GlobalValue::WeakLinkage: > O << "\t.globl " << name << '\n' > << "\t.weak_definition " << name << '\n'; > - SwitchToDataSection(".section > __DATA,__datacoal_nt,coalesced", I); > + SwitchToDataSection("\t.section > __DATA,__datacoal_nt,coalesced", I); > break; > case GlobalValue::AppendingLinkage: > // FIXME: appending linkage variables should go into a > section of > @@ -1008,7 +1007,7 @@ > if (TM.getRelocationModel() == Reloc::PIC_) { > for (std::set::iterator i = FnStubs.begin(), e = > FnStubs.end(); > i != e; ++i) { > - SwitchToTextSection(".section > __TEXT,__picsymbolstub1,symbol_stubs," > + SwitchToTextSection("\t.section > __TEXT,__picsymbolstub1,symbol_stubs," > "pure_instructions,32"); > EmitAlignment(4); > O << "L" << *i << "$stub:\n"; > @@ -1036,7 +1035,7 @@ > } else { > for (std::set::iterator i = FnStubs.begin(), e = > FnStubs.end(); > i != e; ++i) { > - SwitchToTextSection(".section > __TEXT,__symbol_stub1,symbol_stubs," > + SwitchToTextSection("\t.section > __TEXT,__symbol_stub1,symbol_stubs," > "pure_instructions,16"); > EmitAlignment(4); > O << "L" << *i << "$stub:\n"; > > Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Thu Jan 10 > 18:54:37 2008 > @@ -53,7 +53,7 @@ > UsedDirective = "\t.no_dead_strip\t"; > WeakDefDirective = "\t.weak_definition "; > WeakRefDirective = "\t.weak_reference "; > - HiddenDirective = "\t.private_extern\t"; > + HiddenDirective = "\t.private_extern "; > SupportsExceptionHandling = true; > NeedsIndirectEncoding = true; > NeedsSet = true; > > Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Thu Jan 10 18:54:37 > 2008 > @@ -173,7 +173,7 @@ > if (C->isNullValue() && !I->hasSection()) { > if (I->hasExternalLinkage()) { > if (const char *Directive = TAI->getZeroFillDirective()) { > - O << "\t.globl\t" << name << "\n"; > + O << "\t.globl " << name << "\n"; > O << Directive << "__DATA__, __common, " << name << ", " > << Size << ", " << Align << "\n"; > continue; > @@ -181,8 +181,9 @@ > } > > if (!I->isThreadLocal() && > - (I->hasInternalLinkage() || I->hasWeakLinkage() || > - I->hasLinkOnceLinkage())) { > + (I->hasInternalLinkage() || > + (!Subtarget->isTargetDarwin() && > + (I->hasWeakLinkage() || I->hasLinkOnceLinkage())))) { > if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, > avoid it. > if (!NoZerosInBSS && TAI->getBSSSection()) > SwitchToDataSection(TAI->getBSSSection(), I); > @@ -218,9 +219,9 @@ > case GlobalValue::LinkOnceLinkage: > case GlobalValue::WeakLinkage: > if (Subtarget->isTargetDarwin()) { > - O << "\t.globl\t" << name << "\n" > + O << "\t.globl " << name << "\n" > << TAI->getWeakDefDirective() << name << "\n"; > - SwitchToDataSection(".section > __DATA,__const_coal,coalesced", I); > + SwitchToDataSection("\t.section > __DATA,__datacoal_nt,coalesced", I); > } else if (Subtarget->isTargetCygMing()) { > std::string SectionName(".section\t.data$linkonce." + > name + > @@ -244,7 +245,7 @@ > // their name or something. For now, just emit them as > external. > case GlobalValue::ExternalLinkage: > // If external or appending, declare as a global symbol > - O << "\t.globl\t" << name << "\n"; > + O << "\t.globl " << name << "\n"; > // FALL THROUGH > case GlobalValue::InternalLinkage: { > if (I->isConstant()) { > @@ -348,7 +349,7 @@ > unsigned j = 1; > for (std::set::iterator i = FnStubs.begin(), e = > FnStubs.end(); > i != e; ++i, ++j) { > - SwitchToDataSection(".section > __IMPORT,__jump_table,symbol_stubs," > + SwitchToDataSection("\t.section > __IMPORT,__jump_table,symbol_stubs," > "self_modifying_code+pure_instructions,5", > 0); > O << "L" << *i << "$stub:\n"; > O << "\t.indirect_symbol " << *i << "\n"; > @@ -369,7 +370,7 @@ > // Output stubs for external and common global variables. > if (!GVStubs.empty()) > SwitchToDataSection( > - ".section > __IMPORT,__pointers,non_lazy_symbol_pointers"); > + "\t.section > __IMPORT,__pointers,non_lazy_symbol_pointers"); > for (std::set::iterator i = GVStubs.begin(), e = > GVStubs.end(); > i != e; ++i) { > O << "L" << *i << "$non_lazy_ptr:\n"; > > Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Thu Jan 10 > 18:54:37 2008 > @@ -78,7 +78,7 @@ > UsedDirective = "\t.no_dead_strip\t"; > WeakDefDirective = "\t.weak_definition "; > WeakRefDirective = "\t.weak_reference "; > - HiddenDirective = "\t.private_extern\t"; > + HiddenDirective = "\t.private_extern "; > > // In non-PIC modes, emit a special label before jump tables so > that the > // linker can perform more accurate dead code stripping. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Thu Jan 10 19:10:00 2008 From: dalej at apple.com (Dale Johannesen) Date: Thu, 10 Jan 2008 17:10:00 -0800 Subject: [llvm-commits] [llvm] r45848 - in /llvm/trunk/lib/Target: PowerPC/PPCAsmPrinter.cpp PowerPC/PPCTargetAsmInfo.cpp X86/X86AsmPrinter.cpp X86/X86TargetAsmInfo.cpp In-Reply-To: References: <200801110054.m0B0sbeH009251@zion.cs.uiuc.edu> Message-ID: <2FE904A5-A393-4732-BEB6-19773297B70C@apple.com> On Jan 10, 2008, at 4:59 PM, Evan Cheng wrote: > How about ARM? > > Evan Hadn't thought of that, but yeah, I should make the substantiative changes there too. > On Jan 10, 2008, at 4:54 PM, Dale Johannesen wrote: > >> Author: johannes >> Date: Thu Jan 10 18:54:37 2008 >> New Revision: 45848 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45848&view=rev >> Log: >> Weak things initialized to 0 don't go in bss on Darwin. >> Cosmetic changes to spacing to match gcc (some dejagnu >> tests actually care). >> >> >> Modified: >> llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp >> llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp >> llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp >> llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp >> >> Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Jan 10 >> 18:54:37 2008 >> @@ -767,7 +767,7 @@ >> case Function::InternalLinkage: return TAI->getTextSection(); >> case Function::WeakLinkage: >> case Function::LinkOnceLinkage: >> - return ".section >> __TEXT,__textcoal_nt,coalesced,pure_instructions"; >> + return "\t.section >> __TEXT,__textcoal_nt,coalesced,pure_instructions"; >> } >> } >> >> @@ -869,13 +869,13 @@ >> >> // Prime text sections so they are adjacent. This reduces the >> likelihood a >> // large data or debug section causes a branch to exceed 16M limit. >> - SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced," >> + SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced," >> "pure_instructions"); >> if (TM.getRelocationModel() == Reloc::PIC_) { >> - SwitchToTextSection(".section >> __TEXT,__picsymbolstub1,symbol_stubs," >> + SwitchToTextSection("\t.section >> __TEXT,__picsymbolstub1,symbol_stubs," >> "pure_instructions,32"); >> } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { >> - SwitchToTextSection(".section >> __TEXT,__symbol_stub1,symbol_stubs," >> + SwitchToTextSection("\t.section >> __TEXT,__symbol_stub1,symbol_stubs," >> "pure_instructions,16"); >> } >> SwitchToTextSection(TAI->getTextSection()); >> @@ -917,8 +917,7 @@ >> >> if (C->isNullValue() && /* FIXME: Verify correct */ >> !I->hasSection() && >> - (I->hasInternalLinkage() || I->hasWeakLinkage() || >> - I->hasLinkOnceLinkage() || I->hasExternalLinkage())) { >> + (I->hasInternalLinkage() || I->hasExternalLinkage())) { >> if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid >> it. >> if (I->hasExternalLinkage()) { >> O << "\t.globl " << name << '\n'; >> @@ -941,7 +940,7 @@ >> case GlobalValue::WeakLinkage: >> O << "\t.globl " << name << '\n' >> << "\t.weak_definition " << name << '\n'; >> - SwitchToDataSection(".section >> __DATA,__datacoal_nt,coalesced", I); >> + SwitchToDataSection("\t.section >> __DATA,__datacoal_nt,coalesced", I); >> break; >> case GlobalValue::AppendingLinkage: >> // FIXME: appending linkage variables should go into a >> section of >> @@ -1008,7 +1007,7 @@ >> if (TM.getRelocationModel() == Reloc::PIC_) { >> for (std::set::iterator i = FnStubs.begin(), e = >> FnStubs.end(); >> i != e; ++i) { >> - SwitchToTextSection(".section >> __TEXT,__picsymbolstub1,symbol_stubs," >> + SwitchToTextSection("\t.section >> __TEXT,__picsymbolstub1,symbol_stubs," >> "pure_instructions,32"); >> EmitAlignment(4); >> O << "L" << *i << "$stub:\n"; >> @@ -1036,7 +1035,7 @@ >> } else { >> for (std::set::iterator i = FnStubs.begin(), e = >> FnStubs.end(); >> i != e; ++i) { >> - SwitchToTextSection(".section >> __TEXT,__symbol_stub1,symbol_stubs," >> + SwitchToTextSection("\t.section >> __TEXT,__symbol_stub1,symbol_stubs," >> "pure_instructions,16"); >> EmitAlignment(4); >> O << "L" << *i << "$stub:\n"; >> >> Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) >> +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Thu Jan 10 >> 18:54:37 2008 >> @@ -53,7 +53,7 @@ >> UsedDirective = "\t.no_dead_strip\t"; >> WeakDefDirective = "\t.weak_definition "; >> WeakRefDirective = "\t.weak_reference "; >> - HiddenDirective = "\t.private_extern\t"; >> + HiddenDirective = "\t.private_extern "; >> SupportsExceptionHandling = true; >> NeedsIndirectEncoding = true; >> NeedsSet = true; >> >> Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Thu Jan 10 18:54:37 >> 2008 >> @@ -173,7 +173,7 @@ >> if (C->isNullValue() && !I->hasSection()) { >> if (I->hasExternalLinkage()) { >> if (const char *Directive = TAI->getZeroFillDirective()) { >> - O << "\t.globl\t" << name << "\n"; >> + O << "\t.globl " << name << "\n"; >> O << Directive << "__DATA__, __common, " << name << ", " >> << Size << ", " << Align << "\n"; >> continue; >> @@ -181,8 +181,9 @@ >> } >> >> if (!I->isThreadLocal() && >> - (I->hasInternalLinkage() || I->hasWeakLinkage() || >> - I->hasLinkOnceLinkage())) { >> + (I->hasInternalLinkage() || >> + (!Subtarget->isTargetDarwin() && >> + (I->hasWeakLinkage() || I->hasLinkOnceLinkage())))) { >> if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, >> avoid it. >> if (!NoZerosInBSS && TAI->getBSSSection()) >> SwitchToDataSection(TAI->getBSSSection(), I); >> @@ -218,9 +219,9 @@ >> case GlobalValue::LinkOnceLinkage: >> case GlobalValue::WeakLinkage: >> if (Subtarget->isTargetDarwin()) { >> - O << "\t.globl\t" << name << "\n" >> + O << "\t.globl " << name << "\n" >> << TAI->getWeakDefDirective() << name << "\n"; >> - SwitchToDataSection(".section >> __DATA,__const_coal,coalesced", I); >> + SwitchToDataSection("\t.section >> __DATA,__datacoal_nt,coalesced", I); >> } else if (Subtarget->isTargetCygMing()) { >> std::string SectionName(".section\t.data$linkonce." + >> name + >> @@ -244,7 +245,7 @@ >> // their name or something. For now, just emit them as >> external. >> case GlobalValue::ExternalLinkage: >> // If external or appending, declare as a global symbol >> - O << "\t.globl\t" << name << "\n"; >> + O << "\t.globl " << name << "\n"; >> // FALL THROUGH >> case GlobalValue::InternalLinkage: { >> if (I->isConstant()) { >> @@ -348,7 +349,7 @@ >> unsigned j = 1; >> for (std::set::iterator i = FnStubs.begin(), e = >> FnStubs.end(); >> i != e; ++i, ++j) { >> - SwitchToDataSection(".section >> __IMPORT,__jump_table,symbol_stubs," >> + SwitchToDataSection("\t.section >> __IMPORT,__jump_table,symbol_stubs," >> "self_modifying_code+pure_instructions,5", >> 0); >> O << "L" << *i << "$stub:\n"; >> O << "\t.indirect_symbol " << *i << "\n"; >> @@ -369,7 +370,7 @@ >> // Output stubs for external and common global variables. >> if (!GVStubs.empty()) >> SwitchToDataSection( >> - ".section >> __IMPORT,__pointers,non_lazy_symbol_pointers"); >> + "\t.section >> __IMPORT,__pointers,non_lazy_symbol_pointers"); >> for (std::set::iterator i = GVStubs.begin(), e = >> GVStubs.end(); >> i != e; ++i) { >> O << "L" << *i << "$non_lazy_ptr:\n"; >> >> Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Thu Jan 10 >> 18:54:37 2008 >> @@ -78,7 +78,7 @@ >> UsedDirective = "\t.no_dead_strip\t"; >> WeakDefDirective = "\t.weak_definition "; >> WeakRefDirective = "\t.weak_reference "; >> - HiddenDirective = "\t.private_extern\t"; >> + HiddenDirective = "\t.private_extern "; >> >> // In non-PIC modes, emit a special label before jump tables so >> that the >> // linker can perform more accurate dead code stripping. >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Thu Jan 10 19:59:45 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 11 Jan 2008 01:59:45 -0000 Subject: [llvm-commits] [llvm] r45849 - /llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Message-ID: <200801110159.m0B1xjrc013460@zion.cs.uiuc.edu> Author: johannes Date: Thu Jan 10 19:59:45 2008 New Revision: 45849 URL: http://llvm.org/viewvc/llvm-project?rev=45849&view=rev Log: Weak zeroes don't go in bss on Darwin. Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=45849&r1=45848&r2=45849&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Thu Jan 10 19:59:45 2008 @@ -845,8 +845,9 @@ } } - if (I->hasInternalLinkage() || I->hasWeakLinkage() || - I->hasLinkOnceLinkage()) { + if (I->hasInternalLinkage() || + (!Subtarget->isTargetDarwin() && + (I->hasWeakLinkage() || I->hasLinkOnceLinkage()))) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (!NoZerosInBSS && TAI->getBSSSection()) SwitchToDataSection(TAI->getBSSSection(), I); @@ -877,7 +878,7 @@ if (Subtarget->isTargetDarwin()) { O << "\t.globl " << name << "\n" << "\t.weak_definition " << name << "\n"; - SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I); + SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I); } else { std::string SectionName("\t.section\t.llvm.linkonce.d." + name + From evan.cheng at apple.com Thu Jan 10 20:13:11 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 02:13:11 -0000 Subject: [llvm-commits] [llvm] r45850 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> Author: evancheng Date: Thu Jan 10 20:13:09 2008 New Revision: 45850 URL: http://llvm.org/viewvc/llvm-project?rev=45850&view=rev Log: Allow parameter attributes on varargs function parameters. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=45850&r1=45849&r2=45850&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Thu Jan 10 20:13:09 2008 @@ -390,10 +390,9 @@ if (!Attrs) return; - // Note that when calling a varargs function, the following test disallows - // parameter attributes for the arguments corresponding to the varargs part. - Assert1(Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams(), + Assert1(FT->isVarArg() || + (Attrs->size() && + Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()), "Attributes after end of type!", V); bool SawNest = false; From jon at alacatialabs.com Thu Jan 10 20:28:01 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Thu, 10 Jan 2008 20:28:01 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/index.html In-Reply-To: References: <200801101449.m0AEn6QD031798@zion.cs.uiuc.edu> Message-ID: <8B513F11-795F-4D17-8552-367638571E5F@alacatialabs.com> On Jan 10, 2008, at 5:32 PM, Bill Wendling wrote: > On Jan 10, 2008, at 6:49 AM, Jonathan Johnson wrote: >> +

    If your name is mispelled, or organization affiliation isn't >> correct, please email us, and we'll correct it. > > mispelled -> misspelled ;-) I was just checking to see if anyone was paying attention... ;) -Jon -- Jonathan Johnson President Alacatia Labs, Inc. http://www.alacatialabs.com/ From jon at alacatialabs.com Thu Jan 10 20:28:29 2008 From: jon at alacatialabs.com (Jonathan Johnson) Date: Thu, 10 Jan 2008 20:28:29 -0600 Subject: [llvm-commits] CVS: llvm-www/devmtg/current/index.html Message-ID: <200801110228.m0B2STew015710@zion.cs.uiuc.edu> Changes in directory llvm-www/devmtg/current: index.html updated: 1.4 -> 1.5 --- Log message: Coreected speeling error, and updated list of attendees. --- Diffs of the changes: (+5 -3) index.html | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) Index: llvm-www/devmtg/current/index.html diff -u llvm-www/devmtg/current/index.html:1.4 llvm-www/devmtg/current/index.html:1.5 --- llvm-www/devmtg/current/index.html:1.4 Thu Jan 10 08:48:07 2008 +++ llvm-www/devmtg/current/index.html Thu Jan 10 20:27:44 2008 @@ -42,8 +42,10 @@ Robert HundtGoogle Dale JohannesenApple, Inc. Jonathan JohnsonAlacatia Labs, Inc. - Ted Kremenek + Ted KremenekApple, Inc. Chris LattnerApple, Inc. + Nick LewyckyGoogle + Harry Metcalfe Steve NaroffApple, Inc. Ted Neward Devang PatelApple, Inc. @@ -52,8 +54,8 @@ Mike StumpApple, Inc. Bill WendlingApple, Inc. -

    Total unconfirmed: 15

    -

    If your name is mispelled, or organization affiliation isn't correct, please email us, and we'll correct it. +

    Total unconfirmed: 17

    +

    If your name is misspelled, or organization affiliation isn't correct, please email us, and we'll correct it. \ No newline at end of file From scottm at aero.org Thu Jan 10 20:53:16 2008 From: scottm at aero.org (Scott Michel) Date: Fri, 11 Jan 2008 02:53:16 -0000 Subject: [llvm-commits] [llvm] r45851 - in /llvm/trunk: include/llvm/ include/llvm/CodeGen/ lib/Target/CellSPU/ test/CodeGen/CellSPU/ Message-ID: <200801110253.m0B2rILm017503@zion.cs.uiuc.edu> Author: pingbak Date: Thu Jan 10 20:53:15 2008 New Revision: 45851 URL: http://llvm.org/viewvc/llvm-project?rev=45851&view=rev Log: More CellSPU refinement and progress: - Cleaned up custom load/store logic, common code is now shared [see note below], cleaned up address modes - More test cases: various intrinsics, structure element access (load/store test), updated target data strings, indirect function calls. Note: This patch contains a refactoring of the LoadSDNode and StoreSDNode structures: they now share a common base class, LSBaseSDNode, that provides an interface to their common functionality. There is some hackery to access the proper operand depending on the derived class; otherwise, to do a proper job would require finding and rearranging the SDOperands sent to StoreSDNode's constructor. The current refactor errs on the side of being conservatively and backwardly compatible while providing functionality that reduces redundant code for targets where loads and stores are custom-lowered. Added: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll llvm/trunk/test/CodeGen/CellSPU/struct_1.ll Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/include/llvm/IntrinsicsCellSPU.td llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td llvm/trunk/lib/Target/CellSPU/SPUNodes.td llvm/trunk/lib/Target/CellSPU/SPUOperands.td llvm/trunk/test/CodeGen/CellSPU/and_ops.ll llvm/trunk/test/CodeGen/CellSPU/ctpop.ll llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll llvm/trunk/test/CodeGen/CellSPU/eqv.ll llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll llvm/trunk/test/CodeGen/CellSPU/fcmp.ll llvm/trunk/test/CodeGen/CellSPU/fdiv.ll llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll llvm/trunk/test/CodeGen/CellSPU/immed16.ll llvm/trunk/test/CodeGen/CellSPU/immed32.ll llvm/trunk/test/CodeGen/CellSPU/immed64.ll llvm/trunk/test/CodeGen/CellSPU/int2fp.ll llvm/trunk/test/CodeGen/CellSPU/nand.ll llvm/trunk/test/CodeGen/CellSPU/or_ops.ll llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll llvm/trunk/test/CodeGen/CellSPU/select_bits.ll llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Jan 10 20:53:15 2008 @@ -1454,11 +1454,63 @@ } }; +/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode +/// +class LSBaseSDNode : public SDNode { +private: + //! SrcValue - Memory location for alias analysis. + const Value *SrcValue; + + //! SVOffset - Memory location offset. + int SVOffset; + + //! Alignment - Alignment of memory location in bytes. + unsigned Alignment; + + //! IsVolatile - True if the store is volatile. + bool IsVolatile; +protected: + //! Operand array for load and store + /*! + \note Moving this array to the base class captures more + common functionality shared between LoadSDNode and + StoreSDNode + */ + SDOperand Ops[4]; +public: + LSBaseSDNode(ISD::NodeType NodeTy, SDVTList VTs, const Value *SV, int SVO, + unsigned Align, bool Vol) + : SDNode(NodeTy, VTs), + SrcValue(SV), SVOffset(SVO), Alignment(Align), IsVolatile(Vol) + { } + + const SDOperand getChain() const { + return getOperand(0); + } + const SDOperand getBasePtr() const { + return getOperand(getOpcode() == ISD::LOAD ? 1 : 2); + } + const SDOperand getOffset() const { + return getOperand(getOpcode() == ISD::LOAD ? 2 : 3); + } + const SDOperand getValue() const { + assert(getOpcode() == ISD::STORE); + return getOperand(1); + } + + const Value *getSrcValue() const { return SrcValue; } + int getSrcValueOffset() const { return SVOffset; } + unsigned getAlignment() const { return Alignment; } + bool isVolatile() const { return IsVolatile; } + + static bool classof(const LSBaseSDNode *N) { return true; } + static bool classof(const SDNode *N) { return true; } +}; + /// LoadSDNode - This class is used to represent ISD::LOAD nodes. /// -class LoadSDNode : public SDNode { +class LoadSDNode : public LSBaseSDNode { virtual void ANCHOR(); // Out-of-line virtual method to give class a home. - SDOperand Ops[3]; // AddrMode - unindexed, pre-indexed, post-indexed. ISD::MemIndexedMode AddrMode; @@ -1468,26 +1520,13 @@ // LoadedVT - VT of loaded value before extension. MVT::ValueType LoadedVT; - - // SrcValue - Memory location for alias analysis. - const Value *SrcValue; - - // SVOffset - Memory location offset. - int SVOffset; - - // Alignment - Alignment of memory location in bytes. - unsigned Alignment; - - // IsVolatile - True if the load is volatile. - bool IsVolatile; protected: friend class SelectionDAG; LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT, const Value *SV, int O=0, unsigned Align=0, bool Vol=false) - : SDNode(ISD::LOAD, VTs), - AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O), - Alignment(Align), IsVolatile(Vol) { + : LSBaseSDNode(ISD::LOAD, VTs, SV, O, Align, Vol), + AddrMode(AM), ExtType(ETy), LoadedVT(LVT) { Ops[0] = ChainPtrOff[0]; // Chain Ops[1] = ChainPtrOff[1]; // Ptr Ops[2] = ChainPtrOff[2]; // Off @@ -1499,18 +1538,12 @@ } public: - const SDOperand getChain() const { return getOperand(0); } - const SDOperand getBasePtr() const { return getOperand(1); } - const SDOperand getOffset() const { return getOperand(2); } ISD::MemIndexedMode getAddressingMode() const { return AddrMode; } ISD::LoadExtType getExtensionType() const { return ExtType; } MVT::ValueType getLoadedVT() const { return LoadedVT; } - const Value *getSrcValue() const { return SrcValue; } - int getSrcValueOffset() const { return SVOffset; } - unsigned getAlignment() const { return Alignment; } - bool isVolatile() const { return IsVolatile; } static bool classof(const LoadSDNode *) { return true; } + static bool classof(const LSBaseSDNode *N) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD; } @@ -1518,9 +1551,8 @@ /// StoreSDNode - This class is used to represent ISD::STORE nodes. /// -class StoreSDNode : public SDNode { +class StoreSDNode : public LSBaseSDNode { virtual void ANCHOR(); // Out-of-line virtual method to give class a home. - SDOperand Ops[4]; // AddrMode - unindexed, pre-indexed, post-indexed. ISD::MemIndexedMode AddrMode; @@ -1530,26 +1562,13 @@ // StoredVT - VT of the value after truncation. MVT::ValueType StoredVT; - - // SrcValue - Memory location for alias analysis. - const Value *SrcValue; - - // SVOffset - Memory location offset. - int SVOffset; - - // Alignment - Alignment of memory location in bytes. - unsigned Alignment; - - // IsVolatile - True if the store is volatile. - bool IsVolatile; protected: friend class SelectionDAG; StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT, const Value *SV, int O=0, unsigned Align=0, bool Vol=false) - : SDNode(ISD::STORE, VTs), - AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT), SrcValue(SV), - SVOffset(O), Alignment(Align), IsVolatile(Vol) { + : LSBaseSDNode(ISD::STORE, VTs, SV, O, Align, Vol), + AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT) { Ops[0] = ChainValuePtrOff[0]; // Chain Ops[1] = ChainValuePtrOff[1]; // Value Ops[2] = ChainValuePtrOff[2]; // Ptr @@ -1562,19 +1581,12 @@ } public: - const SDOperand getChain() const { return getOperand(0); } - const SDOperand getValue() const { return getOperand(1); } - const SDOperand getBasePtr() const { return getOperand(2); } - const SDOperand getOffset() const { return getOperand(3); } ISD::MemIndexedMode getAddressingMode() const { return AddrMode; } bool isTruncatingStore() const { return IsTruncStore; } MVT::ValueType getStoredVT() const { return StoredVT; } - const Value *getSrcValue() const { return SrcValue; } - int getSrcValueOffset() const { return SVOffset; } - unsigned getAlignment() const { return Alignment; } - bool isVolatile() const { return IsVolatile; } static bool classof(const StoreSDNode *) { return true; } + static bool classof(const LSBaseSDNode *N) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::STORE; } Modified: llvm/trunk/include/llvm/IntrinsicsCellSPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsCellSPU.td?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsCellSPU.td (original) +++ llvm/trunk/include/llvm/IntrinsicsCellSPU.td Thu Jan 10 20:53:15 2008 @@ -17,8 +17,8 @@ //===----------------------------------------------------------------------===// // 7-bit integer type, used as an immediate: -def cell_i7_ty: LLVMType; // Note: This was i8 -def cell_i8_ty: LLVMType; // Note: This was i8 +def cell_i7_ty: LLVMType; +def cell_i8_ty: LLVMType; class v16i8_u7imm : GCCBuiltin, @@ -27,7 +27,7 @@ class v16i8_u8imm : GCCBuiltin, - Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [IntrNoMem]>; class v16i8_s10imm : Modified: llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td (original) +++ llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td Thu Jan 10 20:53:15 2008 @@ -108,18 +108,18 @@ def CellSDKand: RRForm<0b1000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "add\t $rT, $rA, $rB", IntegerOp, + "and\t $rT, $rA, $rB", IntegerOp, [(set (v4i32 VECREG:$rT), (int_spu_si_and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; def CellSDKandc: RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "addc\t $rT, $rA, $rB", IntegerOp, + "andc\t $rT, $rA, $rB", IntegerOp, [(set (v4i32 VECREG:$rT), (int_spu_si_andc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; def CellSDKandbi: - RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val), "andbi\t $rT, $rA, $val", BranchResolv, [(set (v16i8 VECREG:$rT), (int_spu_si_andbi (v16i8 VECREG:$rA), immU8:$val))]>; @@ -149,7 +149,7 @@ (int_spu_si_orc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; def CellSDKorbi: - RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val), "orbi\t $rT, $rA, $val", BranchResolv, [(set (v16i8 VECREG:$rT), (int_spu_si_orbi (v16i8 VECREG:$rA), immU8:$val))]>; @@ -173,7 +173,7 @@ (int_spu_si_xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; def CellSDKxorbi: - RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val), "xorbi\t $rT, $rA, $val", BranchResolv, [(set (v16i8 VECREG:$rT), (int_spu_si_xorbi (v16i8 VECREG:$rA), immU8:$val))]>; @@ -248,7 +248,7 @@ (int_spu_si_ceqb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; def CellSDKceqbi: - RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val), "ceqbi\t $rT, $rA, $val", BranchResolv, [(set (v16i8 VECREG:$rT), (int_spu_si_ceqbi (v16i8 VECREG:$rA), immU8:$val))]>; @@ -294,7 +294,7 @@ (int_spu_si_cgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; def CellSDKcgtbi: - RI10Form<0b01110010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + RI10Form<0b01110010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val), "cgtbi\t $rT, $rA, $val", BranchResolv, [(set (v16i8 VECREG:$rT), (int_spu_si_cgtbi (v16i8 VECREG:$rA), immU8:$val))]>; @@ -329,7 +329,7 @@ (int_spu_si_clgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; def CellSDKclgtbi: - RI10Form<0b01111010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + RI10Form<0b01111010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val), "clgtbi\t $rT, $rA, $val", BranchResolv, [(set (v16i8 VECREG:$rT), (int_spu_si_clgtbi (v16i8 VECREG:$rA), immU8:$val))]>; Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Thu Jan 10 20:53:15 2008 @@ -384,11 +384,17 @@ SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, SDOperand &Index) { // These match the addr256k operand type: - MVT::ValueType PtrVT = SPUtli.getPointerTy(); MVT::ValueType OffsVT = MVT::i16; + MVT::ValueType PtrVT = SPUtli.getPointerTy(); switch (N.getOpcode()) { case ISD::Constant: + case ISD::ConstantPool: + case ISD::GlobalAddress: + cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; + abort(); + /*NOTREACHED*/ + case ISD::TargetConstant: { // Loading from a constant address. ConstantSDNode *CN = dyn_cast(N); @@ -400,23 +406,15 @@ return true; } } - case ISD::ConstantPool: - case ISD::TargetConstantPool: { - // The constant pool address is N. Base is a dummy that will be ignored by + case ISD::TargetGlobalAddress: + case ISD::TargetConstantPool: + case SPUISD::AFormAddr: { + // The address is in Base. N is a dummy that will be ignored by // the assembly printer. Base = N; Index = CurDAG->getTargetConstant(0, OffsVT); return true; } - - case ISD::GlobalAddress: - case ISD::TargetGlobalAddress: { - // The global address is N. Base is a dummy that is ignored by the - // assembly printer. - Base = N; - Index = CurDAG->getTargetConstant(0, OffsVT); - return true; - } } return false; @@ -445,10 +443,9 @@ Index = CurDAG->getTargetConstant(0, PtrTy); return true; } else if (Opc == ISD::FrameIndex) { - // Stack frame index must be less than 512 (divided by 16): FrameIndexSDNode *FI = dyn_cast(N); DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " - << FI->getIndex() << "\n"); + << FI->getIndex() << "\n"); if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { Base = CurDAG->getTargetConstant(0, PtrTy); Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); @@ -458,45 +455,49 @@ // Generated by getelementptr const SDOperand Op0 = N.getOperand(0); // Frame index/base const SDOperand Op1 = N.getOperand(1); // Offset within base - ConstantSDNode *CN = dyn_cast(Op1); - - // Not a constant? - if (CN == 0) - return false; - - int32_t offset = (int32_t) CN->getSignExtended(); - unsigned Opc0 = Op0.getOpcode(); - if ((offset & 0xf) != 0) { - cerr << "SelectDFormAddr: unaligned offset = " << offset << "\n"; - abort(); - /*NOTREACHED*/ - } - - if (Opc0 == ISD::FrameIndex) { - FrameIndexSDNode *FI = dyn_cast(Op0); - DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset - << " frame index = " << FI->getIndex() << "\n"); - - if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { - Base = CurDAG->getTargetConstant(offset, PtrTy); - Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); - return true; + if (Op1.getOpcode() == ISD::Constant + || Op1.getOpcode() == ISD::TargetConstant) { + ConstantSDNode *CN = dyn_cast(Op1); + assert(CN != 0 && "SelectDFormAddr: Expected a constant"); + + int32_t offset = (int32_t) CN->getSignExtended(); + unsigned Opc0 = Op0.getOpcode(); + + if ((offset & 0xf) != 0) { + // Unaligned offset: punt and let X-form address handle it. + // NOTE: This really doesn't have to be strictly 16-byte aligned, + // since the load/store quadword instructions will implicitly + // zero the lower 4 bits of the resulting address. + return false; } - } else if (offset > SPUFrameInfo::minFrameOffset() - && offset < SPUFrameInfo::maxFrameOffset()) { - Base = CurDAG->getTargetConstant(offset, PtrTy); - if (Opc0 == ISD::GlobalAddress) { - // Convert global address to target global address - GlobalAddressSDNode *GV = dyn_cast(Op0); - Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy); - return true; - } else { - // Otherwise, just take operand 0 - Index = Op0; - return true; + + if (Opc0 == ISD::FrameIndex) { + FrameIndexSDNode *FI = dyn_cast(Op0); + DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset + << " frame index = " << FI->getIndex() << "\n"); + + if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { + Base = CurDAG->getTargetConstant(offset, PtrTy); + Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); + return true; + } + } else if (offset > SPUFrameInfo::minFrameOffset() + && offset < SPUFrameInfo::maxFrameOffset()) { + Base = CurDAG->getTargetConstant(offset, PtrTy); + if (Opc0 == ISD::GlobalAddress) { + // Convert global address to target global address + GlobalAddressSDNode *GV = dyn_cast(Op0); + Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy); + return true; + } else { + // Otherwise, just take operand 0 + Index = Op0; + return true; + } } - } + } else + return false; } else if (Opc == SPUISD::DFormAddr) { // D-Form address: This is pretty straightforward, naturally... ConstantSDNode *CN = cast(N.getOperand(1)); @@ -504,6 +505,16 @@ Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); Index = N.getOperand(0); return true; + } else if (Opc == ISD::FrameIndex) { + // Stack frame index must be less than 512 (divided by 16): + FrameIndexSDNode *FI = dyn_cast(N); + DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " + << FI->getIndex() << "\n"); + if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { + Base = CurDAG->getTargetConstant(0, PtrTy); + Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); + return true; + } } return false; @@ -535,7 +546,8 @@ unsigned N2Opc = N2.getOpcode(); if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo) - || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)) { + || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi) + || (N1Opc == SPUISD::XFormAddr)) { Base = N.getOperand(0); Index = N.getOperand(1); return true; @@ -548,6 +560,10 @@ abort(); /*UNREACHED*/ } + } else if (Opc == SPUISD::XFormAddr) { + Base = N; + Index = N.getOperand(1); + return true; } else if (N.getNumOperands() == 2) { SDOperand N1 = N.getOperand(0); SDOperand N2 = N.getOperand(1); @@ -591,11 +607,14 @@ } else if (Opc == ISD::FrameIndex) { // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm. int FI = cast(N)->getIndex(); - SDOperand TFI = CurDAG->getTargetFrameIndex(FI, SPUtli.getPointerTy()); + MVT::ValueType PtrVT = SPUtli.getPointerTy(); + SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT); + SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT); DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 , 0\n"); - return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI, - CurDAG->getTargetConstant(0, MVT::i32)); + if (N->hasOneUse()) + return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI, Zero); + CurDAG->getTargetNode(SPU::AIr32, Op.getValueType(), TFI, Zero); } else if (Opc == SPUISD::LDRESULT) { // Custom select instructions for LDRESULT unsigned VT = N->getValueType(0); Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Jan 10 20:53:15 2008 @@ -82,7 +82,7 @@ /*! \arg Op Operand to test \return true if the operand is a memory target (i.e., global - address, external symbol, constant pool) or an existing D-Form + address, external symbol, constant pool) or an A-form address. */ bool isMemoryOperand(const SDOperand &Op) @@ -90,17 +90,17 @@ const unsigned Opc = Op.getOpcode(); return (Opc == ISD::GlobalAddress || Opc == ISD::GlobalTLSAddress - || Opc == ISD::FrameIndex + /* || Opc == ISD::FrameIndex */ || Opc == ISD::JumpTable || Opc == ISD::ConstantPool || Opc == ISD::ExternalSymbol || Opc == ISD::TargetGlobalAddress || Opc == ISD::TargetGlobalTLSAddress - || Opc == ISD::TargetFrameIndex + /* || Opc == ISD::TargetFrameIndex */ || Opc == ISD::TargetJumpTable || Opc == ISD::TargetConstantPool || Opc == ISD::TargetExternalSymbol - || Opc == SPUISD::DFormAddr); + || Opc == SPUISD::AFormAddr); } } @@ -356,7 +356,7 @@ setOperationAction(ISD::OR, MVT::v16i8, Custom); setOperationAction(ISD::XOR, MVT::v16i8, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom); - + setSetCCResultType(MVT::i32); setShiftAmountType(MVT::i32); setSetCCResultContents(ZeroOrOneSetCCResult); @@ -377,6 +377,7 @@ node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi"; node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo"; node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr"; + node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr"; node_names[(unsigned) SPUISD::DFormAddr] = "SPUISD::DFormAddr"; node_names[(unsigned) SPUISD::XFormAddr] = "SPUISD::XFormAddr"; node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT"; @@ -430,6 +431,105 @@ // LowerOperation implementation //===----------------------------------------------------------------------===// +/// Aligned load common code for CellSPU +/*! + \param[in] Op The SelectionDAG load or store operand + \param[in] DAG The selection DAG + \param[in] ST CellSPU subtarget information structure + \param[in,out] alignment Caller initializes this to the load or store node's + value from getAlignment(), may be updated while generating the aligned load + \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned + offset (divisible by 16, modulo 16 == 0) + \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the + offset of the preferred slot (modulo 16 != 0) + \param[in,out] VT Caller initializes this value type to the the load or store + node's loaded or stored value type; may be updated if an i1-extended load or + store. + \param[out] was16aligned true if the base pointer had 16-byte alignment, + otherwise false. Can help to determine if the chunk needs to be rotated. + + Both load and store lowering load a block of data aligned on a 16-byte + boundary. This is the common aligned load code shared between both. + */ +static SDOperand +AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST, + LSBaseSDNode *LSN, + unsigned &alignment, int &alignOffs, int &prefSlotOffs, + unsigned &VT, bool &was16aligned) +{ + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + const valtype_map_s *vtm = getValueTypeMapEntry(VT); + SDOperand basePtr = LSN->getBasePtr(); + SDOperand chain = LSN->getChain(); + + if (basePtr.getOpcode() == ISD::ADD) { + SDOperand Op1 = basePtr.Val->getOperand(1); + + if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) { + const ConstantSDNode *CN = cast(basePtr.Val->getOperand(1)); + + alignOffs = (int) CN->getValue(); + prefSlotOffs = (int) (alignOffs & 0xf); + + // Adjust the rotation amount to ensure that the final result ends up in + // the preferred slot: + prefSlotOffs -= vtm->prefslot_byte; + basePtr = basePtr.getOperand(0); + + // Modify alignment, since the ADD is likely from getElementPtr: + switch (basePtr.getOpcode()) { + case ISD::GlobalAddress: + case ISD::TargetGlobalAddress: { + GlobalAddressSDNode *GN = cast(basePtr.Val); + const GlobalValue *GV = GN->getGlobal(); + alignment = GV->getAlignment(); + break; + } + } + } else { + alignOffs = 0; + prefSlotOffs = -vtm->prefslot_byte; + } + } else { + alignOffs = 0; + prefSlotOffs = -vtm->prefslot_byte; + } + + if (alignment == 16) { + // Realign the base pointer as a D-Form address: + if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) { + if (isMemoryOperand(basePtr)) { + SDOperand Zero = DAG.getConstant(0, PtrVT); + unsigned Opc = (!ST->usingLargeMem() + ? SPUISD::AFormAddr + : SPUISD::XFormAddr); + basePtr = DAG.getNode(Opc, PtrVT, basePtr, Zero); + } + basePtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, + basePtr, DAG.getConstant((alignOffs & ~0xf), PtrVT)); + } + + // Emit the vector load: + was16aligned = true; + return DAG.getLoad(MVT::v16i8, chain, basePtr, + LSN->getSrcValue(), LSN->getSrcValueOffset(), + LSN->isVolatile(), 16); + } + + // Unaligned load or we're using the "large memory" model, which means that + // we have to be very pessimistic: + if (isMemoryOperand(basePtr)) { + basePtr = DAG.getNode(SPUISD::XFormAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT)); + } + + // Add the offset + basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, DAG.getConstant(alignOffs, PtrVT)); + was16aligned = false; + return DAG.getLoad(MVT::v16i8, chain, basePtr, + LSN->getSrcValue(), LSN->getSrcValueOffset(), + LSN->isVolatile(), 16); +} + /// Custom lower loads for CellSPU /*! All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements @@ -438,22 +538,13 @@ static SDOperand LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { LoadSDNode *LN = cast(Op); - SDOperand basep = LN->getBasePtr(); SDOperand the_chain = LN->getChain(); - MVT::ValueType BasepOpc = basep.Val->getOpcode(); MVT::ValueType VT = LN->getLoadedVT(); MVT::ValueType OpVT = Op.Val->getValueType(0); - MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); ISD::LoadExtType ExtType = LN->getExtensionType(); unsigned alignment = LN->getAlignment(); - const valtype_map_s *vtm = getValueTypeMapEntry(VT); SDOperand Ops[8]; - if (BasepOpc == ISD::FrameIndex) { - // Loading from a frame index is always properly aligned. Always. - return SDOperand(); - } - // For an extending load of an i1 variable, just call it i8 (or whatever we // were passed) and make it zero-extended: if (VT == MVT::i1) { @@ -463,178 +554,76 @@ switch (LN->getAddressingMode()) { case ISD::UNINDEXED: { - SDOperand result; - SDOperand rot_op, rotamt; - SDOperand ptrp; - int c_offset; - int c_rotamt; + int offset, rotamt; + bool was16aligned; + SDOperand result = + AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned); - // The vector type we really want to be when we load the 16-byte chunk - MVT::ValueType vecVT, opVecVT; - - vecVT = MVT::v16i8; - if (VT != MVT::i1) - vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT))); - opVecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT))); - - if (basep.getOpcode() == ISD::ADD) { - const ConstantSDNode *CN = cast(basep.Val->getOperand(1)); - - assert(CN != NULL - && "LowerLOAD: ISD::ADD operand 1 is not constant"); - - c_offset = (int) CN->getValue(); - c_rotamt = (int) (c_offset & 0xf); + if (result.Val == 0) + return result; - // Adjust the rotation amount to ensure that the final result ends up in - // the preferred slot: - c_rotamt -= vtm->prefslot_byte; - ptrp = basep.getOperand(0); - } else { - c_offset = 0; - c_rotamt = -vtm->prefslot_byte; - ptrp = basep; - } - - if (alignment == 16) { - // 16-byte aligned load into preferred slot, no rotation - if (c_rotamt == 0) { - if (isMemoryOperand(ptrp)) - // Return unchanged - return SDOperand(); - else { - // Return modified D-Form address for pointer: - ptrp = DAG.getNode(SPUISD::DFormAddr, PtrVT, - ptrp, DAG.getConstant((c_offset & ~0xf), PtrVT)); - if (VT == OpVT) - return DAG.getLoad(VT, LN->getChain(), ptrp, - LN->getSrcValue(), LN->getSrcValueOffset(), - LN->isVolatile(), 16); - else - return DAG.getExtLoad(ExtType, VT, LN->getChain(), ptrp, LN->getSrcValue(), - LN->getSrcValueOffset(), OpVT, - LN->isVolatile(), 16); - } + the_chain = result.getValue(1); + // Rotate the chunk if necessary + if (rotamt < 0) + rotamt += 16; + if (rotamt != 0) { + SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other); + + if (was16aligned) { + Ops[0] = the_chain; + Ops[1] = result; + Ops[2] = DAG.getConstant(rotamt, MVT::i16); } else { - // Need to rotate... - if (c_rotamt < 0) - c_rotamt += 16; - // Realign the base pointer, with a D-Form address - if ((c_offset & ~0xf) != 0 || !isMemoryOperand(ptrp)) - basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, - ptrp, DAG.getConstant((c_offset & ~0xf), MVT::i32)); - else - basep = ptrp; - - // Rotate the load: - rot_op = DAG.getLoad(MVT::v16i8, the_chain, basep, - LN->getSrcValue(), LN->getSrcValueOffset(), - LN->isVolatile(), 16); - the_chain = rot_op.getValue(1); - rotamt = DAG.getConstant(c_rotamt, MVT::i16); - - SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other); - Ops[0] = the_chain; - Ops[1] = rot_op; - Ops[2] = rotamt; - - result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3); - the_chain = result.getValue(1); - - if (VT == OpVT || ExtType == ISD::EXTLOAD) { - SDVTList scalarvts; - Ops[0] = the_chain; - Ops[1] = result; - if (OpVT == VT) { - scalarvts = DAG.getVTList(VT, MVT::Other); - } else { - scalarvts = DAG.getVTList(OpVT, MVT::Other); - } - - result = DAG.getNode(ISD::BIT_CONVERT, (OpVT == VT ? vecVT : opVecVT), - result); - Ops[0] = the_chain; - Ops[1] = result; - result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2); - the_chain = result.getValue(1); - } else { - // Handle the sign and zero-extending loads for i1 and i8: - unsigned NewOpC; - - if (ExtType == ISD::SEXTLOAD) { - NewOpC = (OpVT == MVT::i1 - ? SPUISD::EXTRACT_I1_SEXT - : SPUISD::EXTRACT_I8_SEXT); - } else { - assert(ExtType == ISD::ZEXTLOAD); - NewOpC = (OpVT == MVT::i1 - ? SPUISD::EXTRACT_I1_ZEXT - : SPUISD::EXTRACT_I8_ZEXT); - } - - result = DAG.getNode(NewOpC, OpVT, result); - } - - SDVTList retvts = DAG.getVTList(OpVT, MVT::Other); - SDOperand retops[2] = { result, the_chain }; - - result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2); - return result; - /*UNREACHED*/ - } - } else { - // Misaligned 16-byte load: - if (basep.getOpcode() == ISD::LOAD) { - LN = cast(basep); - if (LN->getAlignment() == 16) { - // We can verify that we're really loading from a 16-byte aligned - // chunk. Encapsulate basep as a D-Form address and return a new - // load: - basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, basep, - DAG.getConstant(0, PtrVT)); - if (OpVT == VT) - return DAG.getLoad(VT, LN->getChain(), basep, - LN->getSrcValue(), LN->getSrcValueOffset(), - LN->isVolatile(), 16); - else - return DAG.getExtLoad(ExtType, VT, LN->getChain(), basep, - LN->getSrcValue(), LN->getSrcValueOffset(), - OpVT, LN->isVolatile(), 16); - } + LoadSDNode *LN1 = cast(result); + Ops[0] = the_chain; + Ops[1] = result; + Ops[2] = LN1->getBasePtr(); } - // Catch all other cases where we can't guarantee that we have a - // 16-byte aligned entity, which means resorting to an X-form - // address scheme: - - SDOperand ZeroOffs = DAG.getConstant(0, PtrVT); - SDOperand loOp = DAG.getNode(SPUISD::Lo, PtrVT, basep, ZeroOffs); - SDOperand hiOp = DAG.getNode(SPUISD::Hi, PtrVT, basep, ZeroOffs); - - ptrp = DAG.getNode(ISD::ADD, PtrVT, loOp, hiOp); - - SDOperand alignLoad = - DAG.getLoad(opVecVT, LN->getChain(), ptrp, - LN->getSrcValue(), LN->getSrcValueOffset(), - LN->isVolatile(), 16); + result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3); + the_chain = result.getValue(1); + } - SDOperand insertEltOp = - DAG.getNode(SPUISD::INSERT_MASK, vecVT, ptrp); + if (VT == OpVT || ExtType == ISD::EXTLOAD) { + SDVTList scalarvts; + MVT::ValueType vecVT = MVT::v16i8; + + // Convert the loaded v16i8 vector to the appropriate vector type + // specified by the operand: + if (OpVT == VT) { + if (VT != MVT::i1) + vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT))); + } else + vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT))); + + Ops[0] = the_chain; + Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result); + scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other); + result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2); + the_chain = result.getValue(1); + } else { + // Handle the sign and zero-extending loads for i1 and i8: + unsigned NewOpC; - result = DAG.getNode(SPUISD::SHUFB, opVecVT, - alignLoad, - alignLoad, - DAG.getNode(ISD::BIT_CONVERT, opVecVT, insertEltOp)); + if (ExtType == ISD::SEXTLOAD) { + NewOpC = (OpVT == MVT::i1 + ? SPUISD::EXTRACT_I1_SEXT + : SPUISD::EXTRACT_I8_SEXT); + } else { + assert(ExtType == ISD::ZEXTLOAD); + NewOpC = (OpVT == MVT::i1 + ? SPUISD::EXTRACT_I1_ZEXT + : SPUISD::EXTRACT_I8_ZEXT); + } - result = DAG.getNode(SPUISD::EXTRACT_ELT0, OpVT, result); + result = DAG.getNode(NewOpC, OpVT, result); + } - SDVTList retvts = DAG.getVTList(OpVT, MVT::Other); - SDOperand retops[2] = { result, the_chain }; + SDVTList retvts = DAG.getVTList(OpVT, MVT::Other); + SDOperand retops[2] = { result, the_chain }; - result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2); - return result; - } - break; + result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2); + return result; } case ISD::PRE_INC: case ISD::PRE_DEC: @@ -664,58 +653,31 @@ MVT::ValueType VT = Value.getValueType(); MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getStoredVT()); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); - SDOperand the_chain = SN->getChain(); - //unsigned alignment = SN->getAlignment(); - //const valtype_map_s *vtm = getValueTypeMapEntry(VT); + unsigned alignment = SN->getAlignment(); switch (SN->getAddressingMode()) { case ISD::UNINDEXED: { - SDOperand basep = SN->getBasePtr(); - SDOperand ptrOp; - int offset; - - if (basep.getOpcode() == ISD::FrameIndex) { - // FrameIndex nodes are always properly aligned. Really. - return SDOperand(); - } - - if (basep.getOpcode() == ISD::ADD) { - const ConstantSDNode *CN = cast(basep.Val->getOperand(1)); - assert(CN != NULL - && "LowerSTORE: ISD::ADD operand 1 is not constant"); - offset = unsigned(CN->getValue()); - ptrOp = basep.getOperand(0); - DEBUG(cerr << "LowerSTORE: StoreSDNode ISD:ADD offset = " - << offset - << "\n"); - } else { - ptrOp = basep; - offset = 0; - } + int chunk_offset, slot_offset; + bool was16aligned; // The vector type we really want to load from the 16-byte chunk, except // in the case of MVT::i1, which has to be v16i8. - unsigned vecVT, stVecVT; - + unsigned vecVT, stVecVT = MVT::v16i8; + if (StVT != MVT::i1) stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT))); - else - stVecVT = MVT::v16i8; vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT))); - // Realign the pointer as a D-Form address (ptrOp is the pointer, basep is - // the actual dform addr offs($reg). - basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, ptrOp, - DAG.getConstant((offset & ~0xf), PtrVT)); - - // Create the 16-byte aligned vector load - SDOperand alignLoad = - DAG.getLoad(vecVT, the_chain, basep, - SN->getSrcValue(), SN->getSrcValueOffset(), - SN->isVolatile(), 16); - the_chain = alignLoad.getValue(1); - - LoadSDNode *LN = cast(alignLoad); + SDOperand alignLoadVec = + AlignedLoad(Op, DAG, ST, SN, alignment, + chunk_offset, slot_offset, VT, was16aligned); + + if (alignLoadVec.Val == 0) + return alignLoadVec; + + LoadSDNode *LN = cast(alignLoadVec); + SDOperand basePtr = LN->getBasePtr(); + SDOperand the_chain = alignLoadVec.getValue(1); SDOperand theValue = SN->getValue(); SDOperand result; @@ -727,18 +689,34 @@ theValue = theValue.getOperand(0); } - SDOperand insertEltOp = - DAG.getNode(SPUISD::INSERT_MASK, stVecVT, - DAG.getNode(SPUISD::DFormAddr, PtrVT, - ptrOp, - DAG.getConstant((offset & 0xf), PtrVT))); + chunk_offset &= 0xf; + chunk_offset /= (MVT::getSizeInBits(StVT == MVT::i1 ? (unsigned) MVT::i8 : StVT) / 8); + SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT); + SDOperand insertEltPtr; + SDOperand insertEltOp; + + // If the base pointer is already a D-form address, then just create + // a new D-form address with a slot offset and the orignal base pointer. + // Otherwise generate a D-form address with the slot offset relative + // to the stack pointer, which is always aligned. + if (basePtr.getOpcode() == SPUISD::DFormAddr) { + insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, + basePtr.getOperand(0), + insertEltOffs); + } else { + insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, + DAG.getRegister(SPU::R1, PtrVT), + insertEltOffs); + } + + insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr); result = DAG.getNode(SPUISD::SHUFB, vecVT, DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue), - alignLoad, + alignLoadVec, DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp)); - result = DAG.getStore(the_chain, result, basep, + result = DAG.getStore(the_chain, result, basePtr, LN->getSrcValue(), LN->getSrcValueOffset(), LN->isVolatile(), LN->getAlignment()); @@ -767,19 +745,23 @@ ConstantPoolSDNode *CP = cast(Op); Constant *C = CP->getConstVal(); SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); - const TargetMachine &TM = DAG.getTarget(); SDOperand Zero = DAG.getConstant(0, PtrVT); + const TargetMachine &TM = DAG.getTarget(); if (TM.getRelocationModel() == Reloc::Static) { if (!ST->usingLargeMem()) { // Just return the SDOperand with the constant pool address in it. return CPI; } else { +#if 1 // Generate hi/lo address pair SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero); SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero); return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi); +#else + return DAG.getNode(SPUISD::XFormAddr, PtrVT, CPI, Zero); +#endif } } @@ -797,16 +779,9 @@ const TargetMachine &TM = DAG.getTarget(); if (TM.getRelocationModel() == Reloc::Static) { - if (!ST->usingLargeMem()) { - // Just return the SDOperand with the jump table address in it. - return JTI; - } else { - // Generate hi/lo address pair - SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero); - SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero); - - return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi); - } + return (!ST->usingLargeMem() + ? JTI + : DAG.getNode(SPUISD::XFormAddr, PtrVT, JTI, Zero)); } assert(0 && @@ -820,20 +795,13 @@ GlobalAddressSDNode *GSDN = cast(Op); GlobalValue *GV = GSDN->getGlobal(); SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset()); - SDOperand Zero = DAG.getConstant(0, PtrVT); const TargetMachine &TM = DAG.getTarget(); + SDOperand Zero = DAG.getConstant(0, PtrVT); if (TM.getRelocationModel() == Reloc::Static) { - if (!ST->usingLargeMem()) { - // Generate a local store address - return GA; - } else { - // Generate hi/lo address pair - SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero); - SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero); - - return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi); - } + return (!ST->usingLargeMem() + ? GA + : DAG.getNode(SPUISD::XFormAddr, PtrVT, GA, Zero)); } else { cerr << "LowerGlobalAddress: Relocation model other than static not " << "supported.\n"; @@ -1074,7 +1042,7 @@ static SDOperand -LowerCALL(SDOperand Op, SelectionDAG &DAG) { +LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { SDOperand Chain = Op.getOperand(0); #if 0 bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; @@ -1184,25 +1152,35 @@ if (GlobalAddressSDNode *G = dyn_cast(Callee)) { GlobalValue *GV = G->getGlobal(); unsigned CalleeVT = Callee.getValueType(); + SDOperand Zero = DAG.getConstant(0, PtrVT); + SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT); - // Turn calls to targets that are defined (i.e., have bodies) into BRSL - // style calls, otherwise, external symbols are BRASL calls. - // NOTE: - // This may be an unsafe assumption for JIT and really large compilation - // units. - if (GV->isDeclaration()) { - Callee = DAG.getGlobalAddress(GV, CalleeVT); + if (!ST->usingLargeMem()) { + // Turn calls to targets that are defined (i.e., have bodies) into BRSL + // style calls, otherwise, external symbols are BRASL calls. This assumes + // that declared/defined symbols are in the same compilation unit and can + // be reached through PC-relative jumps. + // + // NOTE: + // This may be an unsafe assumption for JIT and really large compilation + // units. + if (GV->isDeclaration()) { + Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero); + } else { + Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero); + } } else { - Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, - DAG.getTargetGlobalAddress(GV, CalleeVT), - DAG.getConstant(0, PtrVT)); + // "Large memory" mode: Turn all calls into indirect calls with a X-form + // address pairs: + Callee = DAG.getNode(SPUISD::XFormAddr, PtrVT, GA, Zero); } } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType()); - else if (SDNode *Dest = isLSAAddress(Callee, DAG)) + else if (SDNode *Dest = isLSAAddress(Callee, DAG)) { // If this is an absolute destination address that appears to be a legal // local store address, use the munged value. Callee = SDOperand(Dest, 0); + } Ops.push_back(Chain); Ops.push_back(Callee); @@ -2468,7 +2446,7 @@ case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); case ISD::CALL: - return LowerCALL(Op, DAG); + return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl()); case ISD::RET: return LowerRET(Op, DAG, getTargetMachine()); Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Thu Jan 10 20:53:15 2008 @@ -31,8 +31,9 @@ Hi, ///< High address component (upper 16) Lo, ///< Low address component (lower 16) PCRelAddr, ///< Program counter relative address + AFormAddr, ///< A-form address (local store) DFormAddr, ///< D-Form address "imm($r)" - XFormAddr, ///< X-Form address "$r1($r2)" + XFormAddr, ///< X-Form address "$r($r)" LDRESULT, ///< Load result (value, chain) CALL, ///< CALL instruction Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Thu Jan 10 20:53:15 2008 @@ -158,7 +158,7 @@ def LQAr32: RI16Form<0b100001100, (outs R32C:$rT), (ins addr256k:$src), "lqa\t$rT, $src", LoadStore, - [(set R32C:$rT, (load aform_addr:$src))]>; + [(set R32C:$rT, (load aform_addr:$src))]>; def LQAf32: RI16Form<0b100001100, (outs R32FP:$rT), (ins addr256k:$src), @@ -610,6 +610,13 @@ RegConstraint<"$rS = $rT">, NoEncode<"$rS">; +def IOHLlo: + RI16Form<0b100000110, (outs R32C:$rT), (ins R32C:$rS, symbolLo:$val), + "iohl\t$rT, $val", ImmLoad, + [/* no pattern */]>, + RegConstraint<"$rS = $rT">, + NoEncode<"$rS">; + // Form select mask for bytes using immediate, used in conjunction with the // SELB instruction: @@ -2367,12 +2374,12 @@ // are used here for type checking (instances where ROTQBI is used actually // use vector registers) def ROTQBYvec: - RRForm<0b00111011100, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB), + RRForm<0b00111011100, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), "rotqby\t$rT, $rA, $rB", RotateShift, - [(set (v16i8 VECREG:$rT), (SPUrotbytes_left (v16i8 VECREG:$rA), R16C:$rB))]>; + [(set (v16i8 VECREG:$rT), (SPUrotbytes_left (v16i8 VECREG:$rA), R32C:$rB))]>; -def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R16C:$rB), - (ROTQBYvec VECREG:$rA, R16C:$rB)>; +def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R32C:$rB), + (ROTQBYvec VECREG:$rA, R32C:$rB)>; // See ROTQBY note above. def ROTQBYIvec: @@ -2720,12 +2727,12 @@ [/* no pattern to match: intrinsic */]>; def CEQBIr8: - RI10Form<0b01111110, (outs R8C:$rT), (ins R8C:$rA, s7imm:$val), + RI10Form<0b01111110, (outs R8C:$rT), (ins R8C:$rA, s7imm_i8:$val), "ceqbi\t$rT, $rA, $val", ByteOp, [/* no pattern to match: intrinsic */]>; def CEQBIv16i8: - RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, s7imm:$val), + RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, s7imm_i8:$val), "ceqbi\t$rT, $rA, $val", ByteOp, [/* no pattern to match: intrinsic */]>; @@ -2793,7 +2800,7 @@ def BRASL: BranchSetLink<0b011001100, (outs), (ins calltarget:$func, variable_ops), "brasl\t$$lr, $func", - [(SPUcall tglobaladdr:$func)]>; + [(SPUcall (SPUaform tglobaladdr:$func, 0))]>; // Branch indirect and set link if external data. These instructions are not // actually generated, matched by an intrinsic: @@ -3468,20 +3475,21 @@ // low parts in order to load them into a register. //===----------------------------------------------------------------------===// -def : Pat<(SPUhi tglobaladdr:$in, 0), (ILHUhi tglobaladdr:$in)>; -def : Pat<(SPUlo tglobaladdr:$in, 0), (ILAlo tglobaladdr:$in)>; -def : Pat<(SPUdform tglobaladdr:$in, imm:$imm), (ILAlsa tglobaladdr:$in)>; -def : Pat<(SPUhi tconstpool:$in , 0), (ILHUhi tconstpool:$in)>; -def : Pat<(SPUlo tconstpool:$in , 0), (ILAlo tconstpool:$in)>; -def : Pat<(SPUdform tconstpool:$in, imm:$imm), (ILAlsa tconstpool:$in)>; -def : Pat<(SPUhi tjumptable:$in, 0), (ILHUhi tjumptable:$in)>; -def : Pat<(SPUlo tjumptable:$in, 0), (ILAlo tjumptable:$in)>; -def : Pat<(SPUdform tjumptable:$in, imm:$imm), (ILAlsa tjumptable:$in)>; - -// Force load of global address to a register. These forms show up in -// SPUISD::DFormAddr pseudo instructions: -def : Pat<(add tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>; -def : Pat<(add tconstpool:$in, 0), (ILAlsa tglobaladdr:$in)>; -def : Pat<(add tjumptable:$in, 0), (ILAlsa tglobaladdr:$in)>; +def : Pat<(SPUhi tglobaladdr:$in, 0), (ILHUhi tglobaladdr:$in)>; +def : Pat<(SPUlo tglobaladdr:$in, 0), (ILAlo tglobaladdr:$in)>; +def : Pat<(SPUaform tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>; +def : Pat<(SPUxform tglobaladdr:$in, 0), + (IOHLlo (ILHUhi tglobaladdr:$in), tglobaladdr:$in)>; +def : Pat<(SPUhi tjumptable:$in, 0), (ILHUhi tjumptable:$in)>; +def : Pat<(SPUlo tjumptable:$in, 0), (ILAlo tjumptable:$in)>; +def : Pat<(SPUaform tjumptable:$in, 0), (ILAlsa tjumptable:$in)>; +def : Pat<(SPUxform tjumptable:$in, 0), + (IOHLlo (ILHUhi tjumptable:$in), tjumptable:$in)>; +def : Pat<(SPUhi tconstpool:$in , 0), (ILHUhi tconstpool:$in)>; +def : Pat<(SPUlo tconstpool:$in , 0), (ILAlo tconstpool:$in)>; +def : Pat<(SPUaform tconstpool:$in, 0), (ILAlsa tconstpool:$in)>; +/* def : Pat<(SPUxform tconstpool:$in, 0), + (IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>; */ + // Instrinsics: include "CellSDKIntrinsics.td" Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Thu Jan 10 20:53:15 2008 @@ -186,9 +186,15 @@ // PC-relative address def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>; +// A-Form local store addresses +def SPUaform : SDNode<"SPUISD::AFormAddr", SDTIntBinOp, []>; + // D-Form "imm($reg)" addresses def SPUdform : SDNode<"SPUISD::DFormAddr", SDTIntBinOp, []>; +// X-Form "$reg($reg)" addresses +def SPUxform : SDNode<"SPUISD::XFormAddr", SDTIntBinOp, []>; + // SPU 32-bit sign-extension to 64-bits def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>; Modified: llvm/trunk/lib/Target/CellSPU/SPUOperands.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUOperands.td?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUOperands.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUOperands.td Thu Jan 10 20:53:15 2008 @@ -140,6 +140,17 @@ return ((Value & ((1 << 19) - 1)) == Value); }]>; +def lo16 : PatLeaf<(imm), [{ + // hi16 predicate - returns true if the immediate has all zeros in the + // low order bits and is a 32-bit constant: + if (N->getValueType(0) == MVT::i32) { + uint32_t val = N->getValue(); + return ((val & 0x0000ffff) == val); + } + + return false; +}], LO16>; + def hi16 : PatLeaf<(imm), [{ // hi16 predicate - returns true if the immediate has all zeros in the // low order bits and is a 32-bit constant: @@ -411,7 +422,11 @@ //===----------------------------------------------------------------------===// // Operand Definitions. -def s7imm: Operand { +def s7imm: Operand { + let PrintMethod = "printS7ImmOperand"; +} + +def s7imm_i8: Operand { let PrintMethod = "printS7ImmOperand"; } Modified: llvm/trunk/test/CodeGen/CellSPU/and_ops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/and_ops.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/and_ops.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/and_ops.ll Thu Jan 10 20:53:15 2008 @@ -4,6 +4,8 @@ ; RUN: grep andi %t1.s | count 36 ; RUN: grep andhi %t1.s | count 30 ; RUN: grep andbi %t1.s | count 4 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" ; AND instruction generation: define <4 x i32> @and_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) { Added: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll?rev=45851&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll Thu Jan 10 20:53:15 2008 @@ -0,0 +1,29 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep bisl %t1.s | count 6 && +; RUN: grep ila %t1.s | count 1 && +; RUN: grep rotqbyi %t1.s | count 4 && +; RUN: grep lqa %t1.s | count 4 && +; RUN: grep lqd %t1.s | count 6 && +; RUN: grep dispatch_tab %t1.s | count 10 +; ModuleID = 'call_indirect.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128" +target triple = "spu-unknown-elf" + + at dispatch_tab = global [6 x void (i32, float)*] zeroinitializer, align 16 + +define void @dispatcher(i32 %i_arg, float %f_arg) { +entry: + %tmp2 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 0), align 16 + tail call void %tmp2( i32 %i_arg, float %f_arg ) + %tmp2.1 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 1), align 4 + tail call void %tmp2.1( i32 %i_arg, float %f_arg ) + %tmp2.2 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 2), align 4 + tail call void %tmp2.2( i32 %i_arg, float %f_arg ) + %tmp2.3 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 3), align 4 + tail call void %tmp2.3( i32 %i_arg, float %f_arg ) + %tmp2.4 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 4), align 4 + tail call void %tmp2.4( i32 %i_arg, float %f_arg ) + %tmp2.5 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 5), align 4 + tail call void %tmp2.5( i32 %i_arg, float %f_arg ) + ret void +} Modified: llvm/trunk/test/CodeGen/CellSPU/ctpop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/ctpop.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/ctpop.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/ctpop.ll Thu Jan 10 20:53:15 2008 @@ -3,6 +3,8 @@ ; RUN: grep andi %t1.s | count 3 && ; RUN: grep rotmi %t1.s | count 2 && ; RUN: grep rothmi %t1.s | count 1 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" declare i32 @llvm.ctpop.i8(i8) declare i32 @llvm.ctpop.i16(i16) Modified: llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll Thu Jan 10 20:53:15 2008 @@ -7,6 +7,8 @@ ; RUN: grep dfnms %t1.s | count 4 ; ; This file includes double precision floating point arithmetic instructions +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define double @fadd(double %arg1, double %arg2) { %A = add double %arg1, %arg2 Modified: llvm/trunk/test/CodeGen/CellSPU/eqv.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/eqv.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/eqv.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/eqv.ll Thu Jan 10 20:53:15 2008 @@ -10,6 +10,8 @@ ; Alternatively, a ^ ~b, which the compiler will also match. ; ModuleID = 'eqv.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define <4 x i32> @equiv_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) { %A = and <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1] Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Thu Jan 10 20:53:15 2008 @@ -5,6 +5,8 @@ ; RUN: grep lqx %t2.s | count 27 && ; RUN: grep space %t1.s | count 8 && ; RUN: grep byte %t1.s | count 424 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define i32 @i32_extract_0(<4 x i32> %v) { entry: Modified: llvm/trunk/test/CodeGen/CellSPU/fcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fcmp.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/fcmp.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/fcmp.ll Thu Jan 10 20:53:15 2008 @@ -3,6 +3,8 @@ ; RUN: grep fcmeq %t1.s | count 1 ; ; This file includes standard floating point arithmetic instructions +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" declare double @fabs(double) declare float @fabsf(float) Modified: llvm/trunk/test/CodeGen/CellSPU/fdiv.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fdiv.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/fdiv.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/fdiv.ll Thu Jan 10 20:53:15 2008 @@ -6,6 +6,8 @@ ; RUN: grep fnms %t1.s | count 2 ; ; This file includes standard floating point arithmetic instructions +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define float @fdiv32(float %arg1, float %arg2) { %A = fdiv float %arg1, %arg2 Modified: llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll Thu Jan 10 20:53:15 2008 @@ -4,6 +4,8 @@ ; RUN: grep xor %t1.s | count 4 && ; RUN: grep and %t1.s | count 5 && ; RUN: grep andbi %t1.s | count 3 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define double @fneg_dp(double %X) { %Y = sub double -0.000000e+00, %X Modified: llvm/trunk/test/CodeGen/CellSPU/immed16.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed16.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/immed16.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/immed16.ll Thu Jan 10 20:53:15 2008 @@ -1,5 +1,7 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: grep "ilh" %t1.s | count 5 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define i16 @test_1() { %x = alloca i16, align 16 Modified: llvm/trunk/test/CodeGen/CellSPU/immed32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed32.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/immed32.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/immed32.ll Thu Jan 10 20:53:15 2008 @@ -12,6 +12,8 @@ ; RUN: grep 49077 %t1.s | count 1 && ; RUN: grep 1267 %t1.s | count 2 && ; RUN: grep 16309 %t1.s | count 1 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define i32 @test_1() { ret i32 4784128 ;; ILHU via pattern (0x49000) Modified: llvm/trunk/test/CodeGen/CellSPU/immed64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed64.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/immed64.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/immed64.ll Thu Jan 10 20:53:15 2008 @@ -11,6 +11,9 @@ ; RUN: grep 128 %t1.s | count 30 && ; RUN: grep 224 %t1.s | count 2 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + ; 1311768467750121234 => 0x 12345678 abcdef12 (4660,22136/43981,61202) ; 18446744073709551591 => 0x ffffffff ffffffe7 (-25) ; 18446744073708516742 => 0x ffffffff fff03586 (-1034874) Modified: llvm/trunk/test/CodeGen/CellSPU/int2fp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/int2fp.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/int2fp.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/int2fp.ll Thu Jan 10 20:53:15 2008 @@ -7,6 +7,9 @@ ; RUN: grep andi %t1.s | count 1 && ; RUN: grep ila %t1.s | count 1 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + define float @sitofp_i32(i32 %arg1) { %A = sitofp i32 %arg1 to float ; [#uses=1] ret float %A Added: llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll?rev=45851&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll Thu Jan 10 20:53:15 2008 @@ -0,0 +1,150 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep ceq %t1.s | count 30 && +; RUN: grep ceqb %t1.s | count 10 && +; RUN: grep ceqhi %t1.s | count 5 && +; RUN: grep ceqi %t1.s | count 5 && +; RUN: grep cgt %t1.s | count 30 && +; RUN: grep cgtb %t1.s | count 10 && +; RUN: grep cgthi %t1.s | count 5 && +; RUN: grep cgti %t1.s | count 5 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +declare <4 x i32> @llvm.spu.si.shli(<4 x i32>, i8) + +declare <4 x i32> @llvm.spu.si.ceq(<4 x i32>, <4 x i32>) +declare <16 x i8> @llvm.spu.si.ceqb(<16 x i8>, <16 x i8>) +declare <8 x i16> @llvm.spu.si.ceqh(<8 x i16>, <8 x i16>) +declare <4 x i32> @llvm.spu.si.ceqi(<4 x i32>, i16) +declare <8 x i16> @llvm.spu.si.ceqhi(<8 x i16>, i16) +declare <16 x i8> @llvm.spu.si.ceqbi(<16 x i8>, i8) + +declare <4 x i32> @llvm.spu.si.cgt(<4 x i32>, <4 x i32>) +declare <16 x i8> @llvm.spu.si.cgtb(<16 x i8>, <16 x i8>) +declare <8 x i16> @llvm.spu.si.cgth(<8 x i16>, <8 x i16>) +declare <4 x i32> @llvm.spu.si.cgti(<4 x i32>, i16) +declare <8 x i16> @llvm.spu.si.cgthi(<8 x i16>, i16) +declare <16 x i8> @llvm.spu.si.cgtbi(<16 x i8>, i8) + +declare <4 x i32> @llvm.spu.si.clgt(<4 x i32>, <4 x i32>) +declare <16 x i8> @llvm.spu.si.clgtb(<16 x i8>, <16 x i8>) +declare <8 x i16> @llvm.spu.si.clgth(<8 x i16>, <8 x i16>) +declare <4 x i32> @llvm.spu.si.clgti(<4 x i32>, i16) +declare <8 x i16> @llvm.spu.si.clgthi(<8 x i16>, i16) +declare <16 x i8> @llvm.spu.si.clgtbi(<16 x i8>, i8) + + + +define <4 x i32> @test(<4 x i32> %A) { + call <4 x i32> @llvm.spu.si.shli(<4 x i32> %A, i8 3) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <4 x i32> @ceqtest(<4 x i32> %A, <4 x i32> %B) { + call <4 x i32> @llvm.spu.si.ceq(<4 x i32> %A, <4 x i32> %B) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @ceqhtest(<8 x i16> %A, <8 x i16> %B) { + call <8 x i16> @llvm.spu.si.ceqh(<8 x i16> %A, <8 x i16> %B) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} + +define <16 x i8> @ceqbtest(<16 x i8> %A, <16 x i8> %B) { + call <16 x i8> @llvm.spu.si.ceqb(<16 x i8> %A, <16 x i8> %B) + %Y = bitcast <16 x i8> %1 to <16 x i8> + ret <16 x i8> %Y +} + +define <4 x i32> @ceqitest(<4 x i32> %A) { + call <4 x i32> @llvm.spu.si.ceqi(<4 x i32> %A, i16 65) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @ceqhitest(<8 x i16> %A) { + call <8 x i16> @llvm.spu.si.ceqhi(<8 x i16> %A, i16 65) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} + +define <16 x i8> @ceqbitest(<16 x i8> %A) { + call <16 x i8> @llvm.spu.si.ceqbi(<16 x i8> %A, i8 65) + %Y = bitcast <16 x i8> %1 to <16 x i8> + ret <16 x i8> %Y +} + +define <4 x i32> @cgttest(<4 x i32> %A, <4 x i32> %B) { + call <4 x i32> @llvm.spu.si.cgt(<4 x i32> %A, <4 x i32> %B) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @cgthtest(<8 x i16> %A, <8 x i16> %B) { + call <8 x i16> @llvm.spu.si.cgth(<8 x i16> %A, <8 x i16> %B) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} + +define <16 x i8> @cgtbtest(<16 x i8> %A, <16 x i8> %B) { + call <16 x i8> @llvm.spu.si.cgtb(<16 x i8> %A, <16 x i8> %B) + %Y = bitcast <16 x i8> %1 to <16 x i8> + ret <16 x i8> %Y +} + +define <4 x i32> @cgtitest(<4 x i32> %A) { + call <4 x i32> @llvm.spu.si.cgti(<4 x i32> %A, i16 65) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @cgthitest(<8 x i16> %A) { + call <8 x i16> @llvm.spu.si.cgthi(<8 x i16> %A, i16 65) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} + +define <16 x i8> @cgtbitest(<16 x i8> %A) { + call <16 x i8> @llvm.spu.si.cgtbi(<16 x i8> %A, i8 65) + %Y = bitcast <16 x i8> %1 to <16 x i8> + ret <16 x i8> %Y +} + +define <4 x i32> @clgttest(<4 x i32> %A, <4 x i32> %B) { + call <4 x i32> @llvm.spu.si.clgt(<4 x i32> %A, <4 x i32> %B) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @clgthtest(<8 x i16> %A, <8 x i16> %B) { + call <8 x i16> @llvm.spu.si.clgth(<8 x i16> %A, <8 x i16> %B) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} + +define <16 x i8> @clgtbtest(<16 x i8> %A, <16 x i8> %B) { + call <16 x i8> @llvm.spu.si.clgtb(<16 x i8> %A, <16 x i8> %B) + %Y = bitcast <16 x i8> %1 to <16 x i8> + ret <16 x i8> %Y +} + +define <4 x i32> @clgtitest(<4 x i32> %A) { + call <4 x i32> @llvm.spu.si.clgti(<4 x i32> %A, i16 65) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @clgthitest(<8 x i16> %A) { + call <8 x i16> @llvm.spu.si.clgthi(<8 x i16> %A, i16 65) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} + +define <16 x i8> @clgtbitest(<16 x i8> %A) { + call <16 x i8> @llvm.spu.si.clgtbi(<16 x i8> %A, i8 65) + %Y = bitcast <16 x i8> %1 to <16 x i8> + ret <16 x i8> %Y +} Added: llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll?rev=45851&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll Thu Jan 10 20:53:15 2008 @@ -0,0 +1,94 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep fa %t1.s | count 5 && +; RUN: grep fs %t1.s | count 5 && +; RUN: grep fm %t1.s | count 15 && +; RUN: grep fceq %t1.s | count 5 && +; RUN: grep fcmeq %t1.s | count 5 && +; RUN: grep fcgt %t1.s | count 5 && +; RUN: grep fcmgt %t1.s | count 5 && +; RUN: grep fma %t1.s | count 5 && +; RUN: grep fnms %t1.s | count 5 && +; RUN: grep fms %t1.s | count 5 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +declare <4 x i32> @llvm.spu.si.shli(<4 x i32>, i8) + +declare <4 x float> @llvm.spu.si.fa(<4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fs(<4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fm(<4 x float>, <4 x float>) + +declare <4 x float> @llvm.spu.si.fceq(<4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fcmeq(<4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fcgt(<4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fcmgt(<4 x float>, <4 x float>) + +declare <4 x float> @llvm.spu.si.fma(<4 x float>, <4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fnms(<4 x float>, <4 x float>, <4 x float>) +declare <4 x float> @llvm.spu.si.fms(<4 x float>, <4 x float>, <4 x float>) + +define <4 x i32> @test(<4 x i32> %A) { + call <4 x i32> @llvm.spu.si.shli(<4 x i32> %A, i8 3) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <4 x float> @fatest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fa(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fstest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fs(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fmtest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fm(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fceqtest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fceq(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fcmeqtest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fcmeq(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fcgttest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fcgt(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fcmgttest(<4 x float> %A, <4 x float> %B) { + call <4 x float> @llvm.spu.si.fcmgt(<4 x float> %A, <4 x float> %B) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fmatest(<4 x float> %A, <4 x float> %B, <4 x float> %C) { + call <4 x float> @llvm.spu.si.fma(<4 x float> %A, <4 x float> %B, <4 x float> %C) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fnmstest(<4 x float> %A, <4 x float> %B, <4 x float> %C) { + call <4 x float> @llvm.spu.si.fnms(<4 x float> %A, <4 x float> %B, <4 x float> %C) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} + +define <4 x float> @fmstest(<4 x float> %A, <4 x float> %B, <4 x float> %C) { + call <4 x float> @llvm.spu.si.fms(<4 x float> %A, <4 x float> %B, <4 x float> %C) + %Y = bitcast <4 x float> %1 to <4 x float> + ret <4 x float> %Y +} \ No newline at end of file Added: llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll?rev=45851&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll Thu Jan 10 20:53:15 2008 @@ -0,0 +1,49 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep and %t1.s | count 20 && +; RUN: grep andc %t1.s | count 5 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +declare <4 x i32> @llvm.spu.si.and(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.spu.si.andc(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.spu.si.andi(<4 x i32>, i16) +declare <8 x i16> @llvm.spu.si.andhi(<8 x i16>, i16) +declare <16 x i8> @llvm.spu.si.andbi(<16 x i8>, i8) + +declare <4 x i32> @llvm.spu.si.or(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.spu.si.orc(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.spu.si.ori(<4 x i32>, i16) +declare <8 x i16> @llvm.spu.si.orhi(<8 x i16>, i16) +declare <16 x i8> @llvm.spu.si.orbi(<16 x i8>, i8) + +declare <4 x i32> @llvm.spu.si.xor(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.spu.si.xori(<4 x i32>, i16) +declare <8 x i16> @llvm.spu.si.xorhi(<8 x i16>, i16) +declare <16 x i8> @llvm.spu.si.xorbi(<16 x i8>, i8) + +declare <4 x i32> @llvm.spu.si.nand(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.spu.si.nor(<4 x i32>, <4 x i32>) + +define <4 x i32> @andtest(<4 x i32> %A, <4 x i32> %B) { + call <4 x i32> @llvm.spu.si.and(<4 x i32> %A, <4 x i32> %B) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <4 x i32> @andctest(<4 x i32> %A, <4 x i32> %B) { + call <4 x i32> @llvm.spu.si.andc(<4 x i32> %A, <4 x i32> %B) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <4 x i32> @anditest(<4 x i32> %A) { + call <4 x i32> @llvm.spu.si.andi(<4 x i32> %A, i16 65) + %Y = bitcast <4 x i32> %1 to <4 x i32> + ret <4 x i32> %Y +} + +define <8 x i16> @andhitest(<8 x i16> %A) { + call <8 x i16> @llvm.spu.si.andhi(<8 x i16> %A, i16 65) + %Y = bitcast <8 x i16> %1 to <8 x i16> + ret <8 x i16> %Y +} Modified: llvm/trunk/test/CodeGen/CellSPU/nand.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/nand.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/nand.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/nand.ll Thu Jan 10 20:53:15 2008 @@ -3,6 +3,8 @@ ; RUN: grep and %t1.s | count 94 ; RUN: grep xsbh %t1.s | count 2 ; RUN: grep xshw %t1.s | count 4 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define <4 x i32> @nand_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) { %A = and <4 x i32> %arg2, %arg1 ; <<4 x i32>> [#uses=1] Modified: llvm/trunk/test/CodeGen/CellSPU/or_ops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/or_ops.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/or_ops.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/or_ops.ll Thu Jan 10 20:53:15 2008 @@ -4,6 +4,8 @@ ; RUN: grep ori %t1.s | count 30 ; RUN: grep orhi %t1.s | count 30 ; RUN: grep orbi %t1.s | count 15 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" ; OR instruction generation: define <4 x i32> @or_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) { Modified: llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll Thu Jan 10 20:53:15 2008 @@ -8,6 +8,8 @@ ; RUN grep rothi.*,.3 %t1.s | count 1 ; RUN: grep andhi %t1.s | count 4 ; RUN: grep shlhi %t1.s | count 4 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" ; Vector rotates are not currently supported in gcc or llvm assembly. These are ; not tested. Modified: llvm/trunk/test/CodeGen/CellSPU/select_bits.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/select_bits.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/select_bits.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/select_bits.ll Thu Jan 10 20:53:15 2008 @@ -3,6 +3,8 @@ ; RUN: grep and %t1.s | count 2 ; RUN: grep xsbh %t1.s | count 1 ; RUN: grep xshw %t1.s | count 2 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define <16 x i8> @selb_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2, <16 x i8> %arg3) { %A = xor <16 x i8> %arg3, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, Modified: llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll Thu Jan 10 20:53:15 2008 @@ -5,6 +5,8 @@ ; RUN: grep shli %t1.s | count 51 ; RUN: grep xshw %t1.s | count 5 ; RUN: grep and %t1.s | count 5 +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" ; Vector shifts are not currently supported in gcc or llvm assembly. These are ; not tested. Modified: llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll?rev=45851&r1=45850&r2=45851&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll Thu Jan 10 20:53:15 2008 @@ -8,6 +8,8 @@ ; ; This file includes standard floating point arithmetic instructions ; NOTE fdiv is tested separately since it is a compound operation +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" define float @fp_add(float %arg1, float %arg2) { %A = add float %arg1, %arg2 ; [#uses=1] Added: llvm/trunk/test/CodeGen/CellSPU/struct_1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/struct_1.ll?rev=45851&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/struct_1.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/struct_1.ll Thu Jan 10 20:53:15 2008 @@ -0,0 +1,107 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep lqa %t1.s | count 10 && +; RUN: grep lqd %t1.s | count 2 && +; RUN: grep rotqbyi %t1.s | count 5 && +; RUN: grep xshw %t1.s | count 1 && +; RUN: grep andi %t1.s | count 4 && +; RUN: grep cbd %t1.s | count 3 && +; RUN: grep chd %t1.s | count 1 && +; RUN: grep cwd %t1.s | count 1 && +; RUN: grep shufb %t1.s | count 5 && +; RUN: grep stqa %t1.s | count 5 +; ModuleID = 'struct_1.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +; struct hackstate { +; unsigned char c1; // offset 0 (rotate left by 13 bytes to byte 3) +; unsigned char c2; // offset 1 (rotate left by 14 bytes to byte 3) +; unsigned char c3; // offset 2 (rotate left by 15 bytes to byte 3) +; int i1; // offset 4 (rotate left by 4 bytes to byte 0) +; short s1; // offset 8 (rotate left by 6 bytes to byte 2) +; int i2; // offset 12 [ignored] +; unsigned char c4; // offset 16 [ignored] +; unsigned char c5; // offset 17 [ignored] +; unsigned char c6; // offset 18 [ignored] +; unsigned char c7; // offset 19 (no rotate, in preferred slot) +; int i3; // offset 20 [ignored] +; int i4; // offset 24 [ignored] +; int i5; // offset 28 [ignored] +; int i6; // offset 32 (no rotate, in preferred slot) +; } +%struct.hackstate = type { i8, i8, i8, i32, i16, i32, i8, i8, i8, i8, i32, i32, i32, i32 } + +; struct hackstate state = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + at state = global %struct.hackstate zeroinitializer, align 16 + +define i8 @get_hackstate_c1() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 0), align 16 + ret i8 %tmp2 +} + +define i8 @get_hackstate_c2() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 1), align 16 + ret i8 %tmp2 +} + +define i8 @get_hackstate_c3() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 2), align 16 + ret i8 %tmp2 +} + +define i32 @get_hackstate_i1() { +entry: + %tmp2 = load i32* getelementptr (%struct.hackstate* @state, i32 0, i32 3), align 16 + ret i32 %tmp2 +} + +define i16 @get_hackstate_s1() signext { +entry: + %tmp2 = load i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 16 + ret i16 %tmp2 +} + +define i8 @get_hackstate_c7() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 9), align 16 + ret i8 %tmp2 +} + +define i32 @get_hackstate_i6() zeroext { +entry: + %tmp2 = load i32* getelementptr (%struct.hackstate* @state, i32 0, i32 13), align 16 + ret i32 %tmp2 +} + +define void @set_hackstate_c1(i8 zeroext %c) { +entry: + store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 0), align 16 + ret void +} + +define void @set_hackstate_c2(i8 zeroext %c) { +entry: + store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 1), align 16 + ret void +} + +define void @set_hackstate_c3(i8 zeroext %c) { +entry: + store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 2), align 16 + ret void +} + +define void @set_hackstate_i1(i32 %i) { +entry: + store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 3), align 16 + ret void +} + +define void @set_hackstate_s1(i16 signext %s) { +entry: + store i16 %s, i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 16 + ret void +} From evan.cheng at apple.com Thu Jan 10 21:07:46 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 03:07:46 -0000 Subject: [llvm-commits] [llvm] r45852 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200801110307.m0B37kC6018348@zion.cs.uiuc.edu> Author: evancheng Date: Thu Jan 10 21:07:46 2008 New Revision: 45852 URL: http://llvm.org/viewvc/llvm-project?rev=45852&view=rev Log: A couple of obvious off-by-one bugs. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=45852&r1=45851&r2=45852&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Thu Jan 10 21:07:46 2008 @@ -366,10 +366,11 @@ FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); const Type *RetTy = cast(I->get())->getElementType(); unsigned Idx = 1; - for (++I; I != E; ++I) { + for (++I, ++Idx; I != E; ++I, ++Idx) { if (PrintedType) FunctionInnards << ", "; - printType(FunctionInnards, *I, + const Type *ArgTy = *I; + printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ""); PrintedType = true; } @@ -1866,23 +1867,25 @@ if (!F->isDeclaration()) { if (!F->arg_empty()) { Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); + unsigned Idx = 1; // If this is a struct-return function, don't print the hidden // struct-return argument. if (isStructReturn) { assert(I != E && "Invalid struct return function!"); ++I; + ++Idx; } std::string ArgName; - unsigned Idx = 1; for (; I != E; ++I) { if (PrintedArg) FunctionInnards << ", "; if (I->hasName() || !Prototype) ArgName = GetValueName(I); else ArgName = ""; - printType(FunctionInnards, I->getType(), + const Type *ArgTy = I->getType(); + printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ArgName); PrintedArg = true; From sabre at nondot.org Fri Jan 11 00:09:31 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:09:31 -0000 Subject: [llvm-commits] [llvm] r45853 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval.ll Message-ID: <200801110609.m0B69VnM031271@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:09:30 2008 New Revision: 45853 URL: http://llvm.org/viewvc/llvm-project?rev=45853&view=rev Log: When inlining a functino with a byval argument, make an explicit copy of it in case the callee modifies the struct. Added: llvm/trunk/test/Transforms/Inline/byval.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=45853&r1=45852&r2=45853&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Fri Jan 11 00:09:30 2008 @@ -18,7 +18,9 @@ #include "llvm/Module.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" +#include "llvm/ParameterAttributes.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CallSite.h" using namespace llvm; @@ -201,7 +203,6 @@ BasicBlock *OrigBB = TheCall->getParent(); Function *Caller = OrigBB->getParent(); - // GC poses two hazards to inlining, which only occur when the callee has GC: // 1. If the caller has no GC, then the callee's GC must be propagated to the // caller. @@ -213,7 +214,6 @@ return false; } - // Get an iterator to the last basic block in the function, which will have // the new function inlined after it. // @@ -228,15 +228,66 @@ { // Scope to destroy ValueMap after cloning. DenseMap ValueMap; - // Calculate the vector of arguments to pass into the function cloner, which - // matches up the formal to the actual argument values. assert(std::distance(CalledFunc->arg_begin(), CalledFunc->arg_end()) == std::distance(CS.arg_begin(), CS.arg_end()) && "No varargs calls can be inlined!"); + + // Calculate the vector of arguments to pass into the function cloner, which + // matches up the formal to the actual argument values. CallSite::arg_iterator AI = CS.arg_begin(); + unsigned ArgNo = 0; for (Function::const_arg_iterator I = CalledFunc->arg_begin(), - E = CalledFunc->arg_end(); I != E; ++I, ++AI) - ValueMap[I] = *AI; + E = CalledFunc->arg_end(); I != E; ++I, ++AI, ++ArgNo) { + Value *ActualArg = *AI; + + // When byval arguments actually inlined, we need to make the copy implied + // by them actually explicit. + // TODO: If we know that the callee never modifies the struct, we can + // remove this copy. + if (CalledFunc->paramHasAttr(ArgNo+1, ParamAttr::ByVal)) { + const Type *AggTy = cast(I->getType())->getElementType(); + const Type *VoidPtrTy = PointerType::getUnqual(Type::Int8Ty); + + // Create the alloca. If we have TargetData, use nice alignment. + unsigned Align = 1; + if (TD) Align = TD->getPrefTypeAlignment(AggTy); + Value *NewAlloca = new AllocaInst(AggTy, 0, Align, I->getName(), + Caller->begin()->begin()); + // Emit a memcpy. + Function *MemCpyFn = Intrinsic::getDeclaration(Caller->getParent(), + Intrinsic::memcpy_i64); + Value *DestCast = new BitCastInst(NewAlloca, VoidPtrTy, "tmp", TheCall); + Value *SrcCast = new BitCastInst(*AI, VoidPtrTy, "tmp", TheCall); + + Value *Size; + if (TD == 0) + Size = ConstantExpr::getSizeOf(AggTy); + else + Size = ConstantInt::get(Type::Int64Ty, TD->getTypeStoreSize(AggTy)); + + // Always generate a memcpy of alignment 1 here because we don't know + // the alignment of the src pointer. Other optimizations can infer + // better alignment. + Value *CallArgs[] = { + DestCast, SrcCast, Size, ConstantInt::get(Type::Int32Ty, 1) + }; + CallInst *TheMemCpy = + new CallInst(MemCpyFn, CallArgs, CallArgs+4, "", TheCall); + + // If we have a call graph, update it. + if (CG) { + CallGraphNode *MemCpyCGN = CG->getOrInsertFunction(MemCpyFn); + CallGraphNode *CallerNode = (*CG)[Caller]; + CallerNode->addCalledFunction(TheMemCpy, MemCpyCGN); + } + + // Uses of the argument in the function should use our new alloca + // instead. + ActualArg = NewAlloca; + } + + ValueMap[I] = ActualArg; + } // We want the inliner to prune the code as it copies. We would LOVE to // have no dead or constant instructions leftover after inlining occurs Added: llvm/trunk/test/Transforms/Inline/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval.ll?rev=45853&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval.ll (added) +++ llvm/trunk/test/Transforms/Inline/byval.ll Fri Jan 11 00:09:30 2008 @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | opt -inline | llvm-dis | grep {llvm.memcpy} + +; Inlining a byval struct should cause an explicit copy into an alloca. + + %struct.ss = type { i32, i64 } + at .str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1] + +define internal void @f(%struct.ss* byval %b) nounwind { +entry: + %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; [#uses=2] + %tmp1 = load i32* %tmp, align 4 ; [#uses=1] + %tmp2 = add i32 %tmp1, 1 ; [#uses=1] + store i32 %tmp2, i32* %tmp, align 4 + ret void +} + +declare i32 @printf(i8*, ...) nounwind + +define i32 @main() nounwind { +entry: + %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] + %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] + store i32 1, i32* %tmp1, align 8 + %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; [#uses=1] + store i64 2, i64* %tmp4, align 4 + call void @f( %struct.ss* byval %S ) nounwind + ret i32 0 +} From sabre at nondot.org Fri Jan 11 00:17:48 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:17:48 -0000 Subject: [llvm-commits] [llvm] r45854 - /llvm/trunk/lib/Target/README.txt Message-ID: <200801110617.m0B6Hmbv031928@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:17:47 2008 New Revision: 45854 URL: http://llvm.org/viewvc/llvm-project?rev=45854&view=rev Log: add some notes. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=45854&r1=45853&r2=45854&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Fri Jan 11 00:17:47 2008 @@ -595,3 +595,21 @@ once. //===---------------------------------------------------------------------===// + +We should extend parameter attributes to capture more information about +pointer parameters for alias analysis. Some ideas: + +1. Add a "nocapture" attribute, which indicates that the callee does not store + the address of the parameter into a global or any other memory location + visible to the callee. This can be used to make basicaa and other analyses + more powerful. It is true for things like memcpy, strcat, and many other + things, including structs passed by value, most C++ references, etc. +2. Generalize readonly to be set on parameters. This is important mod/ref + info for the function, which is important for basicaa and others. It can + also be used by the inliner to avoid inserting a memcpy for byval + arguments when the function is inlined. + +These functions can be inferred by various analysis passes such as the +globalsmodrefaa pass. + +//===---------------------------------------------------------------------===// From sabre at nondot.org Fri Jan 11 00:20:50 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:20:50 -0000 Subject: [llvm-commits] [llvm] r45855 - /llvm/trunk/docs/LangRef.html Message-ID: <200801110620.m0B6KpxC032144@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:20:47 2008 New Revision: 45855 URL: http://llvm.org/viewvc/llvm-project?rev=45855&view=rev Log: document the byval parameter attribute. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=45855&r1=45854&r2=45855&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Fri Jan 11 00:20:47 2008 @@ -799,27 +799,41 @@

    zeroext
    This indicates that the parameter should be zero extended just before a call to this function.
    +
    signext
    This indicates that the parameter should be sign extended just before a call to this function.
    +
    inreg
    This indicates that the parameter should be placed in register (if possible) during assembling function call. Support for this attribute is target-specific
    + +
    byval
    +
    This indicates that the pointer parameter is really an aggregate that + was passed by value to the function. The attribute implies that a hidden + copy of the struct is made between the caller and the callee, so the + callee is unable to modify the struct in the callee. This attribute is only + valid on llvm pointer arguments.
    +
    sret
    This indicates that the parameter specifies the address of a structure that is the return value of the function in the source program.
    +
    noalias
    This indicates that the parameter not alias any other object or any other "noalias" objects during the function call. +
    noreturn
    This function attribute indicates that the function never returns. This indicates to LLVM that every call to this function should be treated as if an unreachable instruction immediately followed the call.
    +
    nounwind
    This function attribute indicates that the function type does not use the unwind instruction and does not allow stack unwinding to propagate through it.
    +
    nest
    This indicates that the parameter can be excised using the trampoline intrinsics.
    From sabre at nondot.org Fri Jan 11 00:27:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:27:42 -0000 Subject: [llvm-commits] [llvm] r45856 - /llvm/trunk/include/llvm/Analysis/LoopInfo.h Message-ID: <200801110627.m0B6RgXv032537@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:27:42 2008 New Revision: 45856 URL: http://llvm.org/viewvc/llvm-project?rev=45856&view=rev Log: Fix 80 col violations Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=45856&r1=45855&r2=45856&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Fri Jan 11 00:27:42 2008 @@ -59,17 +59,20 @@ template class LoopInfoBase; //===----------------------------------------------------------------------===// -/// LoopBase class - Instances of this class are used to represent loops that are -/// detected in the flow graph +/// LoopBase class - Instances of this class are used to represent loops that +/// are detected in the flow graph /// template class LoopBase { LoopBase *ParentLoop; - std::vector*> SubLoops; // Loops contained entirely within this one - std::vector Blocks; // First entry is the header node + // SubLoops - Loops contained entirely within this one. + std::vector*> SubLoops; + + // Blocks - The list of blocks in this loop. First entry is the header node. + std::vector Blocks; LoopBase(const LoopBase &); // DO NOT IMPLEMENT - const LoopBase &operator=(const LoopBase &); // DO NOT IMPLEMENT + const LoopBase&operator=(const LoopBase &);// DO NOT IMPLEMENT public: /// Loop ctor - This creates an empty loop. LoopBase() : ParentLoop(0) {} @@ -288,8 +291,8 @@ if (SI != BlockTraits::child_end(Out)) return 0; // Multiple exits from the block, must not be a preheader. - // If there is exactly one preheader, return it. If there was zero, then Out - // is still null. + // If there is exactly one preheader, return it. If there was zero, then + // Out is still null. return Out; } @@ -412,7 +415,7 @@ for (block_iterator BI = block_begin(), E = block_end(); BI != E; ++BI) { BlockT *BB = *BI; - for (typename BlockT::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + for (typename BlockT::iterator I = BB->begin(), E = BB->end(); I != E;++I) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { BlockT *UserBB = cast(*UI)->getParent(); @@ -421,8 +424,8 @@ UserBB = P->getIncomingBlock(OperandNo/2); } - // Check the current block, as a fast-path. Most values are used in the - // same block they are defined in. + // Check the current block, as a fast-path. Most values are used in + // the same block they are defined in. if (UserBB != BB && !LoopBBs.count(UserBB)) return false; } @@ -573,7 +576,7 @@ TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I) delete *I; // Delete all of the loops... - BBMap.clear(); // Reset internal state of analysis + BBMap.clear(); // Reset internal state of analysis TopLevelLoops.clear(); } @@ -711,19 +714,20 @@ if (!L->contains(X) && // As of yet unprocessed?? DT.dominates(EntryBlock, X)) { // X is reachable from entry block? // Check to see if this block already belongs to a loop. If this occurs - // then we have a case where a loop that is supposed to be a child of the - // current loop was processed before the current loop. When this occurs, - // this child loop gets added to a part of the current loop, making it a - // sibling to the current loop. We have to reparent this loop. + // then we have a case where a loop that is supposed to be a child of + // the current loop was processed before the current loop. When this + // occurs, this child loop gets added to a part of the current loop, + // making it a sibling to the current loop. We have to reparent this + // loop. if (LoopBase *SubLoop = const_cast*>(getLoopFor(X))) - if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)) { + if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)){ // Remove the subloop from it's current parent... assert(SubLoop->ParentLoop && SubLoop->ParentLoop != L); LoopBase *SLP = SubLoop->ParentLoop; // SubLoopParent typename std::vector*>::iterator I = std::find(SLP->SubLoops.begin(), SLP->SubLoops.end(), SubLoop); - assert(I != SLP->SubLoops.end() && "SubLoop not a child of parent?"); + assert(I != SLP->SubLoops.end() &&"SubLoop not a child of parent?"); SLP->SubLoops.erase(I); // Remove from parent... // Add the subloop to THIS loop... @@ -762,8 +766,8 @@ } // Now that we have a list of all of the child loops of this loop, check to - // see if any of them should actually be nested inside of each other. We can - // accidentally pull loops our of their parents, so we must make sure to + // see if any of them should actually be nested inside of each other. We + // can accidentally pull loops our of their parents, so we must make sure to // organize the loop nests correctly now. { std::map*> ContainingLoops; @@ -778,9 +782,9 @@ MoveSiblingLoopInto(Child, ContainingLoop); --i; // The loop got removed from the SubLoops list. } else { - // This is currently considered to be a top-level loop. Check to see if - // any of the contained blocks are loop headers for subloops we have - // already processed. + // This is currently considered to be a top-level loop. Check to see + // if any of the contained blocks are loop headers for subloops we + // have already processed. for (unsigned b = 0, e = Child->Blocks.size(); b != e; ++b) { LoopBase *&BlockLoop = ContainingLoops[Child->Blocks[b]]; if (BlockLoop == 0) { // Child block not processed yet... @@ -805,8 +809,8 @@ return L; } - /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside of - /// the NewParent Loop, instead of being a sibling of it. + /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside + /// of the NewParent Loop, instead of being a sibling of it. void MoveSiblingLoopInto(LoopBase *NewChild, LoopBase *NewParent) { LoopBase *OldParent = NewChild->getParentLoop(); @@ -815,7 +819,8 @@ // Remove NewChild from being a child of OldParent typename std::vector*>::iterator I = - std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(), NewChild); + std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(), + NewChild); assert(I != OldParent->SubLoops.end() && "Parent fields incorrect??"); OldParent->SubLoops.erase(I); // Remove from parent's subloops list NewChild->ParentLoop = 0; @@ -823,12 +828,13 @@ InsertLoopInto(NewChild, NewParent); } - /// InsertLoopInto - This inserts loop L into the specified parent loop. If the - /// parent loop contains a loop which should contain L, the loop gets inserted - /// into L instead. + /// InsertLoopInto - This inserts loop L into the specified parent loop. If + /// the parent loop contains a loop which should contain L, the loop gets + /// inserted into L instead. void InsertLoopInto(LoopBase *L, LoopBase *Parent) { BlockT *LHeader = L->getHeader(); - assert(Parent->contains(LHeader) && "This loop should not be inserted here!"); + assert(Parent->contains(LHeader) && + "This loop should not be inserted here!"); // Check to see if it belongs in a child loop... for (unsigned i = 0, e = Parent->SubLoops.size(); i != e; ++i) From sabre at nondot.org Fri Jan 11 00:29:43 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:29:43 -0000 Subject: [llvm-commits] [llvm] r45857 - /llvm/trunk/include/llvm/Analysis/LoopInfo.h Message-ID: <200801110629.m0B6ThUn000314@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:29:42 2008 New Revision: 45857 URL: http://llvm.org/viewvc/llvm-project?rev=45857&view=rev Log: Move typedef of loop to top of the file where it is more obvious. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=45857&r1=45856&r2=45857&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Fri Jan 11 00:29:42 2008 @@ -57,6 +57,9 @@ class PHINode; class Instruction; template class LoopInfoBase; +template class LoopBase; + +typedef LoopBase Loop; //===----------------------------------------------------------------------===// /// LoopBase class - Instances of this class are used to represent loops that @@ -552,8 +555,6 @@ } }; -typedef LoopBase Loop; - //===----------------------------------------------------------------------===// /// LoopInfo - This class builds and contains all of the top level loop From sabre at nondot.org Fri Jan 11 00:30:04 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:30:04 -0000 Subject: [llvm-commits] [llvm] r45858 - /llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200801110630.m0B6U4qq000360@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:30:04 2008 New Revision: 45858 URL: http://llvm.org/viewvc/llvm-project?rev=45858&view=rev Log: don't include loopinfo.h from this file. Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=45858&r1=45857&r2=45858&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Fri Jan 11 00:30:04 2008 @@ -20,7 +20,6 @@ #include #include "llvm/ADT/DenseMap.h" -#include "llvm/Analysis/LoopInfo.h" namespace llvm { @@ -37,6 +36,9 @@ class Trace; class CallGraph; class TargetData; +class LoopInfo; +template class LoopBase; +typedef LoopBase Loop; /// CloneModule - Return an exact copy of the specified module /// From duncan.sands at math.u-psud.fr Fri Jan 11 00:43:14 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Fri, 11 Jan 2008 07:43:14 +0100 Subject: [llvm-commits] [llvm] r45850 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> References: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> Message-ID: <200801110743.18251.duncan.sands@math.u-psud.fr> Hi Evan, > Allow parameter attributes on varargs function parameters. there are some issues that need to be fixed: (1) the asm parser drops parameter attributes specified on the varargs part of a call/invoke; (2) when the DAE pass drops varargs call arguments, the parameter attributes need to be trimmed, since otherwise you can have attributes that don't correspond to a call argument any more; (3) when instcombine resolves calls to a bitcast of a function into a direct call, then parameter attributes will be lost on any varargs part of a call. You need this for byval support, right? D. From sabre at nondot.org Fri Jan 11 00:59:07 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 06:59:07 -0000 Subject: [llvm-commits] [llvm] r45859 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <200801110659.m0B6x78p002236@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 00:59:07 2008 New Revision: 45859 URL: http://llvm.org/viewvc/llvm-project?rev=45859&view=rev Log: add some missing flags. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=45859&r1=45858&r2=45859&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Fri Jan 11 00:59:07 2008 @@ -300,6 +300,7 @@ //===----------------------------------------------------------------------===// // Move Instructions +let neverHasSideEffects = 1 in def MOVSSrr : SSI<0x10, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src), "movss\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in @@ -386,9 +387,11 @@ // Comparison instructions let isTwoAddress = 1 in { +let neverHasSideEffects = 1 in def CMPSSrr : SSIi8<0xC2, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src, SSECC:$cc), "cmp${cc}ss\t{$src, $dst|$dst, $src}", []>; +let neverHasSideEffects = 1, mayLoad = 1 in def CMPSSrm : SSIi8<0xC2, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1, f32mem:$src, SSECC:$cc), "cmp${cc}ss\t{$src, $dst|$dst, $src}", []>; @@ -649,6 +652,7 @@ "movaps\t{$src, $dst|$dst, $src}", [(alignedstore (v4f32 VR128:$src), addr:$dst)]>; +let neverHasSideEffects = 1 in def MOVUPSrr : PSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movups\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1 in @@ -979,6 +983,7 @@ // Move to lower bits of a VR128, leaving upper bits alone. // Three operand (but two address) aliases. let isTwoAddress = 1 in { +let neverHasSideEffects = 1 in def MOVLSS2PSrr : SSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, FR32:$src2), "movss\t{$src2, $dst|$dst, $src2}", []>; @@ -1007,6 +1012,7 @@ //===----------------------------------------------------------------------===// // Move Instructions +let neverHasSideEffects = 1 in def MOVSDrr : SDI<0x10, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src), "movsd\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in @@ -1090,10 +1096,11 @@ (load addr:$src)))]>; // Comparison instructions -let isTwoAddress = 1 in { +let isTwoAddress = 1, neverHasSideEffects = 1 in { def CMPSDrr : SDIi8<0xC2, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src, SSECC:$cc), "cmp${cc}sd\t{$src, $dst|$dst, $src}", []>; +let mayLoad = 1 in def CMPSDrm : SDIi8<0xC2, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1, f64mem:$src, SSECC:$cc), "cmp${cc}sd\t{$src, $dst|$dst, $src}", []>; @@ -1350,6 +1357,7 @@ "movapd\t{$src, $dst|$dst, $src}", [(alignedstore (v2f64 VR128:$src), addr:$dst)]>; +let neverHasSideEffects = 1 in def MOVUPDrr : PDI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movupd\t{$src, $dst|$dst, $src}", []>; let isSimpleLoad = 1 in @@ -1713,20 +1721,23 @@ // SSE integer instructions // Move Instructions +let neverHasSideEffects = 1 in def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movdqa\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1 in +let isSimpleLoad = 1, mayLoad = 1 in def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "movdqa\t{$src, $dst|$dst, $src}", [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>; +let mayStore = 1 in def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src), "movdqa\t{$src, $dst|$dst, $src}", [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>; -let isSimpleLoad = 1 in +let isSimpleLoad = 1, mayLoad = 1 in def MOVDQUrm : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "movdqu\t{$src, $dst|$dst, $src}", [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>, XS, Requires<[HasSSE2]>; +let mayStore = 1 in def MOVDQUmr : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src), "movdqu\t{$src, $dst|$dst, $src}", [/*(store (v2i64 VR128:$src), addr:$dst)*/]>, @@ -1861,7 +1872,7 @@ // PSRAQ doesn't exist in SSE[1-3]. // 128-bit logical shifts. -let isTwoAddress = 1 in { +let isTwoAddress = 1, neverHasSideEffects = 1 in { def PSLLDQri : PDIi8<0x73, MRM7r, (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2), "pslldq\t{$src2, $dst|$dst, $src2}", []>; @@ -2205,6 +2216,7 @@ // Move to lower bits of a VR128, leaving upper bits alone. // Three operand (but two address) aliases. let isTwoAddress = 1 in { + let neverHasSideEffects = 1 in def MOVLSD2PDrr : SDI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, FR64:$src2), "movsd\t{$src2, $dst|$dst, $src2}", []>; From sabre at nondot.org Fri Jan 11 01:18:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 07:18:17 -0000 Subject: [llvm-commits] [llvm] r45860 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrFPStack.td X86InstrInfo.td Message-ID: <200801110718.m0B7IHqY003241@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 01:18:17 2008 New Revision: 45860 URL: http://llvm.org/viewvc/llvm-project?rev=45860&view=rev Log: more flags set right Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=45860&r1=45859&r2=45860&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Fri Jan 11 01:18:17 2008 @@ -526,6 +526,7 @@ def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), "shl{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>; +let neverHasSideEffects = 1 in def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1), "shl{q}\t$dst", []>; } // isTwoAddress Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=45860&r1=45859&r2=45860&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Fri Jan 11 01:18:17 2008 @@ -166,6 +166,7 @@ FpI_, Requires<[FPStackf64]>; // Register copies. Just copies, the shortening ones do not truncate. +let neverHasSideEffects = 1 in { def MOV_Fp3232 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src), SpecialFP, []>; def MOV_Fp3264 : FpIf32<(outs RFP64:$dst), (ins RFP32:$src), SpecialFP, []>; def MOV_Fp6432 : FpIf32<(outs RFP32:$dst), (ins RFP64:$src), SpecialFP, []>; @@ -175,6 +176,7 @@ def MOV_Fp8064 : FpIf64<(outs RFP64:$dst), (ins RFP80:$src), SpecialFP, []>; def MOV_Fp6480 : FpIf64<(outs RFP80:$dst), (ins RFP64:$src), SpecialFP, []>; def MOV_Fp8080 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), SpecialFP, []>; +} // Factoring for arithmetic. multiclass FPBinary_rr { @@ -293,12 +295,11 @@ defm SIN : FPUnary; defm COS : FPUnary; -def TST_Fp32 : FpIf32<(outs), (ins RFP32:$src), OneArgFP, - []>; -def TST_Fp64 : FpIf64<(outs), (ins RFP64:$src), OneArgFP, - []>; -def TST_Fp80 : FpI_<(outs), (ins RFP80:$src), OneArgFP, - []>; +let neverHasSideEffects = 1 in { +def TST_Fp32 : FpIf32<(outs), (ins RFP32:$src), OneArgFP, []>; +def TST_Fp64 : FpIf64<(outs), (ins RFP64:$src), OneArgFP, []>; +def TST_Fp80 : FpI_<(outs), (ins RFP80:$src), OneArgFP, []>; +} def TST_F : FPI<0xE4, RawFrm, (outs), (ins), "ftst">, D9; // Floating point cmovs. @@ -392,7 +393,7 @@ [(truncstoref64 RFP80:$src, addr:$op)]>; // FST does not support 80-bit memory target; FSTP must be used. -let mayStore = 1 in { +let mayStore = 1, neverHasSideEffects = 1 in { def ST_FpP32m : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, []>; def ST_FpP64m32 : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>; def ST_FpP64m : FpIf64<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>; @@ -401,7 +402,7 @@ } def ST_FpP80m : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP, [(store RFP80:$src, addr:$op)]>; -let mayStore = 1 in { +let mayStore = 1, neverHasSideEffects = 1 in { def IST_Fp16m32 : FpIf32<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>; def IST_Fp32m32 : FpIf32<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>; def IST_Fp64m32 : FpIf32<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>; @@ -498,17 +499,18 @@ // Floating point compares. let Defs = [EFLAGS] in { def UCOM_Fpr32 : FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, - []>; // FPSW = cmp ST(0) with ST(i) + []>; // FPSW = cmp ST(0) with ST(i) +def UCOM_Fpr64 : FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, + []>; // FPSW = cmp ST(0) with ST(i) +def UCOM_Fpr80 : FpI_ <(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, + []>; // FPSW = cmp ST(0) with ST(i) + def UCOM_FpIr32: FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, [(X86cmp RFP32:$lhs, RFP32:$rhs), (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) -def UCOM_Fpr64 : FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, - []>; // FPSW = cmp ST(0) with ST(i) def UCOM_FpIr64: FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, [(X86cmp RFP64:$lhs, RFP64:$rhs), (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) -def UCOM_Fpr80 : FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, - []>; // FPSW = cmp ST(0) with ST(i) def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, [(X86cmp RFP80:$lhs, RFP80:$rhs), (implicit EFLAGS)]>; // CC = ST(0) cmp ST(i) Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45860&r1=45859&r2=45860&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Fri Jan 11 01:18:17 2008 @@ -419,6 +419,7 @@ [(set GR32:$dst, (bswap GR32:$src))]>, TB; // FIXME: Model xchg* as two address instructions? +let neverHasSideEffects = 1 in { def XCHG8rr : I<0x86, MRMDestReg, // xchg GR8, GR8 (outs), (ins GR8:$src1, GR8:$src2), "xchg{b}\t{$src2|$src1}, {$src1|$src2}", []>; @@ -428,7 +429,9 @@ def XCHG32rr : I<0x87, MRMDestReg, // xchg GR32, GR32 (outs), (ins GR32:$src1, GR32:$src2), "xchg{l}\t{$src2|$src1}, {$src1|$src2}", []>; +} +let mayLoad = 1, mayStore = 1 in { def XCHG8mr : I<0x86, MRMDestMem, (outs), (ins i8mem:$src1, GR8:$src2), "xchg{b}\t{$src2|$src1}, {$src1|$src2}", []>; @@ -447,6 +450,7 @@ def XCHG32rm : I<0x87, MRMSrcMem, (outs), (ins GR32:$src1, i32mem:$src2), "xchg{l}\t{$src2|$src1}, {$src1|$src2}", []>; +} // Bit scan instructions. let Defs = [EFLAGS] in { @@ -621,10 +625,10 @@ // This probably ought to be moved to a def : Pat<> if the // syntax can be accepted. [(set AL, (mul AL, GR8:$src))]>; // AL,AH = AL*GR8 -let Defs = [AX,DX,EFLAGS], Uses = [AX] in +let Defs = [AX,DX,EFLAGS], Uses = [AX], neverHasSideEffects = 1 in def MUL16r : I<0xF7, MRM4r, (outs), (ins GR16:$src), "mul{w}\t$src", []>, OpSize; // AX,DX = AX*GR16 -let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in +let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], neverHasSideEffects = 1 in def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src), "mul{l}\t$src", []>; // EAX,EDX = EAX*GR32 let Defs = [AL,AH,EFLAGS], Uses = [AL] in @@ -1416,12 +1420,14 @@ } // Shift left by one. Not used because (add x, x) is slightly cheaper. +let neverHasSideEffects = 1 in { def SHL8r1 : I<0xD0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1), "shl{b}\t$dst", []>; def SHL16r1 : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1), "shl{w}\t$dst", []>, OpSize; def SHL32r1 : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1), "shl{l}\t$dst", []>; +} let isTwoAddress = 0 in { let Uses = [CL] in { From evan.cheng at apple.com Fri Jan 11 01:37:44 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 07:37:44 -0000 Subject: [llvm-commits] [llvm] r45861 - /llvm/trunk/lib/Target/X86/X86Instr64bit.td Message-ID: <200801110737.m0B7bjHl004203@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 01:37:44 2008 New Revision: 45861 URL: http://llvm.org/viewvc/llvm-project?rev=45861&view=rev Log: Rename Int_CVTSI642SSr* to Int_CVTSI2SS64r* for naming consistency and remove unused instructions. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=45861&r1=45860&r2=45861&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Fri Jan 11 01:37:44 2008 @@ -1028,6 +1028,7 @@ def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src), "cvtsi2sd{q}\t{$src, $dst|$dst, $src}", [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>; + let isTwoAddress = 1 in { def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), @@ -1050,17 +1051,21 @@ def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src), "cvtsi2ss{q}\t{$src, $dst|$dst, $src}", [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>; -let isTwoAddress = 1, neverHasSideEffects = 1 in { -def Int_CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - []>; // TODO: add intrinsic -let mayLoad = 1 in -def Int_CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - []>; // TODO: add intrinsic -} // isTwoAddress + +let isTwoAddress = 1 in { + def Int_CVTSI2SS64rr : RSSI<0x2A, MRMSrcReg, + (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), + "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", + [(set VR128:$dst, + (int_x86_sse_cvtsi642ss VR128:$src1, + GR64:$src2))]>; + def Int_CVTSI2SS64rm : RSSI<0x2A, MRMSrcMem, + (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), + "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", + [(set VR128:$dst, + (int_x86_sse_cvtsi642ss VR128:$src1, + (loadi64 addr:$src2)))]>; +} // f32 -> signed i64 def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src), @@ -1086,21 +1091,6 @@ [(set GR64:$dst, (int_x86_sse_cvttss2si64 (load addr:$src)))]>; -let isTwoAddress = 1 in { - def Int_CVTSI642SSrr : RSSI<0x2A, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, GR64:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (int_x86_sse_cvtsi642ss VR128:$src1, - GR64:$src2))]>; - def Int_CVTSI642SSrm : RSSI<0x2A, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2), - "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (int_x86_sse_cvtsi642ss VR128:$src1, - (loadi64 addr:$src2)))]>; -} - //===----------------------------------------------------------------------===// // Alias Instructions //===----------------------------------------------------------------------===// From evan.cheng at apple.com Fri Jan 11 01:45:36 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 23:45:36 -0800 Subject: [llvm-commits] [llvm] r45850 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <200801110743.18251.duncan.sands@math.u-psud.fr> References: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> <200801110743.18251.duncan.sands@math.u-psud.fr> Message-ID: <1859DD11-2B75-4134-A90A-E5345473F774@apple.com> On Jan 10, 2008, at 10:43 PM, Duncan Sands wrote: > Hi Evan, > >> Allow parameter attributes on varargs function parameters. > > there are some issues that need to be fixed: > (1) the asm parser drops parameter attributes specified on the varargs > part of a call/invoke; > (2) when the DAE pass drops varargs call arguments, the parameter > attributes need to be trimmed, since otherwise you can have attributes > that don't correspond to a call argument any more; > (3) when instcombine resolves calls to a bitcast of a function into > a direct call, then parameter attributes will be lost on any varargs > part of a call. > > You need this for byval support, right? Yep. Evan > > D. From evan.cheng at apple.com Fri Jan 11 01:47:33 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Jan 2008 23:47:33 -0800 Subject: [llvm-commits] [llvm] r45848 - in /llvm/trunk/lib/Target: PowerPC/PPCAsmPrinter.cpp PowerPC/PPCTargetAsmInfo.cpp X86/X86AsmPrinter.cpp X86/X86TargetAsmInfo.cpp In-Reply-To: <2FE904A5-A393-4732-BEB6-19773297B70C@apple.com> References: <200801110054.m0B0sbeH009251@zion.cs.uiuc.edu> <2FE904A5-A393-4732-BEB6-19773297B70C@apple.com> Message-ID: <45EEB101-AFB7-4DC5-985A-9C50E2741C98@apple.com> Thanks! Evan On Jan 10, 2008, at 5:10 PM, Dale Johannesen wrote: > > On Jan 10, 2008, at 4:59 PM, Evan Cheng wrote: > >> How about ARM? >> >> Evan > > Hadn't thought of that, but yeah, I should make the substantiative > changes there too. > >> On Jan 10, 2008, at 4:54 PM, Dale Johannesen wrote: >> >>> Author: johannes >>> Date: Thu Jan 10 18:54:37 2008 >>> New Revision: 45848 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=45848&view=rev >>> Log: >>> Weak things initialized to 0 don't go in bss on Darwin. >>> Cosmetic changes to spacing to match gcc (some dejagnu >>> tests actually care). >>> >>> >>> Modified: >>> llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp >>> llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp >>> llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp >>> llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp >>> >>> Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >>> PowerPC/PPCAsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> = >>> --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) >>> +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Jan 10 >>> 18:54:37 2008 >>> @@ -767,7 +767,7 @@ >>> case Function::InternalLinkage: return TAI->getTextSection(); >>> case Function::WeakLinkage: >>> case Function::LinkOnceLinkage: >>> - return ".section >>> __TEXT,__textcoal_nt,coalesced,pure_instructions"; >>> + return "\t.section >>> __TEXT,__textcoal_nt,coalesced,pure_instructions"; >>> } >>> } >>> >>> @@ -869,13 +869,13 @@ >>> >>> // Prime text sections so they are adjacent. This reduces the >>> likelihood a >>> // large data or debug section causes a branch to exceed 16M limit. >>> - SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced," >>> + SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced," >>> "pure_instructions"); >>> if (TM.getRelocationModel() == Reloc::PIC_) { >>> - SwitchToTextSection(".section >>> __TEXT,__picsymbolstub1,symbol_stubs," >>> + SwitchToTextSection("\t.section >>> __TEXT,__picsymbolstub1,symbol_stubs," >>> "pure_instructions,32"); >>> } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { >>> - SwitchToTextSection(".section >>> __TEXT,__symbol_stub1,symbol_stubs," >>> + SwitchToTextSection("\t.section >>> __TEXT,__symbol_stub1,symbol_stubs," >>> "pure_instructions,16"); >>> } >>> SwitchToTextSection(TAI->getTextSection()); >>> @@ -917,8 +917,7 @@ >>> >>> if (C->isNullValue() && /* FIXME: Verify correct */ >>> !I->hasSection() && >>> - (I->hasInternalLinkage() || I->hasWeakLinkage() || >>> - I->hasLinkOnceLinkage() || I->hasExternalLinkage())) { >>> + (I->hasInternalLinkage() || I->hasExternalLinkage())) { >>> if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid >>> it. >>> if (I->hasExternalLinkage()) { >>> O << "\t.globl " << name << '\n'; >>> @@ -941,7 +940,7 @@ >>> case GlobalValue::WeakLinkage: >>> O << "\t.globl " << name << '\n' >>> << "\t.weak_definition " << name << '\n'; >>> - SwitchToDataSection(".section >>> __DATA,__datacoal_nt,coalesced", I); >>> + SwitchToDataSection("\t.section >>> __DATA,__datacoal_nt,coalesced", I); >>> break; >>> case GlobalValue::AppendingLinkage: >>> // FIXME: appending linkage variables should go into a >>> section of >>> @@ -1008,7 +1007,7 @@ >>> if (TM.getRelocationModel() == Reloc::PIC_) { >>> for (std::set::iterator i = FnStubs.begin(), e = >>> FnStubs.end(); >>> i != e; ++i) { >>> - SwitchToTextSection(".section >>> __TEXT,__picsymbolstub1,symbol_stubs," >>> + SwitchToTextSection("\t.section >>> __TEXT,__picsymbolstub1,symbol_stubs," >>> "pure_instructions,32"); >>> EmitAlignment(4); >>> O << "L" << *i << "$stub:\n"; >>> @@ -1036,7 +1035,7 @@ >>> } else { >>> for (std::set::iterator i = FnStubs.begin(), e = >>> FnStubs.end(); >>> i != e; ++i) { >>> - SwitchToTextSection(".section >>> __TEXT,__symbol_stub1,symbol_stubs," >>> + SwitchToTextSection("\t.section >>> __TEXT,__symbol_stub1,symbol_stubs," >>> "pure_instructions,16"); >>> EmitAlignment(4); >>> O << "L" << *i << "$stub:\n"; >>> >>> Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >>> PowerPC/PPCTargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> = >>> --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) >>> +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Thu Jan 10 >>> 18:54:37 2008 >>> @@ -53,7 +53,7 @@ >>> UsedDirective = "\t.no_dead_strip\t"; >>> WeakDefDirective = "\t.weak_definition "; >>> WeakRefDirective = "\t.weak_reference "; >>> - HiddenDirective = "\t.private_extern\t"; >>> + HiddenDirective = "\t.private_extern "; >>> SupportsExceptionHandling = true; >>> NeedsIndirectEncoding = true; >>> NeedsSet = true; >>> >>> Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >>> X86/X86AsmPrinter.cpp?rev=45848&r1=45847&r2=45848&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> = >>> --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) >>> +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Thu Jan 10 18:54:37 >>> 2008 >>> @@ -173,7 +173,7 @@ >>> if (C->isNullValue() && !I->hasSection()) { >>> if (I->hasExternalLinkage()) { >>> if (const char *Directive = TAI->getZeroFillDirective()) { >>> - O << "\t.globl\t" << name << "\n"; >>> + O << "\t.globl " << name << "\n"; >>> O << Directive << "__DATA__, __common, " << name << ", " >>> << Size << ", " << Align << "\n"; >>> continue; >>> @@ -181,8 +181,9 @@ >>> } >>> >>> if (!I->isThreadLocal() && >>> - (I->hasInternalLinkage() || I->hasWeakLinkage() || >>> - I->hasLinkOnceLinkage())) { >>> + (I->hasInternalLinkage() || >>> + (!Subtarget->isTargetDarwin() && >>> + (I->hasWeakLinkage() || I->hasLinkOnceLinkage())))) { >>> if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, >>> avoid it. >>> if (!NoZerosInBSS && TAI->getBSSSection()) >>> SwitchToDataSection(TAI->getBSSSection(), I); >>> @@ -218,9 +219,9 @@ >>> case GlobalValue::LinkOnceLinkage: >>> case GlobalValue::WeakLinkage: >>> if (Subtarget->isTargetDarwin()) { >>> - O << "\t.globl\t" << name << "\n" >>> + O << "\t.globl " << name << "\n" >>> << TAI->getWeakDefDirective() << name << "\n"; >>> - SwitchToDataSection(".section >>> __DATA,__const_coal,coalesced", I); >>> + SwitchToDataSection("\t.section >>> __DATA,__datacoal_nt,coalesced", I); >>> } else if (Subtarget->isTargetCygMing()) { >>> std::string SectionName(".section\t.data$linkonce." + >>> name + >>> @@ -244,7 +245,7 @@ >>> // their name or something. For now, just emit them as >>> external. >>> case GlobalValue::ExternalLinkage: >>> // If external or appending, declare as a global symbol >>> - O << "\t.globl\t" << name << "\n"; >>> + O << "\t.globl " << name << "\n"; >>> // FALL THROUGH >>> case GlobalValue::InternalLinkage: { >>> if (I->isConstant()) { >>> @@ -348,7 +349,7 @@ >>> unsigned j = 1; >>> for (std::set::iterator i = FnStubs.begin(), e = >>> FnStubs.end(); >>> i != e; ++i, ++j) { >>> - SwitchToDataSection(".section >>> __IMPORT,__jump_table,symbol_stubs," >>> + SwitchToDataSection("\t.section >>> __IMPORT,__jump_table,symbol_stubs," >>> "self_modifying_code+pure_instructions,5", >>> 0); >>> O << "L" << *i << "$stub:\n"; >>> O << "\t.indirect_symbol " << *i << "\n"; >>> @@ -369,7 +370,7 @@ >>> // Output stubs for external and common global variables. >>> if (!GVStubs.empty()) >>> SwitchToDataSection( >>> - ".section >>> __IMPORT,__pointers,non_lazy_symbol_pointers"); >>> + "\t.section >>> __IMPORT,__pointers,non_lazy_symbol_pointers"); >>> for (std::set::iterator i = GVStubs.begin(), e = >>> GVStubs.end(); >>> i != e; ++i) { >>> O << "L" << *i << "$non_lazy_ptr:\n"; >>> >>> Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ >>> X86/X86TargetAsmInfo.cpp?rev=45848&r1=45847&r2=45848&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> = >>> --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) >>> +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Thu Jan 10 >>> 18:54:37 2008 >>> @@ -78,7 +78,7 @@ >>> UsedDirective = "\t.no_dead_strip\t"; >>> WeakDefDirective = "\t.weak_definition "; >>> WeakRefDirective = "\t.weak_reference "; >>> - HiddenDirective = "\t.private_extern\t"; >>> + HiddenDirective = "\t.private_extern "; >>> >>> // In non-PIC modes, emit a special label before jump tables so >>> that the >>> // linker can perform more accurate dead code stripping. >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Fri Jan 11 02:32:55 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 11 Jan 2008 08:32:55 -0000 Subject: [llvm-commits] [llvm] r45862 - /llvm/tags/Apple/llvmCore-2007/ Message-ID: <200801110832.m0B8WtP6008758@zion.cs.uiuc.edu> Author: void Date: Fri Jan 11 02:32:54 2008 New Revision: 45862 URL: http://llvm.org/viewvc/llvm-project?rev=45862&view=rev Log: Creating llvmCore-2007 branch Added: llvm/tags/Apple/llvmCore-2007/ - copied from r45861, llvm/trunk/ From isanbard at gmail.com Fri Jan 11 02:35:19 2008 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 11 Jan 2008 08:35:19 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45863 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2007/ Message-ID: <200801110835.m0B8ZJkq010470@zion.cs.uiuc.edu> Author: void Date: Fri Jan 11 02:35:19 2008 New Revision: 45863 URL: http://llvm.org/viewvc/llvm-project?rev=45863&view=rev Log: Creating llvmgcc42-2007 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2007/ - copied from r45862, llvm-gcc-4.2/trunk/ From evan.cheng at apple.com Fri Jan 11 03:00:28 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 01:00:28 -0800 Subject: [llvm-commits] [llvm] r45850 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <200801110743.18251.duncan.sands@math.u-psud.fr> References: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> <200801110743.18251.duncan.sands@math.u-psud.fr> Message-ID: <9469634B-E333-4F3A-A6F9-AEAB7DAC4B34@apple.com> One more. When llvm-extract remove a function with byval parameters, it also drops the attribute. Just in case you are interested. :-) If you don't get to it soon, I'll hack on it tomorrow. Thanks, Evan On Jan 10, 2008, at 10:43 PM, Duncan Sands wrote: > Hi Evan, > >> Allow parameter attributes on varargs function parameters. > > there are some issues that need to be fixed: > (1) the asm parser drops parameter attributes specified on the varargs > part of a call/invoke; > (2) when the DAE pass drops varargs call arguments, the parameter > attributes need to be trimmed, since otherwise you can have attributes > that don't correspond to a call argument any more; > (3) when instcombine resolves calls to a bitcast of a function into > a direct call, then parameter attributes will be lost on any varargs > part of a call. > > You need this for byval support, right? > > D. From evan.cheng at apple.com Fri Jan 11 03:12:49 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 09:12:49 -0000 Subject: [llvm-commits] [llvm] r45864 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200801110912.m0B9Cn2V018122@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 03:12:49 2008 New Revision: 45864 URL: http://llvm.org/viewvc/llvm-project?rev=45864&view=rev Log: Some C backend ByVal parameter attribute support. Not yet complete. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=45864&r1=45863&r2=45864&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Fri Jan 11 03:12:49 2008 @@ -87,6 +87,7 @@ std::map TypeNames; std::map FPConstantMap; std::set intrinsicPrototypesAlreadyGenerated; + std::set ByValParams; public: static char ID; @@ -113,14 +114,16 @@ printFloatingPointConstants(F); printFunction(F); - FPConstantMap.clear(); return false; } virtual bool doFinalization(Module &M) { // Free memory... delete Mang; + FPConstantMap.clear(); TypeNames.clear(); + intrinsicPrototypesAlreadyGenerated.clear(); + ByValParams.clear(); return false; } @@ -370,6 +373,10 @@ if (PrintedType) FunctionInnards << ", "; const Type *ArgTy = *I; + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa(ArgTy)); + ArgTy = cast(ArgTy)->getElementType(); + } printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ""); PrintedType = true; @@ -1885,6 +1892,12 @@ else ArgName = ""; const Type *ArgTy = I->getType(); + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa(ArgTy)); + ArgTy = cast(ArgTy)->getElementType(); + const Value *Arg = &(*I); + ByValParams.insert(Arg); + } printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ArgName); @@ -2384,6 +2397,13 @@ // Make sure we really get a sext from bool by subtracing the bool from 0 Out << "0-"; } + // If it's a byval parameter being casted, then takes its address. + bool isByVal = ByValParams.count(I.getOperand(0)); + if (isByVal) { + assert(I.getOpcode() == Instruction::BitCast && + "ByVal aggregate parameter must ptr type"); + Out << '&'; + } writeOperand(I.getOperand(0)); if (DstTy == Type::Int1Ty && (I.getOpcode() == Instruction::Trunc || @@ -2675,7 +2695,12 @@ /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt)); Out << ')'; } - writeOperand(*AI); + // If call is expecting argument to be passed by value, then do not + // take its address. + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) + writeOperandInternal(*AI); + else + writeOperand(*AI); PrintedArg = true; } Out << ')'; @@ -2869,7 +2894,9 @@ // Print out the -> operator if possible... if (TmpI != E && isa(*TmpI)) { - Out << (HasImplicitAddress ? "." : "->"); + // Check if it's actually an aggregate parameter passed by value. + bool isByVal = ByValParams.count(Ptr); + Out << ((HasImplicitAddress || isByVal) ? "." : "->"); Out << "field" << cast(TmpI.getOperand())->getZExtValue(); I = ++TmpI; } From arnold.schwaighofer at gmail.com Fri Jan 11 08:34:57 2008 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 11 Jan 2008 14:34:57 -0000 Subject: [llvm-commits] [llvm] r45865 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801111434.m0BEYvMn003099@zion.cs.uiuc.edu> Author: arnolds Date: Fri Jan 11 08:34:56 2008 New Revision: 45865 URL: http://llvm.org/viewvc/llvm-project?rev=45865&view=rev Log: Correct a copy and paste error. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45865&r1=45864&r2=45865&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 11 08:34:56 2008 @@ -1441,7 +1441,7 @@ if (!MemOpChains2.empty()) Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, - &MemOpChains2[0], MemOpChains.size()); + &MemOpChains2[0], MemOpChains2.size()); // Store the return address to the appropriate stack slot. if (FPDiff) From arnold.schwaighofer at gmail.com Fri Jan 11 10:49:44 2008 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 11 Jan 2008 16:49:44 -0000 Subject: [llvm-commits] [llvm] r45867 - in /llvm/trunk/lib/Target/X86: README.txt X86ISelLowering.cpp Message-ID: <200801111649.m0BGnib2013499@zion.cs.uiuc.edu> Author: arnolds Date: Fri Jan 11 10:49:42 2008 New Revision: 45867 URL: http://llvm.org/viewvc/llvm-project?rev=45867&view=rev Log: Improve tail call optimized call's argument lowering. Before this commit all arguments where moved to the stack slot where they would reside on a normal function call before the lowering to the tail call stack slot. This was done to prevent arguments overwriting each other. Now only arguments sourcing from a FORMAL_ARGUMENTS node or a CopyFromReg node with virtual register (could also be a caller's argument) are lowered indirectly. --This line, and those below, will be ignored-- M X86/X86ISelLowering.cpp M X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=45867&r1=45866&r2=45867&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Fri Jan 11 10:49:42 2008 @@ -1330,10 +1330,11 @@ Tail call optimization improvements: Tail call optimization currently pushes all arguments on the top of the stack (their normal place for -non-tail call optimized calls) before moving them to actual stack -slot. This is done to prevent overwriting of parameters (see example -below) that might be used, since the arguments of the callee -overwrites caller's arguments. +non-tail call optimized calls) that source from the callers arguments +or that source from a virtual register (also possibly sourcing from +callers arguments). +This is done to prevent overwriting of parameters (see example +below) that might be used later. example: @@ -1352,13 +1353,6 @@ Possible optimizations: - - Only push those arguments to the top of the stack that are actual - parameters of the caller function and have no local value in the - caller. - - In the above example local does not need to be pushed onto the top - of the stack as it is definitely not a caller's function - parameter. - Analyse the actual parameters of the callee to see which would overwrite a caller parameter which is used by the callee and only @@ -1380,35 +1374,6 @@ Here we need to push the arguments because they overwrite each other. - - Code for lowering directly onto callers arguments: -+ SmallVector, 8> RegsToPass; -+ SmallVector MemOpChains; -+ -+ SDOperand FramePtr; -+ SDOperand PtrOff; -+ SDOperand FIN; -+ int FI = 0; -+ // Walk the register/memloc assignments, inserting copies/loads. -+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { -+ CCValAssign &VA = ArgLocs[i]; -+ SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); -+ -+ .... -+ -+ if (VA.isRegLoc()) { -+ RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); -+ } else { -+ assert(VA.isMemLoc()); -+ // create frame index -+ int32_t Offset = VA.getLocMemOffset()+FPDiff; -+ uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; -+ FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); -+ FIN = DAG.getFrameIndex(FI, MVT::i32); -+ // store relative to framepointer -+ MemOpChains.push_back(DAG.getStore(Chain, Arg, FIN, NULL, 0)); -+ } -+ } //===---------------------------------------------------------------------===// main () Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45867&r1=45866&r2=45867&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 11 10:49:42 2008 @@ -1007,6 +1007,45 @@ return None; } + +// IsPossiblyOverriddenArgumentOfTailCall - Check if the operand could possibly +// be overridden when lowering the outgoing arguments in a tail call. Currently +// the implementation of this call is very conservative and assumes all +// arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with virtual +// registers would be overridden by direct lowering. +// Possible improvement: +// Check FORMAL_ARGUMENTS corresponding MERGE_VALUES for CopyFromReg nodes +// indicating inreg passed arguments which also need not be lowered to a safe +// stack slot. +static bool IsPossiblyOverriddenArgumentOfTailCall(SDOperand Op) { + RegisterSDNode * OpReg = NULL; + if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS || + (Op.getOpcode()== ISD::CopyFromReg && + (OpReg = cast(Op.getOperand(1))) && + OpReg->getReg() >= MRegisterInfo::FirstVirtualRegister)) + return true; + return false; +} + +// GetMemCpyWithFlags - Create a MemCpy using function's parameter flag. +static SDOperand +GetMemCpyWithFlags(SelectionDAG &DAG, unsigned Flags, SDOperand From, + SDOperand To, SDOperand Chain) { + + unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> + ISD::ParamFlags::ByValAlignOffs); + + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> + ISD::ParamFlags::ByValSizeOffs; + + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); + SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32); + + return DAG.getMemcpy(Chain, To, From, SizeNode, AlignNode, + AlwaysInline); +} + SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG, const CCValAssign &VA, MachineFrameInfo *MFI, @@ -1221,18 +1260,7 @@ SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); unsigned Flags = cast(FlagsOp)->getValue(); if (Flags & ISD::ParamFlags::ByVal) { - unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> - ISD::ParamFlags::ByValAlignOffs); - - unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> - ISD::ParamFlags::ByValSizeOffs; - - SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); - SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); - SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32); - - return DAG.getMemcpy(Chain, PtrOff, Arg, SizeNode, AlignNode, - AlwaysInline); + return GetMemCpyWithFlags(DAG, Flags, Arg, PtrOff, Chain); } else { return DAG.getStore(Chain, Arg, PtrOff, NULL, 0); } @@ -1306,9 +1334,9 @@ SDOperand StackPtr; - // Walk the register/memloc assignments, inserting copies/loads. - // For tail calls, lower arguments first to the stack slot where they would - // normally - in case of a normal function call - be. + // Walk the register/memloc assignments, inserting copies/loads. For tail + // calls, lower arguments which could otherwise be possibly overwritten to the + // stack slot where they would go on normal function calls. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); @@ -1331,12 +1359,14 @@ if (VA.isRegLoc()) { RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); } else { - assert(VA.isMemLoc()); - if (StackPtr.Val == 0) - StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); - - MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain, - Arg)); + if (!IsTailCall || IsPossiblyOverriddenArgumentOfTailCall(Arg)) { + assert(VA.isMemLoc()); + if (StackPtr.Val == 0) + StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); + + MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain, + Arg)); + } } } @@ -1390,52 +1420,45 @@ InFlag = Chain.getValue(1); } - // Copy from stack slots to stack slot of a tail called function. This needs - // to be done because if we would lower the arguments directly to their real - // stack slot we might end up overwriting each other. - // TODO: To make this more efficient (sometimes saving a store/load) we could - // analyse the arguments and emit this store/load/store sequence only for - // arguments which would be overwritten otherwise. + // For tail calls lower the arguments to the 'real' stack slot. if (IsTailCall) { SmallVector MemOpChains2; - SDOperand PtrOff; SDOperand FIN; int FI = 0; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; if (!VA.isRegLoc()) { + assert(VA.isMemLoc()); + SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); unsigned Flags = cast(FlagsOp)->getValue(); - - // Get source stack slot. - SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), - getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); // Create frame index. int32_t Offset = VA.getLocMemOffset()+FPDiff; uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); FIN = DAG.getFrameIndex(FI, MVT::i32); - if (Flags & ISD::ParamFlags::ByVal) { - // Copy relative to framepointer. - unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> - ISD::ParamFlags::ByValAlignOffs); - - unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> - ISD::ParamFlags::ByValSizeOffs; - - SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); - SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); - SDOperand AlwaysInline = DAG.getConstant(1, MVT::i1); + SDOperand Source = Arg; + if (IsPossiblyOverriddenArgumentOfTailCall(Arg)){ + // Copy from stack slots to stack slot of a tail called function. This + // needs to be done because if we would lower the arguments directly + // to their real stack slot we might end up overwriting each other. + // Get source stack slot. + Source = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); + if (StackPtr.Val == 0) + StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); + Source = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, Source); + if ((Flags & ISD::ParamFlags::ByVal)==0) + Source = DAG.getLoad(VA.getValVT(), Chain, Source,NULL, 0); + } - MemOpChains2.push_back(DAG.getMemcpy(Chain, FIN, PtrOff, SizeNode, - AlignNode,AlwaysInline)); + if (Flags & ISD::ParamFlags::ByVal) { + // Copy relative to framepointer. + MemOpChains2. + push_back(GetMemCpyWithFlags(DAG, Flags, Source, FIN, Chain)); } else { - SDOperand LoadedArg = DAG.getLoad(VA.getValVT(), Chain, PtrOff, - NULL, 0); - // Store relative to framepointer. - MemOpChains2.push_back(DAG.getStore(Chain, LoadedArg, FIN, NULL, 0)); - } + // Store relative to framepointer. + MemOpChains2.push_back(DAG.getStore(Chain, Source, FIN, NULL, 0)); + } } } From arnold.schwaighofer at gmail.com Fri Jan 11 11:10:15 2008 From: arnold.schwaighofer at gmail.com (Arnold Schwaighofer) Date: Fri, 11 Jan 2008 17:10:15 -0000 Subject: [llvm-commits] [llvm] r45868 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801111710.m0BHAFF4014648@zion.cs.uiuc.edu> Author: arnolds Date: Fri Jan 11 11:10:15 2008 New Revision: 45868 URL: http://llvm.org/viewvc/llvm-project?rev=45868&view=rev Log: hrm - correct spelling. Actually were not riding any arguments. Sadly there is no semantic spell checker that is going to safe you from such a mistake. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45868&r1=45867&r2=45868&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 11 11:10:15 2008 @@ -1008,16 +1008,16 @@ } -// IsPossiblyOverriddenArgumentOfTailCall - Check if the operand could possibly -// be overridden when lowering the outgoing arguments in a tail call. Currently +// IsPossiblyOverwrittenArgumentOfTailCall - Check if the operand could possibly +// be overwritten when lowering the outgoing arguments in a tail call. Currently // the implementation of this call is very conservative and assumes all // arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with virtual -// registers would be overridden by direct lowering. +// registers would be overwritten by direct lowering. // Possible improvement: // Check FORMAL_ARGUMENTS corresponding MERGE_VALUES for CopyFromReg nodes // indicating inreg passed arguments which also need not be lowered to a safe // stack slot. -static bool IsPossiblyOverriddenArgumentOfTailCall(SDOperand Op) { +static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op) { RegisterSDNode * OpReg = NULL; if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS || (Op.getOpcode()== ISD::CopyFromReg && @@ -1359,7 +1359,7 @@ if (VA.isRegLoc()) { RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); } else { - if (!IsTailCall || IsPossiblyOverriddenArgumentOfTailCall(Arg)) { + if (!IsTailCall || IsPossiblyOverwrittenArgumentOfTailCall(Arg)) { assert(VA.isMemLoc()); if (StackPtr.Val == 0) StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); @@ -1438,7 +1438,7 @@ FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); FIN = DAG.getFrameIndex(FI, MVT::i32); SDOperand Source = Arg; - if (IsPossiblyOverriddenArgumentOfTailCall(Arg)){ + if (IsPossiblyOverwrittenArgumentOfTailCall(Arg)){ // Copy from stack slots to stack slot of a tail called function. This // needs to be done because if we would lower the arguments directly // to their real stack slot we might end up overwriting each other. From sabre at nondot.org Fri Jan 11 12:00:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:00:14 -0000 Subject: [llvm-commits] [llvm] r45869 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200801111800.m0BI0Ex7017262@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:00:13 2008 New Revision: 45869 URL: http://llvm.org/viewvc/llvm-project?rev=45869&view=rev Log: add a note, remove a done deed. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=45869&r1=45868&r2=45869&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Fri Jan 11 12:00:13 2008 @@ -998,24 +998,6 @@ //===---------------------------------------------------------------------===// -For code like: -phi (undef, x) - -We get an implicit def on the undef side. If the phi is spilled, we then get: -implicitdef xmm1 -store xmm1 -> stack - -It should be possible to teach the x86 backend to "fold" the store into the -implicitdef, which just deletes the implicit def. - -These instructions should go away: -#IMPLICIT_DEF %xmm1 -movaps %xmm1, 192(%esp) -movaps %xmm1, 224(%esp) -movaps %xmm1, 176(%esp) - -//===---------------------------------------------------------------------===// - This is a "commutable two-address" register coallescing deficiency: define <4 x float> @test1(<4 x float> %V) { @@ -1510,6 +1492,9 @@ if the flags of the xor are dead. +Likewise, we isel "x<<1" into "add reg,reg". If reg is spilled, this should +be folded into: shl [mem], 1 + //===---------------------------------------------------------------------===// This testcase misses a read/modify/write opportunity (from PR1425): From sabre at nondot.org Fri Jan 11 12:00:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:00:51 -0000 Subject: [llvm-commits] [llvm] r45870 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.cpp X86InstrInfo.td Message-ID: <200801111800.m0BI0p9X017304@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:00:50 2008 New Revision: 45870 URL: http://llvm.org/viewvc/llvm-project?rev=45870&view=rev Log: remove xchg and shift-reg-by-1 instructions, which are dead. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=45870&r1=45869&r2=45870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Fri Jan 11 12:00:50 2008 @@ -161,17 +161,6 @@ def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src), "bswap{q}\t$dst", [(set GR64:$dst, (bswap GR64:$src))]>, TB; -// Exchange -let neverHasSideEffects = 1 in { -def XCHG64rr : RI<0x87, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), - "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; -let mayLoad = 1, mayStore = 1 in { -def XCHG64mr : RI<0x87, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), - "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG64rm : RI<0x87, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), - "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>; -} -} // Bit scan instructions. let Defs = [EFLAGS] in { @@ -526,9 +515,8 @@ def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2), "shl{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>; -let neverHasSideEffects = 1 in -def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1), - "shl{q}\t$dst", []>; +// NOTE: We don't use shifts of a register by one, because 'add reg,reg' is +// cheaper. } // isTwoAddress let Uses = [CL] in Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45870&r1=45869&r2=45870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Jan 11 12:00:50 2008 @@ -145,16 +145,12 @@ { X86::SBB64ri32, X86::SBB64mi32 }, { X86::SBB64ri8, X86::SBB64mi8 }, { X86::SBB64rr, X86::SBB64mr }, - { X86::SHL16r1, X86::SHL16m1 }, { X86::SHL16rCL, X86::SHL16mCL }, { X86::SHL16ri, X86::SHL16mi }, - { X86::SHL32r1, X86::SHL32m1 }, { X86::SHL32rCL, X86::SHL32mCL }, { X86::SHL32ri, X86::SHL32mi }, - { X86::SHL64r1, X86::SHL64m1 }, { X86::SHL64rCL, X86::SHL64mCL }, { X86::SHL64ri, X86::SHL64mi }, - { X86::SHL8r1, X86::SHL8m1 }, { X86::SHL8rCL, X86::SHL8mCL }, { X86::SHL8ri, X86::SHL8mi }, { X86::SHLD16rrCL, X86::SHLD16mrCL }, @@ -286,11 +282,7 @@ { X86::TEST16ri, X86::TEST16mi, 1 }, { X86::TEST32ri, X86::TEST32mi, 1 }, { X86::TEST64ri32, X86::TEST64mi32, 1 }, - { X86::TEST8ri, X86::TEST8mi, 1 }, - { X86::XCHG16rr, X86::XCHG16mr, 0 }, - { X86::XCHG32rr, X86::XCHG32mr, 0 }, - { X86::XCHG64rr, X86::XCHG64mr, 0 }, - { X86::XCHG8rr, X86::XCHG8mr, 0 } + { X86::TEST8ri, X86::TEST8mi, 1 } }; for (unsigned i = 0, e = array_lengthof(OpTbl0); i != e; ++i) { @@ -417,11 +409,7 @@ { X86::TEST8rr, X86::TEST8rm }, // FIXME: TEST*rr EAX,EAX ---> CMP [mem], 0 { X86::UCOMISDrr, X86::UCOMISDrm }, - { X86::UCOMISSrr, X86::UCOMISSrm }, - { X86::XCHG16rr, X86::XCHG16rm }, - { X86::XCHG32rr, X86::XCHG32rm }, - { X86::XCHG64rr, X86::XCHG64rm }, - { X86::XCHG8rr, X86::XCHG8rm } + { X86::UCOMISSrr, X86::UCOMISSrm } }; for (unsigned i = 0, e = array_lengthof(OpTbl1); i != e; ++i) { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45870&r1=45869&r2=45870&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Fri Jan 11 12:00:50 2008 @@ -418,39 +418,6 @@ "bswap{l}\t$dst", [(set GR32:$dst, (bswap GR32:$src))]>, TB; -// FIXME: Model xchg* as two address instructions? -let neverHasSideEffects = 1 in { -def XCHG8rr : I<0x86, MRMDestReg, // xchg GR8, GR8 - (outs), (ins GR8:$src1, GR8:$src2), - "xchg{b}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG16rr : I<0x87, MRMDestReg, // xchg GR16, GR16 - (outs), (ins GR16:$src1, GR16:$src2), - "xchg{w}\t{$src2|$src1}, {$src1|$src2}", []>, OpSize; -def XCHG32rr : I<0x87, MRMDestReg, // xchg GR32, GR32 - (outs), (ins GR32:$src1, GR32:$src2), - "xchg{l}\t{$src2|$src1}, {$src1|$src2}", []>; -} - -let mayLoad = 1, mayStore = 1 in { -def XCHG8mr : I<0x86, MRMDestMem, - (outs), (ins i8mem:$src1, GR8:$src2), - "xchg{b}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG16mr : I<0x87, MRMDestMem, - (outs), (ins i16mem:$src1, GR16:$src2), - "xchg{w}\t{$src2|$src1}, {$src1|$src2}", []>, OpSize; -def XCHG32mr : I<0x87, MRMDestMem, - (outs), (ins i32mem:$src1, GR32:$src2), - "xchg{l}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG8rm : I<0x86, MRMSrcMem, - (outs), (ins GR8:$src1, i8mem:$src2), - "xchg{b}\t{$src2|$src1}, {$src1|$src2}", []>; -def XCHG16rm : I<0x87, MRMSrcMem, - (outs), (ins GR16:$src1, i16mem:$src2), - "xchg{w}\t{$src2|$src1}, {$src1|$src2}", []>, OpSize; -def XCHG32rm : I<0x87, MRMSrcMem, - (outs), (ins GR32:$src1, i32mem:$src2), - "xchg{l}\t{$src2|$src1}, {$src1|$src2}", []>; -} // Bit scan instructions. let Defs = [EFLAGS] in { @@ -1417,16 +1384,8 @@ def SHL32ri : Ii8<0xC1, MRM4r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2), "shl{l}\t{$src2, $dst|$dst, $src2}", [(set GR32:$dst, (shl GR32:$src1, (i8 imm:$src2)))]>; -} - -// Shift left by one. Not used because (add x, x) is slightly cheaper. -let neverHasSideEffects = 1 in { -def SHL8r1 : I<0xD0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1), - "shl{b}\t$dst", []>; -def SHL16r1 : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1), - "shl{w}\t$dst", []>, OpSize; -def SHL32r1 : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1), - "shl{l}\t$dst", []>; +// NOTE: We don't use shifts of a register by one, because 'add reg,reg' is +// cheaper. } let isTwoAddress = 0 in { From sabre at nondot.org Fri Jan 11 12:10:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:10:51 -0000 Subject: [llvm-commits] [llvm] r45871 - in /llvm/trunk: include/llvm/CodeGen/MachineInstr.h lib/Target/ARM/ARMConstantIslandPass.cpp lib/Target/ARM/ARMInstrInfo.cpp lib/Target/ARM/ARMLoadStoreOptimizer.cpp lib/Target/ARM/ARMRegisterInfo.cpp lib/Target/Alpha/AlphaBranchSelector.cpp lib/Target/PowerPC/PPCRegisterInfo.cpp lib/Target/Sparc/FPMover.cpp lib/Target/X86/X86FloatingPoint.cpp lib/Target/X86/X86InstrInfo.cpp Message-ID: <200801111810.m0BIApEu017798@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:10:50 2008 New Revision: 45871 URL: http://llvm.org/viewvc/llvm-project?rev=45871&view=rev Log: rename MachineInstr::setInstrDescriptor -> setDesc Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp llvm/trunk/lib/Target/Alpha/AlphaBranchSelector.cpp llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/Sparc/FPMover.cpp llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Fri Jan 11 12:10:50 2008 @@ -163,10 +163,10 @@ /// (before the first implicit operand). void addOperand(const MachineOperand &Op); - /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of + /// setDesc - Replace the instruction descriptor (thus opcode) of /// the current instruction with a new one. /// - void setInstrDescriptor(const TargetInstrDesc &tid) { TID = &tid; } + void setDesc(const TargetInstrDesc &tid) { TID = &tid; } /// RemoveOperand - Erase an operand from an instruction, leaving it with one /// fewer operand than it started with. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Fri Jan 11 12:10:50 2008 @@ -1162,7 +1162,7 @@ // Use BL to implement far jump. Br.MaxDisp = (1 << 21) * 2; - MI->setInstrDescriptor(TII->get(ARM::tBfar)); + MI->setDesc(TII->get(ARM::tBfar)); BBSizes[MBB->getNumber()] += 2; AdjustBBOffsetsAfter(MBB, 2); HasFarJump = true; Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Fri Jan 11 12:10:50 2008 @@ -635,7 +635,7 @@ if (isVarArg) continue; Reg = ARM::PC; - PopMI->setInstrDescriptor(get(ARM::tPOP_RET)); + PopMI->setDesc(get(ARM::tPOP_RET)); MBB.erase(MI); } PopMI->addOperand(MachineOperand::CreateReg(Reg, true)); @@ -792,7 +792,7 @@ const std::vector &Pred) const { unsigned Opc = MI->getOpcode(); if (Opc == ARM::B || Opc == ARM::tB) { - MI->setInstrDescriptor(get(Opc == ARM::B ? ARM::Bcc : ARM::tBcc)); + MI->setDesc(get(Opc == ARM::B ? ARM::Bcc : ARM::tBcc)); MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm())); MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false)); return true; Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Fri Jan 11 12:10:50 2008 @@ -741,7 +741,7 @@ if (PrevMI->getOpcode() == ARM::LDM) { MachineOperand &MO = PrevMI->getOperand(PrevMI->getNumOperands()-1); if (MO.getReg() == ARM::LR) { - PrevMI->setInstrDescriptor(TII->get(ARM::LDM_RET)); + PrevMI->setDesc(TII->get(ARM::LDM_RET)); MO.setReg(ARM::PC); MBB.erase(MBBI); return true; Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Fri Jan 11 12:10:50 2008 @@ -589,14 +589,14 @@ Offset += MI.getOperand(i+1).getImm(); if (Offset == 0) { // Turn it into a move. - MI.setInstrDescriptor(TII.get(ARM::MOVr)); + MI.setDesc(TII.get(ARM::MOVr)); MI.getOperand(i).ChangeToRegister(FrameReg, false); MI.RemoveOperand(i+1); return; } else if (Offset < 0) { Offset = -Offset; isSub = true; - MI.setInstrDescriptor(TII.get(ARM::SUBri)); + MI.setDesc(TII.get(ARM::SUBri)); } // Common case: small offset, fits into instruction. @@ -629,7 +629,7 @@ unsigned Scale = 1; if (FrameReg != ARM::SP) { Opcode = ARM::tADDi3; - MI.setInstrDescriptor(TII.get(ARM::tADDi3)); + MI.setDesc(TII.get(ARM::tADDi3)); NumBits = 3; } else { NumBits = 8; @@ -640,7 +640,7 @@ if (Offset == 0) { // Turn it into a move. - MI.setInstrDescriptor(TII.get(ARM::tMOVr)); + MI.setDesc(TII.get(ARM::tMOVr)); MI.getOperand(i).ChangeToRegister(FrameReg, false); MI.RemoveOperand(i+1); return; @@ -680,7 +680,7 @@ // r0 = -imm (this is then translated into a series of instructons) // r0 = add r0, sp emitThumbConstant(MBB, II, DestReg, Offset, TII, *this); - MI.setInstrDescriptor(TII.get(ARM::tADDhirr)); + MI.setDesc(TII.get(ARM::tADDhirr)); MI.getOperand(i).ChangeToRegister(DestReg, false, false, true); MI.getOperand(i+1).ChangeToRegister(FrameReg, false); } @@ -790,7 +790,7 @@ } } else emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, *this); - MI.setInstrDescriptor(TII.get(ARM::tLDR)); + MI.setDesc(TII.get(ARM::tLDR)); MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); if (UseRR) // Use [reg, reg] addrmode. @@ -827,7 +827,7 @@ } } else emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, *this); - MI.setInstrDescriptor(TII.get(ARM::tSTR)); + MI.setDesc(TII.get(ARM::tSTR)); MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); if (UseRR) // Use [reg, reg] addrmode. MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); Modified: llvm/trunk/lib/Target/Alpha/AlphaBranchSelector.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaBranchSelector.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaBranchSelector.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaBranchSelector.cpp Fri Jan 11 12:10:50 2008 @@ -57,7 +57,7 @@ // 1. reg // 2. target MBB const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); - MBBI->setInstrDescriptor(TII->get(MBBI->getOperand(0).getImm())); + MBBI->setDesc(TII->get(MBBI->getOperand(0).getImm())); } } } Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Fri Jan 11 12:10:50 2008 @@ -501,7 +501,7 @@ assert(ImmToIdxMap.count(OpC) && "No indexed form of load or store available!"); unsigned NewOpcode = ImmToIdxMap.find(OpC)->second; - MI.setInstrDescriptor(TII.get(NewOpcode)); + MI.setDesc(TII.get(NewOpcode)); OperandBase = 1; } else { OperandBase = OffsetOperandNo; Modified: llvm/trunk/lib/Target/Sparc/FPMover.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/FPMover.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/FPMover.cpp (original) +++ llvm/trunk/lib/Target/Sparc/FPMover.cpp Fri Jan 11 12:10:50 2008 @@ -101,11 +101,11 @@ const TargetInstrInfo *TII = TM.getInstrInfo(); if (MI->getOpcode() == SP::FpMOVD) - MI->setInstrDescriptor(TII->get(SP::FMOVS)); + MI->setDesc(TII->get(SP::FMOVS)); else if (MI->getOpcode() == SP::FpNEGD) - MI->setInstrDescriptor(TII->get(SP::FNEGS)); + MI->setDesc(TII->get(SP::FNEGS)); else if (MI->getOpcode() == SP::FpABSD) - MI->setInstrDescriptor(TII->get(SP::FABSS)); + MI->setDesc(TII->get(SP::FABSS)); else assert(0 && "Unknown opcode!"); Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Fri Jan 11 12:10:50 2008 @@ -535,7 +535,7 @@ // Check to see if there is a popping version of this instruction... int Opcode = Lookup(PopTable, array_lengthof(PopTable), I->getOpcode()); if (Opcode != -1) { - I->setInstrDescriptor(TII->get(Opcode)); + I->setDesc(TII->get(Opcode)); if (Opcode == X86::UCOM_FPPr) I->RemoveOperand(0); } else { // Insert an explicit pop @@ -587,7 +587,7 @@ // Change from the pseudo instruction to the concrete instruction. MI->RemoveOperand(0); // Remove the explicit ST(0) operand - MI->setInstrDescriptor(TII->get(getConcreteOpcode(MI->getOpcode()))); + MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode()))); // Result gets pushed on the stack. pushReg(DestReg); @@ -632,7 +632,7 @@ // Convert from the pseudo instruction to the concrete instruction. MI->RemoveOperand(NumOps-1); // Remove explicit ST(0) operand - MI->setInstrDescriptor(TII->get(getConcreteOpcode(MI->getOpcode()))); + MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode()))); if (MI->getOpcode() == X86::IST_FP64m || MI->getOpcode() == X86::ISTT_FP16m || @@ -680,7 +680,7 @@ // Change from the pseudo instruction to the concrete instruction. MI->RemoveOperand(1); // Drop the source operand. MI->RemoveOperand(0); // Drop the destination operand. - MI->setInstrDescriptor(TII->get(getConcreteOpcode(MI->getOpcode()))); + MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode()))); } @@ -878,7 +878,7 @@ // Change from the pseudo instruction to the concrete instruction. MI->getOperand(0).setReg(getSTReg(Op1)); MI->RemoveOperand(1); - MI->setInstrDescriptor(TII->get(getConcreteOpcode(MI->getOpcode()))); + MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode()))); // If any of the operands are killed by this instruction, free them. if (KillsOp0) freeStackSlotAfter(I, Op0); @@ -904,7 +904,7 @@ MI->RemoveOperand(0); MI->RemoveOperand(1); MI->getOperand(0).setReg(getSTReg(Op1)); - MI->setInstrDescriptor(TII->get(getConcreteOpcode(MI->getOpcode()))); + MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode()))); // If we kill the second operand, make sure to pop it from the stack. if (Op0 != Op1 && KillsOp1) { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45871&r1=45870&r2=45871&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Jan 11 12:10:50 2008 @@ -1156,7 +1156,7 @@ case X86::CMOVNP64rr: Opc = X86::CMOVP64rr; break; } - MI->setInstrDescriptor(get(Opc)); + MI->setDesc(get(Opc)); // Fallthrough intended. } default: @@ -1755,7 +1755,7 @@ case X86::TEST64rr: NewOpc = X86::CMP64ri32; break; } // Change to CMPXXri r, 0 first. - MI->setInstrDescriptor(get(NewOpc)); + MI->setDesc(get(NewOpc)); MI->getOperand(1).ChangeToImmediate(0); } else if (Ops.size() != 1) return NULL; @@ -1781,7 +1781,7 @@ case X86::TEST64rr: NewOpc = X86::CMP64ri32; break; } // Change to CMPXXri r, 0 first. - MI->setInstrDescriptor(get(NewOpc)); + MI->setDesc(get(NewOpc)); MI->getOperand(1).ChangeToImmediate(0); } else if (Ops.size() != 1) return NULL; @@ -1936,7 +1936,7 @@ case X86::CMP16ri: NewOpc = X86::TEST16rr; break; case X86::CMP8ri: NewOpc = X86::TEST8rr; break; } - DataMI->setInstrDescriptor(get(NewOpc)); + DataMI->setDesc(get(NewOpc)); MO1.ChangeToRegister(MO0.getReg(), false); } } From clattner at apple.com Fri Jan 11 12:14:50 2008 From: clattner at apple.com (Chris Lattner) Date: Fri, 11 Jan 2008 10:14:50 -0800 Subject: [llvm-commits] [llvm] r45850 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <1859DD11-2B75-4134-A90A-E5345473F774@apple.com> References: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> <200801110743.18251.duncan.sands@math.u-psud.fr> <1859DD11-2B75-4134-A90A-E5345473F774@apple.com> Message-ID: On Jan 10, 2008, at 11:45 PM, Evan Cheng wrote: > > On Jan 10, 2008, at 10:43 PM, Duncan Sands wrote: > >> Hi Evan, >> >>> Allow parameter attributes on varargs function parameters. >> >> there are some issues that need to be fixed: >> (1) the asm parser drops parameter attributes specified on the >> varargs >> part of a call/invoke; >> (2) when the DAE pass drops varargs call arguments, the parameter >> attributes need to be trimmed, since otherwise you can have >> attributes >> that don't correspond to a call argument any more; >> (3) when instcombine resolves calls to a bitcast of a function into >> a direct call, then parameter attributes will be lost on any varargs >> part of a call. >> >> You need this for byval support, right? > > Yep. Evan, if you send me a testcase for the DAE problem, I'll fix it. I'm taking a look at argpromote now to see if it needs to be tweaked. -Chris From sabre at nondot.org Fri Jan 11 12:42:02 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:42:02 -0000 Subject: [llvm-commits] [llvm] r45872 - /llvm/trunk/include/llvm/ADT/SmallVector.h Message-ID: <200801111842.m0BIg3wu019290@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:42:02 2008 New Revision: 45872 URL: http://llvm.org/viewvc/llvm-project?rev=45872&view=rev Log: add operator==/!= to smallvector. Modified: llvm/trunk/include/llvm/ADT/SmallVector.h Modified: llvm/trunk/include/llvm/ADT/SmallVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallVector.h?rev=45872&r1=45871&r2=45872&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SmallVector.h (original) +++ llvm/trunk/include/llvm/ADT/SmallVector.h Fri Jan 11 12:42:02 2008 @@ -294,6 +294,16 @@ const SmallVectorImpl &operator=(const SmallVectorImpl &RHS); + bool operator==(const SmallVectorImpl &RHS) const { + if (size() != RHS.size()) return false; + for (T *This = Begin, *That = RHS.Begin, *End = Begin+size(); + This != End; ++This, ++That) + if (*This != *That) + return false; + return true; + } + bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); } + private: /// isSmall - Return true if this is a smallvector which has not had dynamic /// memory allocated for it. From sabre at nondot.org Fri Jan 11 12:43:58 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:43:58 -0000 Subject: [llvm-commits] [llvm] r45873 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801111843.m0BIhxVG019366@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:43:58 2008 New Revision: 45873 URL: http://llvm.org/viewvc/llvm-project?rev=45873&view=rev Log: start using smallvector to avoid vector heap thrashing. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45873&r1=45872&r2=45873&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 12:43:58 2008 @@ -70,7 +70,8 @@ private: bool PromoteArguments(CallGraphNode *CGN); bool isSafeToPromoteArgument(Argument *Arg) const; - Function *DoPromotion(Function *F, std::vector &ArgsToPromote); + Function *DoPromotion(Function *F, + SmallVectorImpl &ArgsToPromote); }; char ArgPromotion::ID = 0; @@ -108,7 +109,7 @@ if (!F || !F->hasInternalLinkage()) return false; // First check: see if there are any pointer arguments! If not, quick exit. - std::vector PointerArgs; + SmallVector PointerArgs; for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) if (isa(I->getType())) PointerArgs.push_back(I); @@ -193,8 +194,8 @@ // instructions (with constant indices) that are subsequently loaded. bool HasLoadInEntryBlock = false; BasicBlock *EntryBlock = Arg->getParent()->begin(); - std::vector Loads; - std::vector > GEPIndices; + SmallVector Loads; + std::vector > GEPIndices; for (Value::use_iterator UI = Arg->use_begin(), E = Arg->use_end(); UI != E; ++UI) if (LoadInst *LI = dyn_cast(*UI)) { @@ -210,7 +211,7 @@ return isSafeToPromoteArgument(Arg); } // Ensure that all of the indices are constants. - std::vector Operands; + SmallVector Operands; for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) if (ConstantInt *C = dyn_cast(GEP->getOperand(i))) Operands.push_back(C); @@ -326,7 +327,7 @@ /// arguments, and returns the new function. At this point, we know that it's /// safe to do so. Function *ArgPromotion::DoPromotion(Function *F, - std::vector &Args2Prom) { + SmallVectorImpl &Args2Prom) { std::set ArgsToPromote(Args2Prom.begin(), Args2Prom.end()); // Start by computing a new prototype for the function, which is the same as From sabre at nondot.org Fri Jan 11 12:47:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:47:46 -0000 Subject: [llvm-commits] [llvm] r45874 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801111847.m0BIlkpY019497@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:47:45 2008 New Revision: 45874 URL: http://llvm.org/viewvc/llvm-project?rev=45874&view=rev Log: another minor datastructure tweak. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45874&r1=45873&r2=45874&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 12:47:45 2008 @@ -328,7 +328,7 @@ /// safe to do so. Function *ArgPromotion::DoPromotion(Function *F, SmallVectorImpl &Args2Prom) { - std::set ArgsToPromote(Args2Prom.begin(), Args2Prom.end()); + SmallPtrSet ArgsToPromote(Args2Prom.begin(), Args2Prom.end()); // Start by computing a new prototype for the function, which is the same as // the old function, but has modified arguments. From sabre at nondot.org Fri Jan 11 12:55:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 18:55:10 -0000 Subject: [llvm-commits] [llvm] r45875 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801111855.m0BItA55019831@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 12:55:10 2008 New Revision: 45875 URL: http://llvm.org/viewvc/llvm-project?rev=45875&view=rev Log: replace a loop with a constant time check. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45875&r1=45874&r2=45875&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 12:55:10 2008 @@ -125,9 +125,8 @@ // Ensure that this call site is CALLING the function, not passing it as // an argument. - for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); - AI != E; ++AI) - if (*AI == F) return false; // Passing the function address in! + if (UI.getOperandNo() != 0) + return false; } // Check to see which arguments are promotable. If an argument is not From sabre at nondot.org Fri Jan 11 13:20:40 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 19:20:40 -0000 Subject: [llvm-commits] [llvm] r45876 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801111920.m0BJKeBS020935@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 13:20:39 2008 New Revision: 45876 URL: http://llvm.org/viewvc/llvm-project?rev=45876&view=rev Log: Update this code to use eraseFromParent where possible. Compute whether an argument is byval and pass into isSafeToPromoteArgument. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45876&r1=45875&r2=45876&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 13:20:39 2008 @@ -69,9 +69,9 @@ private: bool PromoteArguments(CallGraphNode *CGN); - bool isSafeToPromoteArgument(Argument *Arg) const; + bool isSafeToPromoteArgument(Argument *Arg, bool isByVal) const; Function *DoPromotion(Function *F, - SmallVectorImpl &ArgsToPromote); + SmallPtrSet &ArgsToPromote); }; char ArgPromotion::ID = 0; @@ -109,10 +109,12 @@ if (!F || !F->hasInternalLinkage()) return false; // First check: see if there are any pointer arguments! If not, quick exit. - SmallVector PointerArgs; - for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) + SmallVector, 16> PointerArgs; + unsigned ArgNo = 0; + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); + I != E; ++I, ++ArgNo) if (isa(I->getType())) - PointerArgs.push_back(I); + PointerArgs.push_back(std::pair(I, ArgNo)); if (PointerArgs.empty()) return false; // Second check: make sure that all callers are direct callers. We can't @@ -129,19 +131,19 @@ return false; } - // Check to see which arguments are promotable. If an argument is not - // promotable, remove it from the PointerArgs vector. - for (unsigned i = 0; i != PointerArgs.size(); ++i) - if (!isSafeToPromoteArgument(PointerArgs[i])) { - std::swap(PointerArgs[i--], PointerArgs.back()); - PointerArgs.pop_back(); - } - + // Check to see which arguments are promotable. If an argument is promotable, + // add it to ArgsToPromote. + SmallPtrSet ArgsToPromote; + for (unsigned i = 0; i != PointerArgs.size(); ++i) { + bool isByVal = F->paramHasAttr(PointerArgs[i].second, ParamAttr::ByVal); + if (isSafeToPromoteArgument(PointerArgs[i].first, isByVal)) + ArgsToPromote.insert(PointerArgs[i].first); + } + // No promotable pointer arguments. - if (PointerArgs.empty()) return false; + if (ArgsToPromote.empty()) return false; - // Okay, promote all of the arguments and rewrite the callees! - Function *NewF = DoPromotion(F, PointerArgs); + Function *NewF = DoPromotion(F, ArgsToPromote); // Update the call graph to know that the function has been transformed. getAnalysis().changeFunction(F, NewF); @@ -188,7 +190,7 @@ /// This method limits promotion of aggregates to only promote up to three /// elements of the aggregate in order to avoid exploding the number of /// arguments passed in. -bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const { +bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const { // We can only promote this argument if all of the uses are loads, or are GEP // instructions (with constant indices) that are subsequently loaded. bool HasLoadInEntryBlock = false; @@ -206,8 +208,8 @@ // Dead GEP's cause trouble later. Just remove them if we run into // them. getAnalysis().deleteValue(GEP); - GEP->getParent()->getInstList().erase(GEP); - return isSafeToPromoteArgument(Arg); + GEP->eraseFromParent(); + return isSafeToPromoteArgument(Arg, isByVal); } // Ensure that all of the indices are constants. SmallVector Operands; @@ -326,8 +328,7 @@ /// arguments, and returns the new function. At this point, we know that it's /// safe to do so. Function *ArgPromotion::DoPromotion(Function *F, - SmallVectorImpl &Args2Prom) { - SmallPtrSet ArgsToPromote(Args2Prom.begin(), Args2Prom.end()); + SmallPtrSet &ArgsToPromote) { // Start by computing a new prototype for the function, which is the same as // the old function, but has modified arguments. @@ -497,7 +498,7 @@ // Finally, remove the old call from the program, reducing the use-count of // F. - Call->getParent()->getInstList().erase(Call); + Call->eraseFromParent(); } // Since we have now created the new function, splice the body of the old @@ -532,7 +533,7 @@ I2->setName(I->getName()+".val"); LI->replaceAllUsesWith(I2); AA.replaceWithNewValue(LI, I2); - LI->getParent()->getInstList().erase(LI); + LI->eraseFromParent(); DOUT << "*** Promoted load of argument '" << I->getName() << "' in function '" << F->getName() << "'\n"; } else { @@ -562,10 +563,10 @@ LoadInst *L = cast(GEP->use_back()); L->replaceAllUsesWith(TheArg); AA.replaceWithNewValue(L, TheArg); - L->getParent()->getInstList().erase(L); + L->eraseFromParent(); } AA.deleteValue(GEP); - GEP->getParent()->getInstList().erase(GEP); + GEP->eraseFromParent(); } } @@ -583,6 +584,6 @@ AA.replaceWithNewValue(F, NF); // Now that the old function is dead, delete it. - F->getParent()->getFunctionList().erase(F); + F->eraseFromParent(); return NF; } From sabre at nondot.org Fri Jan 11 13:34:36 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 19:34:36 -0000 Subject: [llvm-commits] [llvm] r45877 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801111934.m0BJYaIj021722@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 13:34:32 2008 New Revision: 45877 URL: http://llvm.org/viewvc/llvm-project?rev=45877&view=rev Log: a byval argument is guaranteed to be valid to load. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45877&r1=45876&r2=45877&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 13:34:32 2008 @@ -193,7 +193,15 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const { // We can only promote this argument if all of the uses are loads, or are GEP // instructions (with constant indices) that are subsequently loaded. - bool HasLoadInEntryBlock = false; + + // We can also only promote the load if we can guarantee that it will happen. + // Promoting a load causes the load to be unconditionally executed in the + // caller, so we can't turn a conditional load into an unconditional load in + // general. + bool SafeToUnconditionallyLoad = false; + if (isByVal) // ByVal arguments are always safe to load from. + SafeToUnconditionallyLoad = true; + BasicBlock *EntryBlock = Arg->getParent()->begin(); SmallVector Loads; std::vector > GEPIndices; @@ -202,7 +210,10 @@ if (LoadInst *LI = dyn_cast(*UI)) { if (LI->isVolatile()) return false; // Don't hack volatile loads Loads.push_back(LI); - HasLoadInEntryBlock |= LI->getParent() == EntryBlock; + + // If this load occurs in the entry block, then the pointer is + // unconditionally loaded. + SafeToUnconditionallyLoad |= LI->getParent() == EntryBlock; } else if (GetElementPtrInst *GEP = dyn_cast(*UI)) { if (GEP->use_empty()) { // Dead GEP's cause trouble later. Just remove them if we run into @@ -225,7 +236,10 @@ if (LoadInst *LI = dyn_cast(*UI)) { if (LI->isVolatile()) return false; // Don't hack volatile loads Loads.push_back(LI); - HasLoadInEntryBlock |= LI->getParent() == EntryBlock; + + // If this load occurs in the entry block, then the pointer is + // unconditionally loaded. + SafeToUnconditionallyLoad |= LI->getParent() == EntryBlock; } else { return false; } @@ -257,7 +271,8 @@ // of the pointer in the entry block of the function) or if we can prove that // all pointers passed in are always to legal locations (for example, no null // pointers are passed in, no pointers to free'd memory, etc). - if (!HasLoadInEntryBlock && !AllCalleesPassInValidPointerForArgument(Arg)) + if (!SafeToUnconditionallyLoad && + !AllCalleesPassInValidPointerForArgument(Arg)) return false; // Cannot prove that this is safe!! // Okay, now we know that the argument is only used by load instructions and From sabre at nondot.org Fri Jan 11 13:36:32 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 19:36:32 -0000 Subject: [llvm-commits] [llvm] r45878 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801111936.m0BJaW01021905@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 13:36:30 2008 New Revision: 45878 URL: http://llvm.org/viewvc/llvm-project?rev=45878&view=rev Log: Use smallptrset instead of std::set for efficiency. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45878&r1=45877&r2=45878&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 13:36:30 2008 @@ -282,7 +282,7 @@ // Because there could be several/many load instructions, remember which // blocks we know to be transparent to the load. - std::set TranspBlocks; + SmallPtrSet TranspBlocks; AliasAnalysis &AA = getAnalysis(); TargetData &TD = getAnalysis(); @@ -304,7 +304,8 @@ // To do this, we perform a depth first search on the inverse CFG from the // loading block. for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) - for (idf_ext_iterator I = idf_ext_begin(*PI, TranspBlocks), + for (idf_ext_iterator > + I = idf_ext_begin(*PI, TranspBlocks), E = idf_ext_end(*PI, TranspBlocks); I != E; ++I) if (AA.canBasicBlockModify(**I, Arg, LoadSize)) return false; From evan.cheng at apple.com Fri Jan 11 14:06:43 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 20:06:43 -0000 Subject: [llvm-commits] [test-suite] r45879 - /test-suite/trunk/MultiSource/Applications/minisat/Main.cpp Message-ID: <200801112006.m0BK6hRH023488@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 14:06:43 2008 New Revision: 45879 URL: http://llvm.org/viewvc/llvm-project?rev=45879&view=rev Log: Fix bad bad code. Modified: test-suite/trunk/MultiSource/Applications/minisat/Main.cpp Modified: test-suite/trunk/MultiSource/Applications/minisat/Main.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Applications/minisat/Main.cpp?rev=45879&r1=45878&r2=45879&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Applications/minisat/Main.cpp (original) +++ test-suite/trunk/MultiSource/Applications/minisat/Main.cpp Fri Jan 11 14:06:43 2008 @@ -224,7 +224,7 @@ { int len = strlen(prefix); if (strncmp(str, prefix, len) == 0) - return str + len; + return strdup(str + len); else return NULL; } From dalej at apple.com Fri Jan 11 14:47:33 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 11 Jan 2008 20:47:33 -0000 Subject: [llvm-commits] [llvm] r45881 - /llvm/trunk/test/CodeGen/X86/aligned-comm.ll Message-ID: <200801112047.m0BKlXYl025264@zion.cs.uiuc.edu> Author: johannes Date: Fri Jan 11 14:47:33 2008 New Revision: 45881 URL: http://llvm.org/viewvc/llvm-project?rev=45881&view=rev Log: Disable for now. Modified: llvm/trunk/test/CodeGen/X86/aligned-comm.ll Modified: llvm/trunk/test/CodeGen/X86/aligned-comm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/aligned-comm.ll?rev=45881&r1=45880&r2=45881&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/aligned-comm.ll (original) +++ llvm/trunk/test/CodeGen/X86/aligned-comm.ll Fri Jan 11 14:47:33 2008 @@ -2,6 +2,9 @@ ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin10 | grep {array,16512,7} ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep {array,16512,7} ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin8 | not grep {7} +; XFAIL: * + +; Currently there is no construct which generates .comm, so test is xfail'ed. ; Darwin 9+ should get alignment on common symbols. Darwin8 does ; not support this. From scottm at aero.org Fri Jan 11 15:01:19 2008 From: scottm at aero.org (Scott Michel) Date: Fri, 11 Jan 2008 21:01:19 -0000 Subject: [llvm-commits] [llvm] r45882 - in /llvm/trunk: lib/Target/CellSPU/SPUISelDAGToDAG.cpp lib/Target/CellSPU/SPUISelLowering.cpp test/CodeGen/CellSPU/call_indirect.ll test/CodeGen/CellSPU/struct_1.ll test/CodeGen/CellSPU/struct_2.ll Message-ID: <200801112101.m0BL1JNf026078@zion.cs.uiuc.edu> Author: pingbak Date: Fri Jan 11 15:01:19 2008 New Revision: 45882 URL: http://llvm.org/viewvc/llvm-project?rev=45882&view=rev Log: More CellSPU refinements: - struct_2.ll: Completely unaligned load/store testing - call_indirect.ll, struct_1.ll: Add test lines to exercise X-form [$reg($reg)] addressing At this point, loads and stores should be under control (he says in an optimistic tone of voice.) Added: llvm/trunk/test/CodeGen/CellSPU/struct_2.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll llvm/trunk/test/CodeGen/CellSPU/struct_1.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=45882&r1=45881&r2=45882&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Fri Jan 11 15:01:19 2008 @@ -456,8 +456,9 @@ const SDOperand Op0 = N.getOperand(0); // Frame index/base const SDOperand Op1 = N.getOperand(1); // Offset within base - if (Op1.getOpcode() == ISD::Constant - || Op1.getOpcode() == ISD::TargetConstant) { + if ((Op1.getOpcode() == ISD::Constant + || Op1.getOpcode() == ISD::TargetConstant) + && Op0.getOpcode() != SPUISD::XFormAddr) { ConstantSDNode *CN = dyn_cast(Op1); assert(CN != 0 && "SelectDFormAddr: Expected a constant"); @@ -499,12 +500,19 @@ } else return false; } else if (Opc == SPUISD::DFormAddr) { - // D-Form address: This is pretty straightforward, naturally... - ConstantSDNode *CN = cast(N.getOperand(1)); - assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant"); - Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); - Index = N.getOperand(0); - return true; + // D-Form address: This is pretty straightforward, + // naturally... but make sure that this isn't a D-form address + // with a X-form address embedded within: + const SDOperand Op0 = N.getOperand(0); // Frame index/base + const SDOperand Op1 = N.getOperand(1); // Offset within base + + if (Op0.getOpcode() != SPUISD::XFormAddr) { + ConstantSDNode *CN = cast(Op1); + assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant"); + Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); + Index = Op0; + return true; + } } else if (Opc == ISD::FrameIndex) { // Stack frame index must be less than 512 (divided by 16): FrameIndexSDNode *FI = dyn_cast(N); @@ -564,6 +572,12 @@ Base = N; Index = N.getOperand(1); return true; + } else if (Opc == SPUISD::DFormAddr) { + // Must be a D-form address with an X-form address embedded + // within: + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; } else if (N.getNumOperands() == 2) { SDOperand N1 = N.getOperand(0); SDOperand N2 = N.getOperand(1); @@ -578,14 +592,14 @@ /*UNREACHED*/ } else { cerr << "SelectXFormAddr: 2-operand unhandled operand:\n"; - N.Val->dump(); + N.Val->dump(CurDAG); cerr << "\n"; abort(); /*UNREACHED*/ } } else { cerr << "SelectXFormAddr: Unhandled operand type:\n"; - N.Val->dump(); + N.Val->dump(CurDAG); cerr << "\n"; abort(); /*UNREACHED*/ Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=45882&r1=45881&r2=45882&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Fri Jan 11 15:01:19 2008 @@ -90,13 +90,11 @@ const unsigned Opc = Op.getOpcode(); return (Opc == ISD::GlobalAddress || Opc == ISD::GlobalTLSAddress - /* || Opc == ISD::FrameIndex */ || Opc == ISD::JumpTable || Opc == ISD::ConstantPool || Opc == ISD::ExternalSymbol || Opc == ISD::TargetGlobalAddress || Opc == ISD::TargetGlobalTLSAddress - /* || Opc == ISD::TargetFrameIndex */ || Opc == ISD::TargetJumpTable || Opc == ISD::TargetConstantPool || Opc == ISD::TargetExternalSymbol @@ -566,7 +564,7 @@ // Rotate the chunk if necessary if (rotamt < 0) rotamt += 16; - if (rotamt != 0) { + if (rotamt != 0 || !was16aligned) { SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other); if (was16aligned) { @@ -574,10 +572,12 @@ Ops[1] = result; Ops[2] = DAG.getConstant(rotamt, MVT::i16); } else { + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); LoadSDNode *LN1 = cast(result); Ops[0] = the_chain; Ops[1] = result; - Ops[2] = LN1->getBasePtr(); + Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(), + DAG.getConstant(rotamt, PtrVT)); } result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3); @@ -690,7 +690,6 @@ } chunk_offset &= 0xf; - chunk_offset /= (MVT::getSizeInBits(StVT == MVT::i1 ? (unsigned) MVT::i8 : StVT) / 8); SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT); SDOperand insertEltPtr; @@ -700,10 +699,18 @@ // a new D-form address with a slot offset and the orignal base pointer. // Otherwise generate a D-form address with the slot offset relative // to the stack pointer, which is always aligned. + DEBUG(cerr << "CellSPU LowerSTORE: basePtr = "); + DEBUG(basePtr.Val->dump(&DAG)); + DEBUG(cerr << "\n"); + if (basePtr.getOpcode() == SPUISD::DFormAddr) { insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, basePtr.getOperand(0), insertEltOffs); + } else if (basePtr.getOpcode() == SPUISD::XFormAddr || + (basePtr.getOpcode() == ISD::ADD + && basePtr.getOperand(0).getOpcode() == SPUISD::XFormAddr)) { + insertEltPtr = basePtr; } else { insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, DAG.getRegister(SPU::R1, PtrVT), Modified: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll?rev=45882&r1=45881&r2=45882&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll Fri Jan 11 15:01:19 2008 @@ -1,10 +1,21 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: llvm-as -o - %s | llc -march=cellspu -mattr=large_mem > %t2.s ; RUN: grep bisl %t1.s | count 6 && ; RUN: grep ila %t1.s | count 1 && ; RUN: grep rotqbyi %t1.s | count 4 && ; RUN: grep lqa %t1.s | count 4 && ; RUN: grep lqd %t1.s | count 6 && ; RUN: grep dispatch_tab %t1.s | count 10 +; RUN: grep bisl %t2.s | count 6 && +; RUN: grep ilhu %t2.s | count 1 && +; RUN: grep iohl %t2.s | count 1 && +; RUN: grep rotqby %t2.s | count 5 && +; RUN: grep lqd %t2.s | count 12 && +; RUN: grep lqx %t2.s | count 6 && +; RUN: grep il %t2.s | count 7 && +; RUN: grep ai %t2.s | count 5 && +; RUN: grep dispatch_tab %t2.s | count 7 + ; ModuleID = 'call_indirect.bc' target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128" target triple = "spu-unknown-elf" Modified: llvm/trunk/test/CodeGen/CellSPU/struct_1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/struct_1.ll?rev=45882&r1=45881&r2=45882&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/struct_1.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/struct_1.ll Fri Jan 11 15:01:19 2008 @@ -1,14 +1,27 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: llvm-as -o - %s | llc -march=cellspu -mattr=large_mem > %t2.s ; RUN: grep lqa %t1.s | count 10 && -; RUN: grep lqd %t1.s | count 2 && +; RUN: grep lqd %t1.s | count 4 && ; RUN: grep rotqbyi %t1.s | count 5 && ; RUN: grep xshw %t1.s | count 1 && ; RUN: grep andi %t1.s | count 4 && ; RUN: grep cbd %t1.s | count 3 && ; RUN: grep chd %t1.s | count 1 && -; RUN: grep cwd %t1.s | count 1 && -; RUN: grep shufb %t1.s | count 5 && +; RUN: grep cwd %t1.s | count 3 && +; RUN: grep shufb %t1.s | count 7 && ; RUN: grep stqa %t1.s | count 5 +; RUN: grep iohl %t2.s | count 14 && +; RUN: grep ilhu %t2.s | count 14 && +; RUN: grep lqx %t2.s | count 14 && +; RUN: grep rotqbyi %t2.s | count 5 && +; RUN: grep xshw %t2.s | count 1 && +; RUN: grep andi %t2.s | count 4 && +; RUN: grep cbd %t2.s | count 3 && +; RUN: grep chd %t2.s | count 1 && +; RUN: grep cwd %t2.s | count 3 && +; RUN: grep shufb %t2.s | count 7 && +; RUN: grep stqx %t2.s | count 7 + ; ModuleID = 'struct_1.bc' target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" @@ -105,3 +118,17 @@ store i16 %s, i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 16 ret void } + +define void @set_hackstate_i3(i32 %i) { +entry: + store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 11), align 16 + ret void +} + + +define void @set_hackstate_i6(i32 %i) { +entry: + store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 13), align 16 + ret void +} + Added: llvm/trunk/test/CodeGen/CellSPU/struct_2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/struct_2.ll?rev=45882&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/struct_2.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/struct_2.ll Fri Jan 11 15:01:19 2008 @@ -0,0 +1,122 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep lqx %t1.s | count 14 && +; RUN: grep rotqby %t1.s | count 7 && +; RUN: grep xshw %t1.s | count 1 && +; RUN: grep andi %t1.s | count 4 && +; RUN: grep cbx %t1.s | count 1 && +; RUN: grep cbd %t1.s | count 2 && +; RUN: grep chd %t1.s | count 1 && +; RUN: grep cwd %t1.s | count 3 && +; RUN: grep shufb %t1.s | count 7 && +; RUN: grep stqx %t1.s | count 7 + +; ModuleID = 'struct_1.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +; struct hackstate { +; unsigned char c1; // offset 0 (rotate left by 13 bytes to byte 3) +; unsigned char c2; // offset 1 (rotate left by 14 bytes to byte 3) +; unsigned char c3; // offset 2 (rotate left by 15 bytes to byte 3) +; int i1; // offset 4 (rotate left by 4 bytes to byte 0) +; short s1; // offset 8 (rotate left by 6 bytes to byte 2) +; int i2; // offset 12 [ignored] +; unsigned char c4; // offset 16 [ignored] +; unsigned char c5; // offset 17 [ignored] +; unsigned char c6; // offset 18 [ignored] +; unsigned char c7; // offset 19 (no rotate, in preferred slot) +; int i3; // offset 20 [ignored] +; int i4; // offset 24 [ignored] +; int i5; // offset 28 [ignored] +; int i6; // offset 32 (no rotate, in preferred slot) +; } +%struct.hackstate = type { i8, i8, i8, i32, i16, i32, i8, i8, i8, i8, i32, i32, i32, i32 } + +; struct hackstate state = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + at state = global %struct.hackstate zeroinitializer, align 4 + +define i8 @get_hackstate_c1() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 0), align 4 + ret i8 %tmp2 +} + +define i8 @get_hackstate_c2() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 1), align 4 + ret i8 %tmp2 +} + +define i8 @get_hackstate_c3() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 2), align 4 + ret i8 %tmp2 +} + +define i32 @get_hackstate_i1() { +entry: + %tmp2 = load i32* getelementptr (%struct.hackstate* @state, i32 0, i32 3), align 4 + ret i32 %tmp2 +} + +define i16 @get_hackstate_s1() signext { +entry: + %tmp2 = load i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 4 + ret i16 %tmp2 +} + +define i8 @get_hackstate_c7() zeroext { +entry: + %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 9), align 4 + ret i8 %tmp2 +} + +define i32 @get_hackstate_i6() zeroext { +entry: + %tmp2 = load i32* getelementptr (%struct.hackstate* @state, i32 0, i32 13), align 4 + ret i32 %tmp2 +} + +define void @set_hackstate_c1(i8 zeroext %c) { +entry: + store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 0), align 4 + ret void +} + +define void @set_hackstate_c2(i8 zeroext %c) { +entry: + store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 1), align 4 + ret void +} + +define void @set_hackstate_c3(i8 zeroext %c) { +entry: + store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 2), align 4 + ret void +} + +define void @set_hackstate_i1(i32 %i) { +entry: + store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 3), align 4 + ret void +} + +define void @set_hackstate_s1(i16 signext %s) { +entry: + store i16 %s, i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 4 + ret void +} + +define void @set_hackstate_i3(i32 %i) { +entry: + store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 11), align 4 + ret void +} + + +define void @set_hackstate_i6(i32 %i) { +entry: + store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 13), align 4 + ret void +} + From evan.cheng at apple.com Fri Jan 11 15:20:46 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 21:20:46 -0000 Subject: [llvm-commits] [test-suite] r45883 - in /test-suite/trunk: External/SPEC/Makefile.spec Makefile.programs Makefile.rules Makefile.tests MultiSource/Makefile.multisrc SingleSource/Makefile.singlesrc TEST.nightly.Makefile Message-ID: <200801112120.m0BLKkpl026966@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 15:20:45 2008 New Revision: 45883 URL: http://llvm.org/viewvc/llvm-project?rev=45883&view=rev Log: - Clean up. - Added DISABLE_LTO option to disable link time optimization. If this is not set, each file is compiled with -O0 and optimization is performed with opt -std-compile-opts and llvm-ld. If it is set, each file is compiled with -O3 (same as gcc, g++) and -disable-inlining and -disable-opt are passed to opt and llvm-ld. This is useful for performance comparison and finding ABI problems. Modified: test-suite/trunk/External/SPEC/Makefile.spec test-suite/trunk/Makefile.programs test-suite/trunk/Makefile.rules test-suite/trunk/Makefile.tests test-suite/trunk/MultiSource/Makefile.multisrc test-suite/trunk/SingleSource/Makefile.singlesrc test-suite/trunk/TEST.nightly.Makefile Modified: test-suite/trunk/External/SPEC/Makefile.spec URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/External/SPEC/Makefile.spec?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/External/SPEC/Makefile.spec (original) +++ test-suite/trunk/External/SPEC/Makefile.spec Fri Jan 11 15:20:45 2008 @@ -7,10 +7,6 @@ include $(LEVEL)/MultiSource/Makefile.multisrc -# Do not pass -Wall to compile commands... -LCCFLAGS := -O3 -LCXXFLAGS := -O3 - CPPFLAGS += -I $(SPEC_BENCH_DIR)/src/ SPEC_SANDBOX := $(PROGDIR)/External/SPEC/Sandbox.sh Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Fri Jan 11 15:20:45 2008 @@ -348,7 +348,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.cbe): \ Output/%.cbe: Output/%.cbe.c - -$(CC) $< -o $@ $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -O2 -fno-inline $(TARGET_FLAGS) $(LIBS) + -$(CC) $< -o $@ $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -fno-inline $(TARGET_FLAGS) $(LIBS) # # Compile a linked program to machine code with LLC. Modified: test-suite/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.rules?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/Makefile.rules (original) +++ test-suite/trunk/Makefile.rules Fri Jan 11 15:20:45 2008 @@ -350,6 +350,11 @@ CPPFLAGS += -DSMALL_PROBLEM_SIZE endif +ifdef DISABLE_LTO +EXTRA_LOPT_OPTIONS += -disable-opt -disable-inlining +EXTRA_LINKTIME_OPT_FLAGS += -disable-opt -disable-inlining +endif + # # Compile commands with libtool. # Modified: test-suite/trunk/Makefile.tests URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.tests?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/Makefile.tests (original) +++ test-suite/trunk/Makefile.tests Fri Jan 11 15:20:45 2008 @@ -34,9 +34,23 @@ .PRECIOUS: Output/%.llvm.bc .PRECIOUS: Output/%.llvm -LCCFLAGS += -O2 -LCXXFLAGS += -O2 -LLCFLAGS = +ifndef CFLAGS +CFLAGS = -O3 +endif +ifndef CXXFLAGS +CXXFLAGS = -O3 +endif + +# If LTO is on, compile each .c .cpp file with -O0 and optimize with +# opt and llvm-ld. +ifndef DISABLE_LTO +LCCFLAGS := -O0 $(CPPFLAGS) +LCXXFLAGS := -O0 $(CPPFLAGS) +else +LCCFLAGS := $(CFLAGS) $(CPPFLAGS) +LCXXFLAGS := $(CXXFLAGS) $(CPPFLAGS) +endif + FAILURE = $(LLVM_SRC_ROOT)/test/Failure.sh LLCLIBS := $(LLCLIBS) -lm @@ -46,22 +60,22 @@ # Compile from X.c to Output/X.ll Output/%.bc: %.c $(LCC1) Output/.dir $(INCLUDES) - -$(LLVMGCC) $(CPPFLAGS) $(LCCFLAGS) $(TARGET_FLAGS) -O0 -c $< -o $@ -emit-llvm + -$(LLVMGCC) $(CPPFLAGS) $(LCCFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm -$(call UPGRADE_LL,$@) # Compile from X.cpp to Output/X.ll Output/%.bc: %.cpp $(LCC1XX) Output/.dir $(INCLUDES) - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm -$(call UPGRADE_LL,$@) # Compile from X.cc to Output/X.ll Output/%.bc: %.cc $(LCC1XX) Output/.dir $(INCLUDES) - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm -$(call UPGRADE_LL,$@) # Compile from X.C to Output/X.ll Output/%.bc: %.C $(LCC1XX) Output/.dir $(INCLUDES) - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm -$(call UPGRADE_LL,$@) # LLVM Assemble from X.ll to Output/X.bc. Because we are coming directly from Modified: test-suite/trunk/MultiSource/Makefile.multisrc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Makefile.multisrc?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Makefile.multisrc (original) +++ test-suite/trunk/MultiSource/Makefile.multisrc Fri Jan 11 15:20:45 2008 @@ -10,7 +10,6 @@ # ##===----------------------------------------------------------------------===## -LCCFLAGS := $(CFLAGS) $(CPPFLAGS) PROGRAMS_TO_TEST := $(PROG) ## LLVM bytecode libraries that must be linked with an application @@ -29,16 +28,16 @@ .PRECIOUS: $(LObjects) $(NObjects) Output/%.o: %.c Output/.dir - -$(CC) $(CPPFLAGS) $(CFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ + -$(CC) $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) -c $< -o $@ Output/%.o: %.C Output/.dir - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ Output/%.o: %.cpp Output/.dir - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ Output/%.o: %.cc Output/.dir - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ bugpoint-opt: Output/$(PROG).bugpoint-opt bugpoint-gccas: Output/$(PROG).bugpoint-opt Modified: test-suite/trunk/SingleSource/Makefile.singlesrc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Makefile.singlesrc?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Makefile.singlesrc (original) +++ test-suite/trunk/SingleSource/Makefile.singlesrc Fri Jan 11 15:20:45 2008 @@ -34,10 +34,10 @@ # FIXME: LIBS should be specified, not hardcoded to -lm Output/%.native: $(SourceDir)/%.c Output/.dir - -$(CC) -O2 $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) + -$(CC) $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) Output/%.native: $(SourceDir)/%.cpp Output/.dir - -$(CXX) -O2 $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) + -$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) bugpoint-gccas bugpoint-opt bugpoint-llvm-ld bugpoint-gccld bugpoint-jit bugpoint-llc bugpoint-llc-beta: Modified: test-suite/trunk/TEST.nightly.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly.Makefile?rev=45883&r1=45882&r2=45883&view=diff ============================================================================== --- test-suite/trunk/TEST.nightly.Makefile (original) +++ test-suite/trunk/TEST.nightly.Makefile Fri Jan 11 15:20:45 2008 @@ -8,7 +8,6 @@ CURDIR := $(shell cd .; pwd) PROGDIR := $(PROJ_SRC_ROOT) RELDIR := $(subst $(PROGDIR),,$(CURDIR)) -CFLAGS := -O3 REPORTS_TO_GEN := compile nat ifndef DISABLE_LLC From baldrick at free.fr Fri Jan 11 15:23:39 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Jan 2008 21:23:39 -0000 Subject: [llvm-commits] [llvm] r45884 - in /llvm/trunk: lib/AsmParser/llvmAsmParser.y test/Assembler/2008-01-11-VarargAttrs.ll Message-ID: <200801112123.m0BLNe3L027098@zion.cs.uiuc.edu> Author: baldrick Date: Fri Jan 11 15:23:39 2008 New Revision: 45884 URL: http://llvm.org/viewvc/llvm-project?rev=45884&view=rev Log: If there are attributes on the varargs part of a call, don't discard them. Added: llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=45884&r1=45883&r2=45884&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Fri Jan 11 15:23:39 2008 @@ -2675,8 +2675,15 @@ if (Ty->isVarArg()) { if (I == E) - for (; ArgI != ArgE; ++ArgI) + for (; ArgI != ArgE; ++ArgI, ++index) { Args.push_back(ArgI->Val); // push the remaining varargs + if (ArgI->Attrs != ParamAttr::None) { + ParamAttrsWithIndex PAWI; + PAWI.index = index; + PAWI.attrs = ArgI->Attrs; + Attrs.push_back(PAWI); + } + } } else if (I != E || ArgI != ArgE) GEN_ERROR("Invalid number of parameters detected"); } @@ -3006,8 +3013,15 @@ } if (Ty->isVarArg()) { if (I == E) - for (; ArgI != ArgE; ++ArgI) + for (; ArgI != ArgE; ++ArgI, ++index) { Args.push_back(ArgI->Val); // push the remaining varargs + if (ArgI->Attrs != ParamAttr::None) { + ParamAttrsWithIndex PAWI; + PAWI.index = index; + PAWI.attrs = ArgI->Attrs; + Attrs.push_back(PAWI); + } + } } else if (I != E || ArgI != ArgE) GEN_ERROR("Invalid number of parameters detected"); } Added: llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll?rev=45884&view=auto ============================================================================== --- llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll (added) +++ llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll Fri Jan 11 15:23:39 2008 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llvm-dis | grep byval | count 2 + + %struct = type { } + +declare void @foo(...) + +define void @bar() { + call void (...)* @foo(%struct* byval null, %struct* byval null ) + ret void +} From lattner at apple.com Fri Jan 11 15:43:31 2008 From: lattner at apple.com (Tanya Lattner) Date: Fri, 11 Jan 2008 13:43:31 -0800 Subject: [llvm-commits] [test-suite] r45883 - in /test-suite/trunk: External/SPEC/Makefile.spec Makefile.programs Makefile.rules Makefile.tests MultiSource/Makefile.multisrc SingleSource/Makefile.singlesrc TEST.nightly.Makefile In-Reply-To: <200801112120.m0BLKkpl026966@zion.cs.uiuc.edu> References: <200801112120.m0BLKkpl026966@zion.cs.uiuc.edu> Message-ID: <2F9E60B5-6663-41D1-93AB-4DBE915529F8@apple.com> Switching the nightly tester makefile to be -O3 is going to mess with performance data over time (was it O2 always before?). The nightly testers probably should be modified so that this information is propagated to the tester databases and also you should be able to set it when you run the nightly tester. -Tanya On Jan 11, 2008, at 1:20 PM, Evan Cheng wrote: > Author: evancheng > Date: Fri Jan 11 15:20:45 2008 > New Revision: 45883 > > URL: http://llvm.org/viewvc/llvm-project?rev=45883&view=rev > Log: > - Clean up. > - Added DISABLE_LTO option to disable link time optimization. If > this is not > set, each file is compiled with -O0 and optimization is performed > with > opt -std-compile-opts and llvm-ld. If it is set, each file is > compiled with > -O3 (same as gcc, g++) and -disable-inlining and -disable-opt are > passed to > opt and llvm-ld. This is useful for performance comparison and > finding ABI > problems. > > Modified: > test-suite/trunk/External/SPEC/Makefile.spec > test-suite/trunk/Makefile.programs > test-suite/trunk/Makefile.rules > test-suite/trunk/Makefile.tests > test-suite/trunk/MultiSource/Makefile.multisrc > test-suite/trunk/SingleSource/Makefile.singlesrc > test-suite/trunk/TEST.nightly.Makefile > > Modified: test-suite/trunk/External/SPEC/Makefile.spec > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/External/ > SPEC/Makefile.spec?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/External/SPEC/Makefile.spec (original) > +++ test-suite/trunk/External/SPEC/Makefile.spec Fri Jan 11 > 15:20:45 2008 > @@ -7,10 +7,6 @@ > > include $(LEVEL)/MultiSource/Makefile.multisrc > > -# Do not pass -Wall to compile commands... > -LCCFLAGS := -O3 > -LCXXFLAGS := -O3 > - > CPPFLAGS += -I $(SPEC_BENCH_DIR)/src/ > SPEC_SANDBOX := $(PROGDIR)/External/SPEC/Sandbox.sh > > > Modified: test-suite/trunk/Makefile.programs > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ > Makefile.programs?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/Makefile.programs (original) > +++ test-suite/trunk/Makefile.programs Fri Jan 11 15:20:45 2008 > @@ -348,7 +348,7 @@ > > $(PROGRAMS_TO_TEST:%=Output/%.cbe): \ > Output/%.cbe: Output/%.cbe.c > - -$(CC) $< -o $@ $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -O2 - > fno-inline $(TARGET_FLAGS) $(LIBS) > + -$(CC) $< -o $@ $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -fno- > inline $(TARGET_FLAGS) $(LIBS) > > # > # Compile a linked program to machine code with LLC. > > Modified: test-suite/trunk/Makefile.rules > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ > Makefile.rules?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/Makefile.rules (original) > +++ test-suite/trunk/Makefile.rules Fri Jan 11 15:20:45 2008 > @@ -350,6 +350,11 @@ > CPPFLAGS += -DSMALL_PROBLEM_SIZE > endif > > +ifdef DISABLE_LTO > +EXTRA_LOPT_OPTIONS += -disable-opt -disable-inlining > +EXTRA_LINKTIME_OPT_FLAGS += -disable-opt -disable-inlining > +endif > + > # > # Compile commands with libtool. > # > > Modified: test-suite/trunk/Makefile.tests > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ > Makefile.tests?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/Makefile.tests (original) > +++ test-suite/trunk/Makefile.tests Fri Jan 11 15:20:45 2008 > @@ -34,9 +34,23 @@ > .PRECIOUS: Output/%.llvm.bc > .PRECIOUS: Output/%.llvm > > -LCCFLAGS += -O2 > -LCXXFLAGS += -O2 > -LLCFLAGS = > +ifndef CFLAGS > +CFLAGS = -O3 > +endif > +ifndef CXXFLAGS > +CXXFLAGS = -O3 > +endif > + > +# If LTO is on, compile each .c .cpp file with -O0 and optimize with > +# opt and llvm-ld. > +ifndef DISABLE_LTO > +LCCFLAGS := -O0 $(CPPFLAGS) > +LCXXFLAGS := -O0 $(CPPFLAGS) > +else > +LCCFLAGS := $(CFLAGS) $(CPPFLAGS) > +LCXXFLAGS := $(CXXFLAGS) $(CPPFLAGS) > +endif > + > FAILURE = $(LLVM_SRC_ROOT)/test/Failure.sh > LLCLIBS := $(LLCLIBS) -lm > > @@ -46,22 +60,22 @@ > > # Compile from X.c to Output/X.ll > Output/%.bc: %.c $(LCC1) Output/.dir $(INCLUDES) > - -$(LLVMGCC) $(CPPFLAGS) $(LCCFLAGS) $(TARGET_FLAGS) -O0 -c $< -o > $@ -emit-llvm > + -$(LLVMGCC) $(CPPFLAGS) $(LCCFLAGS) $(TARGET_FLAGS) -c $< -o $@ - > emit-llvm > -$(call UPGRADE_LL,$@) > > # Compile from X.cpp to Output/X.ll > Output/%.bc: %.cpp $(LCC1XX) Output/.dir $(INCLUDES) > - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o > $@ -emit-llvm > + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ - > emit-llvm > -$(call UPGRADE_LL,$@) > > # Compile from X.cc to Output/X.ll > Output/%.bc: %.cc $(LCC1XX) Output/.dir $(INCLUDES) > - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o > $@ -emit-llvm > + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ - > emit-llvm > -$(call UPGRADE_LL,$@) > > # Compile from X.C to Output/X.ll > Output/%.bc: %.C $(LCC1XX) Output/.dir $(INCLUDES) > - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o > $@ -emit-llvm > + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ - > emit-llvm > -$(call UPGRADE_LL,$@) > > # LLVM Assemble from X.ll to Output/X.bc. Because we are coming > directly from > > Modified: test-suite/trunk/MultiSource/Makefile.multisrc > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ > MultiSource/Makefile.multisrc?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/MultiSource/Makefile.multisrc (original) > +++ test-suite/trunk/MultiSource/Makefile.multisrc Fri Jan 11 > 15:20:45 2008 > @@ -10,7 +10,6 @@ > # > > ##===----------------------------------------------------------------- > -----===## > > -LCCFLAGS := $(CFLAGS) $(CPPFLAGS) > PROGRAMS_TO_TEST := $(PROG) > > ## LLVM bytecode libraries that must be linked with an application > @@ -29,16 +28,16 @@ > .PRECIOUS: $(LObjects) $(NObjects) > > Output/%.o: %.c Output/.dir > - -$(CC) $(CPPFLAGS) $(CFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ > + -$(CC) $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) -c $< -o $@ > > Output/%.o: %.C Output/.dir > - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ > + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ > > Output/%.o: %.cpp Output/.dir > - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ > + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ > > Output/%.o: %.cc Output/.dir > - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ > + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ > > bugpoint-opt: Output/$(PROG).bugpoint-opt > bugpoint-gccas: Output/$(PROG).bugpoint-opt > > Modified: test-suite/trunk/SingleSource/Makefile.singlesrc > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ > SingleSource/Makefile.singlesrc?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/SingleSource/Makefile.singlesrc (original) > +++ test-suite/trunk/SingleSource/Makefile.singlesrc Fri Jan 11 > 15:20:45 2008 > @@ -34,10 +34,10 @@ > > # FIXME: LIBS should be specified, not hardcoded to -lm > Output/%.native: $(SourceDir)/%.c Output/.dir > - -$(CC) -O2 $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ > (LDFLAGS) > + -$(CC) $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) > > Output/%.native: $(SourceDir)/%.cpp Output/.dir > - -$(CXX) -O2 $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ > (LDFLAGS) > + -$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ > (LDFLAGS) > > > bugpoint-gccas bugpoint-opt bugpoint-llvm-ld bugpoint-gccld > bugpoint-jit bugpoint-llc bugpoint-llc-beta: > > Modified: test-suite/trunk/TEST.nightly.Makefile > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ > TEST.nightly.Makefile?rev=45883&r1=45882&r2=45883&view=diff > > ====================================================================== > ======== > --- test-suite/trunk/TEST.nightly.Makefile (original) > +++ test-suite/trunk/TEST.nightly.Makefile Fri Jan 11 15:20:45 2008 > @@ -8,7 +8,6 @@ > CURDIR := $(shell cd .; pwd) > PROGDIR := $(PROJ_SRC_ROOT) > RELDIR := $(subst $(PROGDIR),,$(CURDIR)) > -CFLAGS := -O3 > > REPORTS_TO_GEN := compile nat > ifndef DISABLE_LLC > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Fri Jan 11 15:46:24 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Jan 2008 21:46:24 -0000 Subject: [llvm-commits] [llvm] r45885 - /llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll Message-ID: <200801112146.m0BLkOcN028121@zion.cs.uiuc.edu> Author: baldrick Date: Fri Jan 11 15:46:24 2008 New Revision: 45885 URL: http://llvm.org/viewvc/llvm-project?rev=45885&view=rev Log: Two occurrences on one line count as one... Modified: llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll Modified: llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll?rev=45885&r1=45884&r2=45885&view=diff ============================================================================== --- llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll (original) +++ llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll Fri Jan 11 15:46:24 2008 @@ -1,10 +1,10 @@ -; RUN: llvm-as < %s | llvm-dis | grep byval | count 2 +; RUN: llvm-as < %s | llvm-dis | grep byval %struct = type { } declare void @foo(...) define void @bar() { - call void (...)* @foo(%struct* byval null, %struct* byval null ) + call void (...)* @foo(%struct* byval null ) ret void } From evan.cheng at apple.com Fri Jan 11 16:16:56 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 14:16:56 -0800 Subject: [llvm-commits] [test-suite] r45883 - in /test-suite/trunk: External/SPEC/Makefile.spec Makefile.programs Makefile.rules Makefile.tests MultiSource/Makefile.multisrc SingleSource/Makefile.singlesrc TEST.nightly.Makefile In-Reply-To: <2F9E60B5-6663-41D1-93AB-4DBE915529F8@apple.com> References: <200801112120.m0BLKkpl026966@zion.cs.uiuc.edu> <2F9E60B5-6663-41D1-93AB-4DBE915529F8@apple.com> Message-ID: <012CA036-DF44-48B4-9874-718C65112757@apple.com> On Jan 11, 2008, at 1:43 PM, Tanya Lattner wrote: > Switching the nightly tester makefile to be -O3 is going to mess with > performance data over time (was it O2 always before?). The nightly > testers probably should be modified so that this information is > propagated to the tester databases and also you should be able to set > it when you run the nightly tester. No, it won't. Native has always been compiled with -O3. And up to now we have not been testing with LTO turned off. So each .c and .cpp files have been compiled with -O0 and optimization is performed at link time. This patch won't change that. Evan > > -Tanya > > On Jan 11, 2008, at 1:20 PM, Evan Cheng wrote: > >> Author: evancheng >> Date: Fri Jan 11 15:20:45 2008 >> New Revision: 45883 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45883&view=rev >> Log: >> - Clean up. >> - Added DISABLE_LTO option to disable link time optimization. If >> this is not >> set, each file is compiled with -O0 and optimization is performed >> with >> opt -std-compile-opts and llvm-ld. If it is set, each file is >> compiled with >> -O3 (same as gcc, g++) and -disable-inlining and -disable-opt are >> passed to >> opt and llvm-ld. This is useful for performance comparison and >> finding ABI >> problems. >> >> Modified: >> test-suite/trunk/External/SPEC/Makefile.spec >> test-suite/trunk/Makefile.programs >> test-suite/trunk/Makefile.rules >> test-suite/trunk/Makefile.tests >> test-suite/trunk/MultiSource/Makefile.multisrc >> test-suite/trunk/SingleSource/Makefile.singlesrc >> test-suite/trunk/TEST.nightly.Makefile >> >> Modified: test-suite/trunk/External/SPEC/Makefile.spec >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/External/ >> SPEC/Makefile.spec?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/External/SPEC/Makefile.spec (original) >> +++ test-suite/trunk/External/SPEC/Makefile.spec Fri Jan 11 >> 15:20:45 2008 >> @@ -7,10 +7,6 @@ >> >> include $(LEVEL)/MultiSource/Makefile.multisrc >> >> -# Do not pass -Wall to compile commands... >> -LCCFLAGS := -O3 >> -LCXXFLAGS := -O3 >> - >> CPPFLAGS += -I $(SPEC_BENCH_DIR)/src/ >> SPEC_SANDBOX := $(PROGDIR)/External/SPEC/Sandbox.sh >> >> >> Modified: test-suite/trunk/Makefile.programs >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ >> Makefile.programs?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/Makefile.programs (original) >> +++ test-suite/trunk/Makefile.programs Fri Jan 11 15:20:45 2008 >> @@ -348,7 +348,7 @@ >> >> $(PROGRAMS_TO_TEST:%=Output/%.cbe): \ >> Output/%.cbe: Output/%.cbe.c >> - -$(CC) $< -o $@ $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -O2 - >> fno-inline $(TARGET_FLAGS) $(LIBS) >> + -$(CC) $< -o $@ $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -fno- >> inline $(TARGET_FLAGS) $(LIBS) >> >> # >> # Compile a linked program to machine code with LLC. >> >> Modified: test-suite/trunk/Makefile.rules >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ >> Makefile.rules?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/Makefile.rules (original) >> +++ test-suite/trunk/Makefile.rules Fri Jan 11 15:20:45 2008 >> @@ -350,6 +350,11 @@ >> CPPFLAGS += -DSMALL_PROBLEM_SIZE >> endif >> >> +ifdef DISABLE_LTO >> +EXTRA_LOPT_OPTIONS += -disable-opt -disable-inlining >> +EXTRA_LINKTIME_OPT_FLAGS += -disable-opt -disable-inlining >> +endif >> + >> # >> # Compile commands with libtool. >> # >> >> Modified: test-suite/trunk/Makefile.tests >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ >> Makefile.tests?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/Makefile.tests (original) >> +++ test-suite/trunk/Makefile.tests Fri Jan 11 15:20:45 2008 >> @@ -34,9 +34,23 @@ >> .PRECIOUS: Output/%.llvm.bc >> .PRECIOUS: Output/%.llvm >> >> -LCCFLAGS += -O2 >> -LCXXFLAGS += -O2 >> -LLCFLAGS = >> +ifndef CFLAGS >> +CFLAGS = -O3 >> +endif >> +ifndef CXXFLAGS >> +CXXFLAGS = -O3 >> +endif >> + >> +# If LTO is on, compile each .c .cpp file with -O0 and optimize with >> +# opt and llvm-ld. >> +ifndef DISABLE_LTO >> +LCCFLAGS := -O0 $(CPPFLAGS) >> +LCXXFLAGS := -O0 $(CPPFLAGS) >> +else >> +LCCFLAGS := $(CFLAGS) $(CPPFLAGS) >> +LCXXFLAGS := $(CXXFLAGS) $(CPPFLAGS) >> +endif >> + >> FAILURE = $(LLVM_SRC_ROOT)/test/Failure.sh >> LLCLIBS := $(LLCLIBS) -lm >> >> @@ -46,22 +60,22 @@ >> >> # Compile from X.c to Output/X.ll >> Output/%.bc: %.c $(LCC1) Output/.dir $(INCLUDES) >> - -$(LLVMGCC) $(CPPFLAGS) $(LCCFLAGS) $(TARGET_FLAGS) -O0 -c $< -o >> $@ -emit-llvm >> + -$(LLVMGCC) $(CPPFLAGS) $(LCCFLAGS) $(TARGET_FLAGS) -c $< -o $@ - >> emit-llvm >> -$(call UPGRADE_LL,$@) >> >> # Compile from X.cpp to Output/X.ll >> Output/%.bc: %.cpp $(LCC1XX) Output/.dir $(INCLUDES) >> - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o >> $@ -emit-llvm >> + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ - >> emit-llvm >> -$(call UPGRADE_LL,$@) >> >> # Compile from X.cc to Output/X.ll >> Output/%.bc: %.cc $(LCC1XX) Output/.dir $(INCLUDES) >> - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o >> $@ -emit-llvm >> + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ - >> emit-llvm >> -$(call UPGRADE_LL,$@) >> >> # Compile from X.C to Output/X.ll >> Output/%.bc: %.C $(LCC1XX) Output/.dir $(INCLUDES) >> - -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -O0 -c $< -o >> $@ -emit-llvm >> + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ - >> emit-llvm >> -$(call UPGRADE_LL,$@) >> >> # LLVM Assemble from X.ll to Output/X.bc. Because we are coming >> directly from >> >> Modified: test-suite/trunk/MultiSource/Makefile.multisrc >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ >> MultiSource/Makefile.multisrc?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/MultiSource/Makefile.multisrc (original) >> +++ test-suite/trunk/MultiSource/Makefile.multisrc Fri Jan 11 >> 15:20:45 2008 >> @@ -10,7 +10,6 @@ >> # >> >> ##===---------------------------------------------------------------- >> - >> -----===## >> >> -LCCFLAGS := $(CFLAGS) $(CPPFLAGS) >> PROGRAMS_TO_TEST := $(PROG) >> >> ## LLVM bytecode libraries that must be linked with an application >> @@ -29,16 +28,16 @@ >> .PRECIOUS: $(LObjects) $(NObjects) >> >> Output/%.o: %.c Output/.dir >> - -$(CC) $(CPPFLAGS) $(CFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ >> + -$(CC) $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) -c $< -o $@ >> >> Output/%.o: %.C Output/.dir >> - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ >> + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ >> >> Output/%.o: %.cpp Output/.dir >> - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ >> + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ >> >> Output/%.o: %.cc Output/.dir >> - -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_FLAGS) -c $< -o $@ >> + -$(CC) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) -c $< -o $@ >> >> bugpoint-opt: Output/$(PROG).bugpoint-opt >> bugpoint-gccas: Output/$(PROG).bugpoint-opt >> >> Modified: test-suite/trunk/SingleSource/Makefile.singlesrc >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ >> SingleSource/Makefile.singlesrc?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/SingleSource/Makefile.singlesrc (original) >> +++ test-suite/trunk/SingleSource/Makefile.singlesrc Fri Jan 11 >> 15:20:45 2008 >> @@ -34,10 +34,10 @@ >> >> # FIXME: LIBS should be specified, not hardcoded to -lm >> Output/%.native: $(SourceDir)/%.c Output/.dir >> - -$(CC) -O2 $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ >> (LDFLAGS) >> + -$(CC) $(CPPFLAGS) $(CFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ >> (LDFLAGS) >> >> Output/%.native: $(SourceDir)/%.cpp Output/.dir >> - -$(CXX) -O2 $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ >> (LDFLAGS) >> + -$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $ >> (LDFLAGS) >> >> >> bugpoint-gccas bugpoint-opt bugpoint-llvm-ld bugpoint-gccld >> bugpoint-jit bugpoint-llc bugpoint-llc-beta: >> >> Modified: test-suite/trunk/TEST.nightly.Makefile >> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/ >> TEST.nightly.Makefile?rev=45883&r1=45882&r2=45883&view=diff >> >> ===================================================================== >> = >> ======== >> --- test-suite/trunk/TEST.nightly.Makefile (original) >> +++ test-suite/trunk/TEST.nightly.Makefile Fri Jan 11 15:20:45 2008 >> @@ -8,7 +8,6 @@ >> CURDIR := $(shell cd .; pwd) >> PROGDIR := $(PROJ_SRC_ROOT) >> RELDIR := $(subst $(PROGDIR),,$(CURDIR)) >> -CFLAGS := -O3 >> >> REPORTS_TO_GEN := compile nat >> ifndef DISABLE_LLC >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Fri Jan 11 16:17:28 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 14:17:28 -0800 Subject: [llvm-commits] [llvm] r45884 - in /llvm/trunk: lib/AsmParser/llvmAsmParser.y test/Assembler/2008-01-11-VarargAttrs.ll In-Reply-To: <200801112123.m0BLNe3L027098@zion.cs.uiuc.edu> References: <200801112123.m0BLNe3L027098@zion.cs.uiuc.edu> Message-ID: Thanks Duncan! Evan On Jan 11, 2008, at 1:23 PM, Duncan Sands wrote: > Author: baldrick > Date: Fri Jan 11 15:23:39 2008 > New Revision: 45884 > > URL: http://llvm.org/viewvc/llvm-project?rev=45884&view=rev > Log: > If there are attributes on the varargs part of a > call, don't discard them. > > Added: > llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll > Modified: > llvm/trunk/lib/AsmParser/llvmAsmParser.y > > Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/ > llvmAsmParser.y?rev=45884&r1=45883&r2=45884&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original) > +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Fri Jan 11 15:23:39 2008 > @@ -2675,8 +2675,15 @@ > > if (Ty->isVarArg()) { > if (I == E) > - for (; ArgI != ArgE; ++ArgI) > + for (; ArgI != ArgE; ++ArgI, ++index) { > Args.push_back(ArgI->Val); // push the remaining varargs > + if (ArgI->Attrs != ParamAttr::None) { > + ParamAttrsWithIndex PAWI; > + PAWI.index = index; > + PAWI.attrs = ArgI->Attrs; > + Attrs.push_back(PAWI); > + } > + } > } else if (I != E || ArgI != ArgE) > GEN_ERROR("Invalid number of parameters detected"); > } > @@ -3006,8 +3013,15 @@ > } > if (Ty->isVarArg()) { > if (I == E) > - for (; ArgI != ArgE; ++ArgI) > + for (; ArgI != ArgE; ++ArgI, ++index) { > Args.push_back(ArgI->Val); // push the remaining varargs > + if (ArgI->Attrs != ParamAttr::None) { > + ParamAttrsWithIndex PAWI; > + PAWI.index = index; > + PAWI.attrs = ArgI->Attrs; > + Attrs.push_back(PAWI); > + } > + } > } else if (I != E || ArgI != ArgE) > GEN_ERROR("Invalid number of parameters detected"); > } > > Added: llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/ > 2008-01-11-VarargAttrs.ll?rev=45884&view=auto > > ====================================================================== > ======== > --- llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll (added) > +++ llvm/trunk/test/Assembler/2008-01-11-VarargAttrs.ll Fri Jan 11 > 15:23:39 2008 > @@ -0,0 +1,10 @@ > +; RUN: llvm-as < %s | llvm-dis | grep byval | count 2 > + > + %struct = type { } > + > +declare void @foo(...) > + > +define void @bar() { > + call void (...)* @foo(%struct* byval null, %struct* byval null ) > + ret void > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Fri Jan 11 16:31:43 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 22:31:43 -0000 Subject: [llvm-commits] [llvm] r45886 - in /llvm/trunk: lib/Transforms/IPO/ArgumentPromotion.cpp test/Transforms/ArgumentPromotion/byval.ll Message-ID: <200801112231.m0BMVhoX030573@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 16:31:41 2008 New Revision: 45886 URL: http://llvm.org/viewvc/llvm-project?rev=45886&view=rev Log: Teach argpromote to ruthlessly hack small byval structs when it can get away with it, which exposes opportunities to eliminate the memory objects entirely. For example, we now compile byval.ll to: define internal void @f1(i32 %b.0, i64 %b.1) { entry: %tmp2 = add i32 %b.0, 1 ; [#uses=0] ret void } define i32 @main() nounwind { entry: call void @f1( i32 1, i64 2 ) ret i32 0 } This seems like it would trigger a lot for code that passes around small structs (e.g. SDOperand's or _Complex)... Added: llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45886&r1=45885&r2=45886&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Fri Jan 11 16:31:41 2008 @@ -51,6 +51,7 @@ STATISTIC(NumArgumentsPromoted , "Number of pointer arguments promoted"); STATISTIC(NumAggregatesPromoted, "Number of aggregate arguments promoted"); +STATISTIC(NumByValArgsPromoted , "Number of byval arguments promoted"); STATISTIC(NumArgumentsDead , "Number of dead pointer args eliminated"); namespace { @@ -71,7 +72,8 @@ bool PromoteArguments(CallGraphNode *CGN); bool isSafeToPromoteArgument(Argument *Arg, bool isByVal) const; Function *DoPromotion(Function *F, - SmallPtrSet &ArgsToPromote); + SmallPtrSet &ArgsToPromote, + SmallPtrSet &ByValArgsToTransform); }; char ArgPromotion::ID = 0; @@ -134,16 +136,44 @@ // Check to see which arguments are promotable. If an argument is promotable, // add it to ArgsToPromote. SmallPtrSet ArgsToPromote; + SmallPtrSet ByValArgsToTransform; for (unsigned i = 0; i != PointerArgs.size(); ++i) { - bool isByVal = F->paramHasAttr(PointerArgs[i].second, ParamAttr::ByVal); - if (isSafeToPromoteArgument(PointerArgs[i].first, isByVal)) - ArgsToPromote.insert(PointerArgs[i].first); + bool isByVal = F->paramHasAttr(PointerArgs[i].second+1, ParamAttr::ByVal); + + // If this is a byval argument, and if the aggregate type is small, just + // pass the elements, which is always safe. + Argument *PtrArg = PointerArgs[i].first; + if (isByVal) { + const Type *AgTy = cast(PtrArg->getType())->getElementType(); + if (const StructType *STy = dyn_cast(AgTy)) + if (STy->getNumElements() <= 3) { + // If all the elements are first class types, we can promote it. + bool AllSimple = true; + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + if (!STy->getElementType(i)->isFirstClassType()) { + AllSimple = false; + break; + } + + // Safe to transform, don't even bother trying to "promote" it. + // Passing the elements as a scalar will allow scalarrepl to hack on + // the new alloca we introduce. + if (AllSimple) { + ByValArgsToTransform.insert(PtrArg); + continue; + } + } + } + + // Otherwise, see if we can promote the pointer to its value. + if (isSafeToPromoteArgument(PtrArg, isByVal)) + ArgsToPromote.insert(PtrArg); } // No promotable pointer arguments. - if (ArgsToPromote.empty()) return false; + if (ArgsToPromote.empty() && ByValArgsToTransform.empty()) return false; - Function *NewF = DoPromotion(F, ArgsToPromote); + Function *NewF = DoPromotion(F, ArgsToPromote, ByValArgsToTransform); // Update the call graph to know that the function has been transformed. getAnalysis().changeFunction(F, NewF); @@ -344,7 +374,8 @@ /// arguments, and returns the new function. At this point, we know that it's /// safe to do so. Function *ArgPromotion::DoPromotion(Function *F, - SmallPtrSet &ArgsToPromote) { + SmallPtrSet &ArgsToPromote, + SmallPtrSet &ByValArgsToTransform) { // Start by computing a new prototype for the function, which is the same as // the old function, but has modified arguments. @@ -375,15 +406,18 @@ unsigned index = 1; for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; - ++I, ++index) - if (!ArgsToPromote.count(I)) { + ++I, ++index) { + if (ByValArgsToTransform.count(I)) { + // Just add all the struct element types. + const Type *AgTy = cast(I->getType())->getElementType(); + const StructType *STy = cast(AgTy); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) + Params.push_back(STy->getElementType(i)); + ++NumByValArgsPromoted; + } else if (!ArgsToPromote.count(I)) { Params.push_back(I->getType()); - if (PAL) { - unsigned attrs = PAL->getParamAttrs(index); - if (attrs) - ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(), - attrs)); - } + if (unsigned attrs = PAL ? PAL->getParamAttrs(index) : 0) + ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(), attrs)); } else if (I->use_empty()) { ++NumArgumentsDead; } else { @@ -416,6 +450,7 @@ else ++NumAggregatesPromoted; } + } const Type *RetTy = FTy->getReturnType(); @@ -462,9 +497,22 @@ CallSite::arg_iterator AI = CS.arg_begin(); for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I, ++AI) - if (!ArgsToPromote.count(I)) + if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) { Args.push_back(*AI); // Unmodified argument - else if (!I->use_empty()) { + } else if (ByValArgsToTransform.count(I)) { + // Emit a GEP and load for each element of the struct. + const Type *AgTy = cast(I->getType())->getElementType(); + const StructType *STy = cast(AgTy); + Value *Idxs[2] = { ConstantInt::get(Type::Int32Ty, 0), 0 }; + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + Idxs[1] = ConstantInt::get(Type::Int32Ty, i); + Value *Idx = new GetElementPtrInst(*AI, Idxs, Idxs+2, + (*AI)->getName()+"."+utostr(i), + Call); + // TODO: Tell AA about the new values? + Args.push_back(new LoadInst(Idx, Idx->getName()+".val", Call)); + } + } else if (!I->use_empty()) { // Non-dead argument: insert GEPs and loads as appropriate. ScalarizeTable &ArgIndices = ScalarizedElements[I]; for (ScalarizeTable::iterator SI = ArgIndices.begin(), @@ -526,71 +574,103 @@ // the new arguments, also transfering over the names as well. // for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(), - I2 = NF->arg_begin(); I != E; ++I) - if (!ArgsToPromote.count(I)) { + I2 = NF->arg_begin(); I != E; ++I) { + if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) { // If this is an unmodified argument, move the name and users over to the // new version. I->replaceAllUsesWith(I2); I2->takeName(I); AA.replaceWithNewValue(I, I2); ++I2; - } else if (I->use_empty()) { + continue; + } + + if (ByValArgsToTransform.count(I)) { + // In the callee, we create an alloca, and store each of the new incoming + // arguments into the alloca. + Instruction *InsertPt = NF->begin()->begin(); + + // Just add all the struct element types. + const Type *AgTy = cast(I->getType())->getElementType(); + Value *TheAlloca = new AllocaInst(AgTy, 0, "", InsertPt); + const StructType *STy = cast(AgTy); + Value *Idxs[2] = { ConstantInt::get(Type::Int32Ty, 0), 0 }; + + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + Idxs[1] = ConstantInt::get(Type::Int32Ty, i); + Value *Idx = new GetElementPtrInst(TheAlloca, Idxs, Idxs+2, + TheAlloca->getName()+"."+utostr(i), + InsertPt); + I2->setName(I->getName()+"."+utostr(i)); + new StoreInst(I2++, Idx, InsertPt); + } + + // Anything that used the arg should now use the alloca. + I->replaceAllUsesWith(TheAlloca); + TheAlloca->takeName(I); + AA.replaceWithNewValue(I, TheAlloca); + continue; + } + + if (I->use_empty()) { AA.deleteValue(I); - } else { - // Otherwise, if we promoted this argument, then all users are load - // instructions, and all loads should be using the new argument that we - // added. - ScalarizeTable &ArgIndices = ScalarizedElements[I]; - - while (!I->use_empty()) { - if (LoadInst *LI = dyn_cast(I->use_back())) { - assert(ArgIndices.begin()->empty() && - "Load element should sort to front!"); - I2->setName(I->getName()+".val"); - LI->replaceAllUsesWith(I2); - AA.replaceWithNewValue(LI, I2); - LI->eraseFromParent(); - DOUT << "*** Promoted load of argument '" << I->getName() - << "' in function '" << F->getName() << "'\n"; - } else { - GetElementPtrInst *GEP = cast(I->use_back()); - std::vector Operands(GEP->op_begin()+1, GEP->op_end()); - - Function::arg_iterator TheArg = I2; - for (ScalarizeTable::iterator It = ArgIndices.begin(); - *It != Operands; ++It, ++TheArg) { - assert(It != ArgIndices.end() && "GEP not handled??"); - } + continue; + } + + // Otherwise, if we promoted this argument, then all users are load + // instructions, and all loads should be using the new argument that we + // added. + ScalarizeTable &ArgIndices = ScalarizedElements[I]; + + while (!I->use_empty()) { + if (LoadInst *LI = dyn_cast(I->use_back())) { + assert(ArgIndices.begin()->empty() && + "Load element should sort to front!"); + I2->setName(I->getName()+".val"); + LI->replaceAllUsesWith(I2); + AA.replaceWithNewValue(LI, I2); + LI->eraseFromParent(); + DOUT << "*** Promoted load of argument '" << I->getName() + << "' in function '" << F->getName() << "'\n"; + } else { + GetElementPtrInst *GEP = cast(I->use_back()); + std::vector Operands(GEP->op_begin()+1, GEP->op_end()); + + Function::arg_iterator TheArg = I2; + for (ScalarizeTable::iterator It = ArgIndices.begin(); + *It != Operands; ++It, ++TheArg) { + assert(It != ArgIndices.end() && "GEP not handled??"); + } - std::string NewName = I->getName(); - for (unsigned i = 0, e = Operands.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast(Operands[i])) - NewName += "." + CI->getValue().toStringUnsigned(10); - else - NewName += ".x"; - TheArg->setName(NewName+".val"); - - DOUT << "*** Promoted agg argument '" << TheArg->getName() - << "' of function '" << F->getName() << "'\n"; - - // All of the uses must be load instructions. Replace them all with - // the argument specified by ArgNo. - while (!GEP->use_empty()) { - LoadInst *L = cast(GEP->use_back()); - L->replaceAllUsesWith(TheArg); - AA.replaceWithNewValue(L, TheArg); - L->eraseFromParent(); - } - AA.deleteValue(GEP); - GEP->eraseFromParent(); + std::string NewName = I->getName(); + for (unsigned i = 0, e = Operands.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(Operands[i])) + NewName += "." + CI->getValue().toStringUnsigned(10); + else + NewName += ".x"; + TheArg->setName(NewName+".val"); + + DOUT << "*** Promoted agg argument '" << TheArg->getName() + << "' of function '" << F->getName() << "'\n"; + + // All of the uses must be load instructions. Replace them all with + // the argument specified by ArgNo. + while (!GEP->use_empty()) { + LoadInst *L = cast(GEP->use_back()); + L->replaceAllUsesWith(TheArg); + AA.replaceWithNewValue(L, TheArg); + L->eraseFromParent(); } + AA.deleteValue(GEP); + GEP->eraseFromParent(); } - - // Increment I2 past all of the arguments added for this promoted pointer. - for (unsigned i = 0, e = ArgIndices.size(); i != e; ++i) - ++I2; } + // Increment I2 past all of the arguments added for this promoted pointer. + for (unsigned i = 0, e = ArgIndices.size(); i != e; ++i) + ++I2; + } + // Notify the alias analysis implementation that we inserted a new argument. if (ExtraArgHack) AA.copyValue(Constant::getNullValue(Type::Int32Ty), NF->arg_begin()); Added: llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll?rev=45886&view=auto ============================================================================== --- llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll (added) +++ llvm/trunk/test/Transforms/ArgumentPromotion/byval.ll Fri Jan 11 16:31:41 2008 @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -argpromotion -scalarrepl | llvm-dis | not grep load +; Argpromote + scalarrepl should change this to passing the two integers by value. + + %struct.ss = type { i32, i64 } + +define internal void @f(%struct.ss* byval %b) nounwind { +entry: + %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; [#uses=2] + %tmp1 = load i32* %tmp, align 4 ; [#uses=1] + %tmp2 = add i32 %tmp1, 1 ; [#uses=1] + store i32 %tmp2, i32* %tmp, align 4 + ret void +} + +define i32 @main() nounwind { +entry: + %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] + %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] + store i32 1, i32* %tmp1, align 8 + %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; [#uses=1] + store i64 2, i64* %tmp4, align 4 + call void @f( %struct.ss* byval %S ) nounwind + ret i32 0 +} From baldrick at free.fr Fri Jan 11 16:36:49 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Jan 2008 22:36:49 -0000 Subject: [llvm-commits] [llvm] r45887 - in /llvm/trunk: include/llvm/ParameterAttributes.h lib/VMCore/Verifier.cpp test/Verifier/2008-01-11-VarargAttrs.ll Message-ID: <200801112236.m0BMan1F030843@zion.cs.uiuc.edu> Author: baldrick Date: Fri Jan 11 16:36:48 2008 New Revision: 45887 URL: http://llvm.org/viewvc/llvm-project?rev=45887&view=rev Log: Do not allow attributes beyond a function's last parameter, even if it is a varargs function. Do allow attributes on the varargs part of a call, but not beyond the last argument. Only allow selected attributes to be on the varargs part of a call (currently only 'byval' is allowed). The reasoning here is that most attributes, eg inreg, simply make no sense here. Added: llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll Modified: llvm/trunk/include/llvm/ParameterAttributes.h llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/ParameterAttributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=45887&r1=45886&r2=45887&view=diff ============================================================================== --- llvm/trunk/include/llvm/ParameterAttributes.h (original) +++ llvm/trunk/include/llvm/ParameterAttributes.h Fri Jan 11 16:36:48 2008 @@ -52,6 +52,9 @@ /// @brief Attributes that only apply to function return values. const uint16_t ReturnOnly = NoReturn | NoUnwind | ReadNone | ReadOnly; +/// @brief Attributes that can apply to vararg call arguments. +const uint16_t VarArgsCompatible = ByVal; + /// @brief Attributes that are mutually incompatible. const uint16_t MutuallyIncompatible[3] = { ByVal | InReg | Nest | StructRet, Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=45887&r1=45886&r2=45887&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Fri Jan 11 16:36:48 2008 @@ -390,11 +390,6 @@ if (!Attrs) return; - Assert1(FT->isVarArg() || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()), - "Attributes after end of type!", V); - bool SawNest = false; for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) { @@ -450,8 +445,15 @@ Assert1(!F.isStructReturn() || FT->getReturnType() == Type::VoidTy, "Invalid struct-return function!", &F); + const ParamAttrsList *Attrs = F.getParamAttrs(); + + Assert1(!Attrs || + (Attrs->size() && + Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()), + "Attributes after last parameter!", &F); + // Check function attributes. - VerifyParamAttrs(FT, F.getParamAttrs(), &F); + VerifyParamAttrs(FT, Attrs, &F); // Check that this function meets the restrictions on this calling convention. switch (F.getCallingConv()) { @@ -847,8 +849,24 @@ "Call parameter type does not match function signature!", CS.getArgument(i), FTy->getParamType(i), I); + const ParamAttrsList *Attrs = CS.getParamAttrs(); + + Assert1(!Attrs || + (Attrs->size() && + Attrs->getParamIndex(Attrs->size()-1) <= CS.arg_size()), + "Attributes after last argument!", I); + // Verify call attributes. - VerifyParamAttrs(FTy, CS.getParamAttrs(), I); + VerifyParamAttrs(FTy, Attrs, I); + + if (Attrs && FTy->isVarArg()) + // Check attributes on the varargs part. + for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { + uint16_t Attr = Attrs->getParamAttrs(Idx); + uint16_t VArgI = Attr & ~ParamAttr::VarArgsCompatible; + Assert1(!VArgI, "Attribute " + Attrs->getParamAttrsText(VArgI) + + "cannot be used for vararg call arguments!", I); + } visitInstruction(*I); } Added: llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll?rev=45887&view=auto ============================================================================== --- llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll (added) +++ llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll Fri Jan 11 16:36:48 2008 @@ -0,0 +1,10 @@ +; RUN: not llvm-as < %s + + %struct = type { } + +declare void @foo(...) + +define void @bar() { + call void (...)* @foo(%struct* inreg null ) + ret void +} From sabre at nondot.org Fri Jan 11 17:04:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 23:04:14 -0000 Subject: [llvm-commits] [llvm] r45888 - /llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Message-ID: <200801112304.m0BN4EQg032018@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 17:04:14 2008 New Revision: 45888 URL: http://llvm.org/viewvc/llvm-project?rev=45888&view=rev Log: new testcase Added: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Added: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B%2BFrontend/2008-01-11-BadWarning.cpp?rev=45888&view=auto ============================================================================== --- llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp (added) +++ llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Fri Jan 11 17:04:14 2008 @@ -0,0 +1,6 @@ +// RUN: %llvmgcc -xc++ %s -S -o /dev/null |& not grep warning +// rdar://5683899 +void** f(void **Buckets, unsigned NumBuckets) { + return Buckets + NumBuckets; +} + From sabre at nondot.org Fri Jan 11 17:05:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 23:05:10 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45889 - /llvm-gcc-4.2/trunk/gcc/cp/typeck.c Message-ID: <200801112305.m0BN5AnK032072@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 17:05:10 2008 New Revision: 45889 URL: http://llvm.org/viewvc/llvm-project?rev=45889&view=rev Log: Do not emit a warning for code like this: void** f(void **Buckets, unsigned NumBuckets) { return Buckets + NumBuckets; } This was already fixed in the C FE, but the C++ FE needed a matching fix. Testcase here: test/C++Frontend/2008-01-11-BadWarning.cpp Modified: llvm-gcc-4.2/trunk/gcc/cp/typeck.c Modified: llvm-gcc-4.2/trunk/gcc/cp/typeck.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/typeck.c?rev=45889&r1=45888&r2=45889&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/cp/typeck.c (original) +++ llvm-gcc-4.2/trunk/gcc/cp/typeck.c Fri Jan 11 17:05:10 2008 @@ -6764,7 +6764,17 @@ while (TREE_CODE (whats_returned) == COMPONENT_REF || TREE_CODE (whats_returned) == ARRAY_REF) + /* LLVM LOCAL begin */ + { +#ifdef ENABLE_LLVM + if (TREE_CODE (whats_returned) == ARRAY_REF + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (whats_returned, 0))) + != ARRAY_TYPE)) + break; /* Ignore pointer base of array ref extension. */ +#endif whats_returned = TREE_OPERAND (whats_returned, 0); + } + /* LLVM LOCAL end */ if (DECL_P (whats_returned) && DECL_NAME (whats_returned) From sabre at nondot.org Fri Jan 11 17:06:56 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 23:06:56 -0000 Subject: [llvm-commits] [llvm] r45890 - /llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Message-ID: <200801112306.m0BN6uuN032171@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 17:06:56 2008 New Revision: 45890 URL: http://llvm.org/viewvc/llvm-project?rev=45890&view=rev Log: llvm-g++ 4.0 has completely different code for this warning, just xfail it. Modified: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Modified: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B%2BFrontend/2008-01-11-BadWarning.cpp?rev=45890&r1=45889&r2=45890&view=diff ============================================================================== --- llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp (original) +++ llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Fri Jan 11 17:06:56 2008 @@ -1,5 +1,6 @@ // RUN: %llvmgcc -xc++ %s -S -o /dev/null |& not grep warning // rdar://5683899 +// XFAIL: llvmgcc4.0.1 void** f(void **Buckets, unsigned NumBuckets) { return Buckets + NumBuckets; } From evan.cheng at apple.com Fri Jan 11 17:10:12 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Jan 2008 23:10:12 -0000 Subject: [llvm-commits] [llvm] r45891 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200801112310.m0BNACVZ032369@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 17:10:11 2008 New Revision: 45891 URL: http://llvm.org/viewvc/llvm-project?rev=45891&view=rev Log: More cbe byval fixes. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=45891&r1=45890&r2=45891&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Fri Jan 11 17:10:11 2008 @@ -1908,18 +1908,24 @@ } else { // Loop over the arguments, printing them. FunctionType::param_iterator I = FT->param_begin(), E = FT->param_end(); + unsigned Idx = 1; // If this is a struct-return function, don't print the hidden // struct-return argument. if (isStructReturn) { assert(I != E && "Invalid struct return function!"); ++I; + ++Idx; } - unsigned Idx = 1; for (; I != E; ++I) { if (PrintedArg) FunctionInnards << ", "; - printType(FunctionInnards, *I, + const Type *ArgTy = *I; + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa(ArgTy)); + ArgTy = cast(ArgTy)->getElementType(); + } + printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt)); PrintedArg = true; ++Idx; @@ -2628,9 +2634,11 @@ const ParamAttrsList *PAL = I.getParamAttrs(); bool isStructRet = I.isStructReturn(); if (isStructRet) { - Out << "*("; + bool isByVal = ByValParams.count(I.getOperand(1)); + if (!isByVal) Out << "*("; writeOperand(I.getOperand(1)); - Out << ") = "; + if (!isByVal) Out << ")"; + Out << " = "; } if (I.isTailCall()) Out << " /*tail*/ "; @@ -2685,22 +2693,26 @@ } bool PrintedArg = false; - unsigned Idx = 1; - for (; AI != AE; ++AI, ++ArgNo, ++Idx) { + for (; AI != AE; ++AI, ++ArgNo) { if (PrintedArg) Out << ", "; if (ArgNo < NumDeclaredParams && (*AI)->getType() != FTy->getParamType(ArgNo)) { Out << '('; printType(Out, FTy->getParamType(ArgNo), - /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt)); + /*isSigned=*/PAL && PAL->paramHasAttr(ArgNo+1, ParamAttr::SExt)); Out << ')'; } - // If call is expecting argument to be passed by value, then do not - // take its address. - if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) - writeOperandInternal(*AI); - else - writeOperand(*AI); + // Check if the argument is expected to be passed by value. + bool isOutByVal = PAL && PAL->paramHasAttr(ArgNo+1, ParamAttr::ByVal); + // Check if this argument itself is passed in by reference. + bool isInByVal = ByValParams.count(*AI); + if (isOutByVal && !isInByVal) + Out << "*("; + else if (!isOutByVal && isInByVal) + Out << "&("; + writeOperand(*AI); + if (isOutByVal ^ isInByVal) + Out << ")"; PrintedArg = true; } Out << ')'; From baldrick at free.fr Fri Jan 11 17:13:45 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Jan 2008 23:13:45 -0000 Subject: [llvm-commits] [llvm] r45892 - in /llvm/trunk: lib/Transforms/IPO/DeadArgumentElimination.cpp test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll Message-ID: <200801112313.m0BNDkq5032619@zion.cs.uiuc.edu> Author: baldrick Date: Fri Jan 11 17:13:45 2008 New Revision: 45892 URL: http://llvm.org/viewvc/llvm-project?rev=45892&view=rev Log: When DAE drops the varargs part of a function, ensure any attributes on the vararg call arguments are also dropped. Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp llvm/trunk/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=45892&r1=45891&r2=45892&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Fri Jan 11 17:13:45 2008 @@ -175,16 +175,29 @@ // Pass all the same arguments. Args.assign(CS.arg_begin(), CS.arg_begin()+NumArgs); + // Drop any attributes that were on the vararg arguments. + const ParamAttrsList *PAL = CS.getParamAttrs(); + if (PAL && PAL->getParamIndex(PAL->size() - 1) > NumArgs) { + ParamAttrsVector ParamAttrsVec; + for (unsigned i = 0; PAL->getParamIndex(i) <= NumArgs; ++i) { + ParamAttrsWithIndex PAWI; + PAWI = ParamAttrsWithIndex::get(PAL->getParamIndex(i), + PAL->getParamAttrsAtIndex(i)); + ParamAttrsVec.push_back(PAWI); + } + PAL = ParamAttrsList::get(ParamAttrsVec); + } + Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(), Args.begin(), Args.end(), "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setParamAttrs(CS.getParamAttrs()); + cast(New)->setParamAttrs(PAL); } else { New = new CallInst(NF, Args.begin(), Args.end(), "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setParamAttrs(CS.getParamAttrs()); + cast(New)->setParamAttrs(PAL); if (cast(Call)->isTailCall()) cast(New)->setTailCall(); } Modified: llvm/trunk/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll?rev=45892&r1=45891&r2=45892&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll (original) +++ llvm/trunk/test/Transforms/DeadArgElim/2007-12-20-ParamAttrs.ll Fri Jan 11 17:13:45 2008 @@ -2,6 +2,9 @@ ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | grep signext | count 2 ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | not grep inreg ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | not grep zeroext +; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | not grep byval + + %struct = type { } @g = global i8 0 @@ -11,6 +14,6 @@ } define i32 @bar() { - %A = call i8(i8*, i8, ...)* @foo(i8* inreg null, i8 signext 1, i8 2) zeroext nounwind + %A = call i8(i8*, i8, ...)* @foo(i8* inreg null, i8 signext 1, %struct* byval null ) zeroext nounwind ret i32 0 } From sabre at nondot.org Fri Jan 11 17:25:16 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 11 Jan 2008 23:25:16 -0000 Subject: [llvm-commits] [llvm] r45893 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200801112325.m0BNPH5g000671@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 17:25:16 2008 New Revision: 45893 URL: http://llvm.org/viewvc/llvm-project?rev=45893&view=rev Log: remove some incorrect classof's. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=45893&r1=45892&r2=45893&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Fri Jan 11 17:25:16 2008 @@ -1543,7 +1543,6 @@ MVT::ValueType getLoadedVT() const { return LoadedVT; } static bool classof(const LoadSDNode *) { return true; } - static bool classof(const LSBaseSDNode *N) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD; } @@ -1586,7 +1585,6 @@ MVT::ValueType getStoredVT() const { return StoredVT; } static bool classof(const StoreSDNode *) { return true; } - static bool classof(const LSBaseSDNode *N) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::STORE; } From sabre at nondot.org Fri Jan 11 18:17:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 00:17:42 -0000 Subject: [llvm-commits] [llvm] r45894 - /llvm/trunk/lib/CodeGen/MachineSink.cpp Message-ID: <200801120017.m0C0HgJp003295@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 18:17:41 2008 New Revision: 45894 URL: http://llvm.org/viewvc/llvm-project?rev=45894&view=rev Log: implement support for sinking a load out the bottom of a block that has no stores between the load and the end of block. This works great and sinks hundreds of stores, but we can't turn it on because machineinstrs don't have volatility information and we don't want to sink volatile stores :( Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=45894&r1=45893&r2=45894&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSink.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSink.cpp Fri Jan 11 18:17:41 2008 @@ -47,7 +47,7 @@ } private: bool ProcessBlock(MachineBasicBlock &MBB); - bool SinkInstruction(MachineInstr *MI); + bool SinkInstruction(MachineInstr *MI, bool &SawStore); bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB) const; }; @@ -115,10 +115,11 @@ // Can't sink anything out of a block that has less than two successors. if (MBB.succ_size() <= 1) return false; - // Walk the basic block bottom-up + // Walk the basic block bottom-up. Remember if we saw a store. + bool SawStore = false; for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ){ MachineBasicBlock::iterator LastIt = I; - if (SinkInstruction(--I)) { + if (SinkInstruction(--I, SawStore)) { I = LastIt; ++NumSunk; } @@ -129,24 +130,30 @@ /// SinkInstruction - Determine whether it is safe to sink the specified machine /// instruction out of its current block into a successor. -bool MachineSinking::SinkInstruction(MachineInstr *MI) { +bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { const TargetInstrDesc &TID = MI->getDesc(); // Ignore stuff that we obviously can't sink. - if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() || - TID.hasUnmodeledSideEffects()) + if (TID.mayStore() || TID.isCall()) { + SawStore = true; + return false; + } + if (TID.isReturn() || TID.isBranch() || TID.hasUnmodeledSideEffects()) return false; - if (TID.mayLoad()) { - // Okay, this instruction does a load. As a refinement, allow the target - // to decide whether the loaded value is actually a constant. If so, we - // can actually use it as a load. - if (!TII->isInvariantLoad(MI)) { - // FIXME: we should be able to sink loads with no other side effects if - // there is nothing that can change memory from here until the end of - // block. This is a trivial form of alias analysis. - return false; - } + // See if this instruction does a load. If so, we have to guarantee that the + // loaded value doesn't change between the load and the end of block. The + // check for isInvariantLoad gives the targe the chance to classify the load + // as always returning a constant, e.g. a constant pool load. + if (TID.mayLoad() && !TII->isInvariantLoad(MI)) { + // Otherwise, this is a real load. If there is a store between the load and + // end of block, we can't sink the load. + // + // FIXME: we can't do this transformation until we know that the load is + // not volatile, and machineinstrs don't keep this info. :( + // + //if (SawStore) + return false; } // FIXME: This should include support for sinking instructions within the From sabre at nondot.org Fri Jan 11 18:35:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 00:35:10 -0000 Subject: [llvm-commits] [llvm] r45895 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200801120035.m0C0ZArT004899@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 18:35:08 2008 New Revision: 45895 URL: http://llvm.org/viewvc/llvm-project?rev=45895&view=rev Log: Any x86 instruction that reads from an invariant location is invariant. This allows us to sink things like: cvtsi2sd 32(%esp), %xmm1 when reading from the argument area, for example. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45895&r1=45894&r2=45895&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Jan 11 18:35:08 2008 @@ -758,54 +758,35 @@ /// only return true of *all* loads the instruction does are invariant (if it /// does multiple loads). bool X86InstrInfo::isInvariantLoad(MachineInstr *MI) const { - // FIXME: This should work with any X86 instruction that does a load, for - // example, all load+op instructions. - switch (MI->getOpcode()) { - default: break; - case X86::MOV32rm: - // Loads from stubs of global addresses are invariant. - if (MI->getOperand(1).isReg() && - MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && - MI->getOperand(4).isGlobal() && - TM.getSubtarget().GVRequiresExtraLoad - (MI->getOperand(4).getGlobal(), TM, false) && - MI->getOperand(2).getImm() == 1 && - MI->getOperand(3).getReg() == 0) - return true; - // FALLTHROUGH - case X86::MOV8rm: - case X86::MOV16rm: - case X86::MOV16_rm: - case X86::MOV32_rm: - case X86::MOV64rm: - case X86::LD_Fp64m: - case X86::MOVSSrm: - case X86::MOVSDrm: - case X86::MOVAPSrm: - case X86::MOVAPDrm: - case X86::MMX_MOVD64rm: - case X86::MMX_MOVQ64rm: + // This code cares about loads from three cases: constant pool entries, + // invariant argument slots, and global stubs. In order to handle these cases + // for all of the myriad of X86 instructions, we just scan for a CP/FI/GV + // operand and base are analysis on it. This is safe because the address of + // none of these three cases is ever used as anything other than a load base + // and X86 doesn't have any instructions that load from multiple places. + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); // Loads from constant pools are trivially invariant. - if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && - MI->getOperand(3).isReg() && MI->getOperand(4).isCPI() && - MI->getOperand(1).getReg() == 0 && - MI->getOperand(2).getImm() == 1 && - MI->getOperand(3).getReg() == 0) + if (MO.isCPI()) return true; - - // If this is a load from a fixed argument slot, we know the value is - // invariant across the whole function, because we don't redefine argument - // values. - MachineFunction *MF = MI->getParent()->getParent(); - if (MI->getOperand(1).isFI()) { - const MachineFrameInfo &MFI = *MF->getFrameInfo(); - int Idx = MI->getOperand(1).getIndex(); + + if (MO.isGlobal()) { + if (TM.getSubtarget().GVRequiresExtraLoad(MO.getGlobal(), + TM, false)) + return true; + return false; + } + + // If this is a load from an invariant stack slot, the load is a constant. + if (MO.isFI()) { + const MachineFrameInfo &MFI = + *MI->getParent()->getParent()->getFrameInfo(); + int Idx = MO.getIndex(); return MFI.isFixedObjectIndex(Idx) && MFI.isImmutableObjectIndex(Idx); } - - return false; } - + // All other instances of these instructions are presumed to have other // issues. return false; From gordonhenriksen at mac.com Fri Jan 11 18:50:28 2008 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Fri, 11 Jan 2008 19:50:28 -0500 Subject: [llvm-commits] [llvm] r45895 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp In-Reply-To: <200801120035.m0C0ZArT004899@zion.cs.uiuc.edu> References: <200801120035.m0C0ZArT004899@zion.cs.uiuc.edu> Message-ID: On 2008-01-11, at 19:35, Chris Lattner wrote: > + // operand and base are analysis on it. This is safe because the > address of Spello. ? Gordon From sabre at nondot.org Fri Jan 11 18:53:16 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 00:53:16 -0000 Subject: [llvm-commits] [llvm] r45896 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200801120053.m0C0rGae006071@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 18:53:16 2008 New Revision: 45896 URL: http://llvm.org/viewvc/llvm-project?rev=45896&view=rev Log: fix a wordo that gordon noticed :) Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45896&r1=45895&r2=45896&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Jan 11 18:53:16 2008 @@ -761,7 +761,7 @@ // This code cares about loads from three cases: constant pool entries, // invariant argument slots, and global stubs. In order to handle these cases // for all of the myriad of X86 instructions, we just scan for a CP/FI/GV - // operand and base are analysis on it. This is safe because the address of + // operand and base our analysis on it. This is safe because the address of // none of these three cases is ever used as anything other than a load base // and X86 doesn't have any instructions that load from multiple places. From evan.cheng at apple.com Fri Jan 11 19:07:41 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 01:07:41 -0000 Subject: [llvm-commits] [llvm] r45897 - /llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Message-ID: <200801120107.m0C17fGB007092@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 19:07:41 2008 New Revision: 45897 URL: http://llvm.org/viewvc/llvm-project?rev=45897&view=rev Log: ByVal arguments are passed on stack. Make sure to allocate a slot using size and alignment information on the parameter attribute. Modified: llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Modified: llvm/trunk/utils/TableGen/CallingConvEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CallingConvEmitter.cpp?rev=45897&r1=45896&r2=45897&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CallingConvEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/CallingConvEmitter.cpp Fri Jan 11 19:07:41 2008 @@ -115,19 +115,32 @@ int Size = Action->getValueAsInt("Size"); int Align = Action->getValueAsInt("Align"); - O << IndentStr << "unsigned Offset" << ++Counter - << " = State.AllocateStack("; + O << IndentStr << "unsigned Size = "; if (Size) - O << Size << ", "; + O << Size; else - O << "\n" << IndentStr << " State.getTarget().getTargetData()" - "->getABITypeSize(MVT::getTypeForValueType(LocVT)), "; + O << "State.getTarget().getTargetData()" + "->getABITypeSize(MVT::getTypeForValueType(LocVT))"; + O << ";\n" + << IndentStr << "unsigned Align = "; if (Align) O << Align; else - O << "\n" << IndentStr << " State.getTarget().getTargetData()" + O << "State.getTarget().getTargetData()" "->getABITypeAlignment(MVT::getTypeForValueType(LocVT))"; - O << ");\n" << IndentStr + O << ";\n"; + O << IndentStr << "if (ArgFlags & ISD::ParamFlags::ByVal) {\n"; + O << IndentStr << " " << + "Size = (ArgFlags & ISD::ParamFlags::ByValSize) >> " + "ISD::ParamFlags::ByValSizeOffs;\n"; + O << IndentStr << " " << + "unsigned ParamAlign = 1 << ((ArgFlags & ISD::ParamFlags::ByValAlign) " + ">> ISD::ParamFlags::ByValAlignOffs);\n"; + O << IndentStr << " Align = std::max(Align, ParamAlign);\n" + << IndentStr << "}\n"; + O << IndentStr << "unsigned Offset" << ++Counter + << " = State.AllocateStack(Size, Align);\n"; + O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" << Counter << ", LocVT, LocInfo));\n"; O << IndentStr << "return false;\n"; From evan.cheng at apple.com Fri Jan 11 19:08:07 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 01:08:07 -0000 Subject: [llvm-commits] [llvm] r45898 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801120108.m0C187YC007147@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 19:08:07 2008 New Revision: 45898 URL: http://llvm.org/viewvc/llvm-project?rev=45898&view=rev Log: Code clean up. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45898&r1=45897&r2=45898&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jan 11 19:08:07 2008 @@ -1027,23 +1027,21 @@ return false; } -// GetMemCpyWithFlags - Create a MemCpy using function's parameter flag. +// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified +// by "Src" to address "Dst" with size and alignment information specified by +// the specific parameter attribute. The copy will be passed as a byval function +// parameter. static SDOperand -GetMemCpyWithFlags(SelectionDAG &DAG, unsigned Flags, SDOperand From, - SDOperand To, SDOperand Chain) { - - unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> - ISD::ParamFlags::ByValAlignOffs); - - unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> +CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain, + unsigned Flags, SelectionDAG &DAG) { + unsigned Align = 1 << + ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs); + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> ISD::ParamFlags::ByValSizeOffs; - - SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); - SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32); - - return DAG.getMemcpy(Chain, To, From, SizeNode, AlignNode, - AlwaysInline); + return DAG.getMemcpy(Chain, Dst, Src, SizeNode, AlignNode, AlwaysInline); } SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG, @@ -1260,10 +1258,9 @@ SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); unsigned Flags = cast(FlagsOp)->getValue(); if (Flags & ISD::ParamFlags::ByVal) { - return GetMemCpyWithFlags(DAG, Flags, Arg, PtrOff, Chain); - } else { - return DAG.getStore(Chain, Arg, PtrOff, NULL, 0); + return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG); } + return DAG.getStore(Chain, Arg, PtrOff, NULL, 0); } SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { @@ -1438,7 +1435,7 @@ FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); FIN = DAG.getFrameIndex(FI, MVT::i32); SDOperand Source = Arg; - if (IsPossiblyOverwrittenArgumentOfTailCall(Arg)){ + if (IsPossiblyOverwrittenArgumentOfTailCall(Arg)) { // Copy from stack slots to stack slot of a tail called function. This // needs to be done because if we would lower the arguments directly // to their real stack slot we might end up overwriting each other. @@ -1452,12 +1449,12 @@ } if (Flags & ISD::ParamFlags::ByVal) { - // Copy relative to framepointer. - MemOpChains2. - push_back(GetMemCpyWithFlags(DAG, Flags, Source, FIN, Chain)); + // Copy relative to framepointer. + MemOpChains2.push_back(CreateCopyOfByValArgument(Source, FIN, Chain, + Flags, DAG)); } else { - // Store relative to framepointer. - MemOpChains2.push_back(DAG.getStore(Chain, Source, FIN, NULL, 0)); + // Store relative to framepointer. + MemOpChains2.push_back(DAG.getStore(Chain, Source, FIN, NULL, 0)); } } } From lattner at apple.com Fri Jan 11 19:11:38 2008 From: lattner at apple.com (Tanya Lattner) Date: Fri, 11 Jan 2008 17:11:38 -0800 Subject: [llvm-commits] [llvm] r45890 - /llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp In-Reply-To: <200801112306.m0BN6uuN032171@zion.cs.uiuc.edu> References: <200801112306.m0BN6uuN032171@zion.cs.uiuc.edu> Message-ID: It XPASSes with llvm-gcc4.0. I don't think xfail is what you want. I don't think there is a way to specify a test for pass/fail for a specific version of llvm-gcc. I think this was on my todo list awhile back. File a bug. -Tanya On Jan 11, 2008, at 3:06 PM, Chris Lattner wrote: > Author: lattner > Date: Fri Jan 11 17:06:56 2008 > New Revision: 45890 > > URL: http://llvm.org/viewvc/llvm-project?rev=45890&view=rev > Log: > llvm-g++ 4.0 has completely different code for this warning, > just xfail it. > > Modified: > llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp > > Modified: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B% > 2BFrontend/2008-01-11-BadWarning.cpp? > rev=45890&r1=45889&r2=45890&view=diff > > ====================================================================== > ======== > --- llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp (original) > +++ llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Fri Jan > 11 17:06:56 2008 > @@ -1,5 +1,6 @@ > // RUN: %llvmgcc -xc++ %s -S -o /dev/null |& not grep warning > // rdar://5683899 > +// XFAIL: llvmgcc4.0.1 > void** f(void **Buckets, unsigned NumBuckets) { > return Buckets + NumBuckets; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Fri Jan 11 19:45:22 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 01:45:22 -0000 Subject: [llvm-commits] [llvm] r45899 - /llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Message-ID: <200801120145.m0C1jMa0009498@zion.cs.uiuc.edu> Author: lattner Date: Fri Jan 11 19:45:22 2008 New Revision: 45899 URL: http://llvm.org/viewvc/llvm-project?rev=45899&view=rev Log: this actually does pass with 4.0 Modified: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Modified: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B%2BFrontend/2008-01-11-BadWarning.cpp?rev=45899&r1=45898&r2=45899&view=diff ============================================================================== --- llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp (original) +++ llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Fri Jan 11 19:45:22 2008 @@ -1,6 +1,5 @@ // RUN: %llvmgcc -xc++ %s -S -o /dev/null |& not grep warning // rdar://5683899 -// XFAIL: llvmgcc4.0.1 void** f(void **Buckets, unsigned NumBuckets) { return Buckets + NumBuckets; } From clattner at apple.com Fri Jan 11 19:45:41 2008 From: clattner at apple.com (Chris Lattner) Date: Fri, 11 Jan 2008 17:45:41 -0800 Subject: [llvm-commits] [llvm] r45890 - /llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp In-Reply-To: References: <200801112306.m0BN6uuN032171@zion.cs.uiuc.edu> Message-ID: <063201B4-891C-40DC-B4C8-97E63550CBF1@apple.com> On Jan 11, 2008, at 5:11 PM, Tanya Lattner wrote: > It XPASSes with llvm-gcc4.0. I don't think xfail is what you want. I > don't think there is a way to specify a test for pass/fail for a > specific version of llvm-gcc. I think this was on my todo list awhile > back. File a bug. Actually, that's a good thing. I've verified it passes with 4.0 and 4.2, so I can just remove the XFAIL line. Thanks! -Chris > > -Tanya > > > On Jan 11, 2008, at 3:06 PM, Chris Lattner wrote: > >> Author: lattner >> Date: Fri Jan 11 17:06:56 2008 >> New Revision: 45890 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=45890&view=rev >> Log: >> llvm-g++ 4.0 has completely different code for this warning, >> just xfail it. >> >> Modified: >> llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp >> >> Modified: llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B% >> 2BFrontend/2008-01-11-BadWarning.cpp? >> rev=45890&r1=45889&r2=45890&view=diff >> >> = >> ===================================================================== >> ======== >> --- llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp (original) >> +++ llvm/trunk/test/C++Frontend/2008-01-11-BadWarning.cpp Fri Jan >> 11 17:06:56 2008 >> @@ -1,5 +1,6 @@ >> // RUN: %llvmgcc -xc++ %s -S -o /dev/null |& not grep warning >> // rdar://5683899 >> +// XFAIL: llvmgcc4.0.1 >> void** f(void **Buckets, unsigned NumBuckets) { >> return Buckets + NumBuckets; >> } >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Fri Jan 11 22:27:19 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 04:27:19 -0000 Subject: [llvm-commits] [llvm] r45900 - /llvm/trunk/utils/NewNightlyTest.pl Message-ID: <200801120427.m0C4RJ4W026278@zion.cs.uiuc.edu> Author: evancheng Date: Fri Jan 11 22:27:18 2008 New Revision: 45900 URL: http://llvm.org/viewvc/llvm-project?rev=45900&view=rev Log: Add -disable-lto optimization. Modified: llvm/trunk/utils/NewNightlyTest.pl Modified: llvm/trunk/utils/NewNightlyTest.pl URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/NewNightlyTest.pl?rev=45900&r1=45899&r2=45900&view=diff ============================================================================== --- llvm/trunk/utils/NewNightlyTest.pl (original) +++ llvm/trunk/utils/NewNightlyTest.pl Fri Jan 11 22:27:18 2008 @@ -35,6 +35,7 @@ # -disable-llc Disable LLC tests in the nightly tester. # -disable-jit Disable JIT tests in the nightly tester. # -disable-cbe Disable C backend tests in the nightly tester. +# -disable-lto Disable link time optimization. # -verbose Turn on some debug output # -debug Print information useful only to maintainers of this script. # -nice Checkout/Configure/Build with "nice" to reduce impact @@ -152,6 +153,7 @@ if (/^-disable-jit$/) { $PROGTESTOPTS .= " DISABLE_JIT=1"; $CONFIGUREARGS .= " --disable-jit"; next; } if (/^-disable-cbe$/) { $PROGTESTOPTS .= " DISABLE_CBE=1"; next; } + if (/^-disable-lto$/) { $PROGTESTOPTS .= " DISABLE_LTO=1"; next; } if (/^-test-opts$/) { $PROGTESTOPTS .= "$ARGV[0]"; shift; next; } if (/^-verbose$/) { $VERBOSE = 1; next; } if (/^-debug$/) { $DEBUG = 1; next; } From sabre at nondot.org Sat Jan 12 00:46:09 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 06:46:09 -0000 Subject: [llvm-commits] [llvm] r45902 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200801120646.m0C6kAV7001821@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 00:46:09 2008 New Revision: 45902 URL: http://llvm.org/viewvc/llvm-project?rev=45902&view=rev Log: Add support for NetBSD, patch by Krister Walfridsson! Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=45902&r1=45901&r2=45902&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat Jan 12 00:46:09 2008 @@ -1323,7 +1323,7 @@ << "extern void *__builtin_alloca(unsigned int);\n" << "#endif\n" << "#define alloca(x) __builtin_alloca(x)\n" - << "#elif defined(__FreeBSD__) || defined(__OpenBSD__)\n" + << "#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)\n" << "#define alloca(x) __builtin_alloca(x)\n" << "#elif defined(_MSC_VER)\n" << "#define inline _inline\n" From sabre at nondot.org Sat Jan 12 00:49:13 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 06:49:13 -0000 Subject: [llvm-commits] [llvm] r45903 - in /llvm/trunk: include/llvm/Transforms/IPO.h include/llvm/Transforms/IPO/InlinerPass.h lib/Transforms/IPO/InlineSimple.cpp lib/Transforms/IPO/Inliner.cpp Message-ID: <200801120649.m0C6nD3d002031@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 00:49:13 2008 New Revision: 45903 URL: http://llvm.org/viewvc/llvm-project?rev=45903&view=rev Log: Allow clients to specify the inline threshold when creating the inliner pass. Patch by Robert Zeh. Modified: llvm/trunk/include/llvm/Transforms/IPO.h llvm/trunk/include/llvm/Transforms/IPO/InlinerPass.h llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp llvm/trunk/lib/Transforms/IPO/Inliner.cpp Modified: llvm/trunk/include/llvm/Transforms/IPO.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=45903&r1=45902&r2=45903&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/IPO.h (original) +++ llvm/trunk/include/llvm/Transforms/IPO.h Sat Jan 12 00:49:13 2008 @@ -91,6 +91,7 @@ /// to inline direct function calls to small functions. /// Pass *createFunctionInliningPass(); +Pass *createFunctionInliningPass(int Threshold); //===----------------------------------------------------------------------===// /// createPruneEHPass - Return a new pass object which transforms invoke Modified: llvm/trunk/include/llvm/Transforms/IPO/InlinerPass.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/InlinerPass.h?rev=45903&r1=45902&r2=45903&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/IPO/InlinerPass.h (original) +++ llvm/trunk/include/llvm/Transforms/IPO/InlinerPass.h Sat Jan 12 00:49:13 2008 @@ -27,6 +27,7 @@ /// struct Inliner : public CallGraphSCCPass { explicit Inliner(const void *ID); + explicit Inliner(const void *ID, int Threshold); /// getAnalysisUsage - For this class, we declare that we require and preserve /// the call graph. If the derived class implements this method, it should Modified: llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp?rev=45903&r1=45902&r2=45903&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Sat Jan 12 00:49:13 2008 @@ -35,6 +35,7 @@ InlineCostAnalyzer CA; public: SimpleInliner() : Inliner(&ID) {} + SimpleInliner(int Threshold) : Inliner(&ID, Threshold) {} static char ID; // Pass identification, replacement for typeid int getInlineCost(CallSite CS) { return CA.getInlineCost(CS, NeverInline); @@ -47,6 +48,10 @@ Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } +Pass *llvm::createFunctionInliningPass(int Threshold) { + return new SimpleInliner(Threshold); +} + // doInitialization - Initializes the vector of functions that have been // annotated with the noinline attribute. bool SimpleInliner::doInitialization(CallGraph &CG) { Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=45903&r1=45902&r2=45903&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Sat Jan 12 00:49:13 2008 @@ -39,6 +39,9 @@ Inliner::Inliner(const void *ID) : CallGraphSCCPass((intptr_t)ID), InlineThreshold(InlineLimit) {} +Inliner::Inliner(const void *ID, int Threshold) + : CallGraphSCCPass((intptr_t)ID), InlineThreshold(Threshold) {} + /// getAnalysisUsage - For this class, we declare that we require and preserve /// the call graph. If the derived class implements this method, it should /// always explicitly call the implementation here. From sabre at nondot.org Sat Jan 12 01:21:53 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 01:21:53 -0600 Subject: [llvm-commits] CVS: llvm-www/Users.html Message-ID: <200801120721.m0C7Lris003875@zion.cs.uiuc.edu> Changes in directory llvm-www: Users.html updated: 1.24 -> 1.25 --- Log message: add another academic institute, thanks to Pertti Kellomaki --- Diffs of the changes: (+11 -5) Users.html | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) Index: llvm-www/Users.html diff -u llvm-www/Users.html:1.24 llvm-www/Users.html:1.25 --- llvm-www/Users.html:1.24 Wed Oct 31 09:29:25 2007 +++ llvm-www/Users.html Sat Jan 12 01:21:08 2008 @@ -118,17 +118,23 @@ Aspicere2 + + + New York University + Anna Zaks + Validation of interprocedural optimizations + + Rice University Keith Cooper's Research Group - - New York University - Anna Zaks - Validation of interprocedural optimizations + Tampere University of Technology + Jarmo Takala's research group, Department of Computer Systems + The TTA Based Codesign Environment (TCE) project @@ -272,6 +278,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!">
    LLVM Development List
    - Last modified: $Date: 2007/10/31 14:29:25 $ + Last modified: $Date: 2008/01/12 07:21:08 $ From evan.cheng at apple.com Sat Jan 12 03:22:44 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 09:22:44 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45907 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-types.cpp Message-ID: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> Author: evancheng Date: Sat Jan 12 03:22:43 2008 New Revision: 45907 URL: http://llvm.org/viewvc/llvm-project?rev=45907&view=rev Log: Add support for aggregate parameter passing by reference. At the llvm level they look like passing by address but with the ByVal parameter attribute. Code generator will lower them to confirm target ABI's. e.g. X86-32 passes aggregates on stack. Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=45907&r1=45906&r2=45907&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Sat Jan 12 03:22:43 2008 @@ -32,6 +32,7 @@ #include "llvm-internal.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/ParameterAttributes.h" #include "llvm/Target/TargetData.h" namespace llvm { @@ -126,7 +127,15 @@ // would often be 64-bits). #ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS #define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \ - !isSingleElementStructOrArray(type) + !isSingleElementStructOrArray(X) +#endif + +// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate +// value should be passed by reference by passing its address with the byval +// attribute bit set. The default is false. +#ifndef LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X) +#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X) \ + false #endif /// DefaultABI - This class implements the default LLVM ABI where structures are @@ -192,13 +201,17 @@ /// argument and invokes methods on the client that indicate how its pieces /// should be handled. This handles things like decimating structures into /// their fields. - void HandleArgument(tree type) { + void HandleArgument(tree type, uint16_t *Attributes = NULL) { const Type *Ty = ConvertType(type); if (isPassedByInvisibleReference(type)) { // variable size -> by-ref. C.HandleScalarArgument(PointerType::getUnqual(Ty), type); } else if (Ty->isFirstClassType()) { C.HandleScalarArgument(Ty, type); + } else if (LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(type)) { + C.HandleByValArgument(Ty, type); + if (Attributes) + *Attributes |= ParamAttr::ByVal; } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type)) { PassInIntegerRegisters(type, Ty); } else if (TREE_CODE(type) == RECORD_TYPE) { Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=45907&r1=45906&r2=45907&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat Jan 12 03:22:43 2008 @@ -493,6 +493,11 @@ ++AI; } + void HandleByValArgument(const llvm::Type *LLVMTy, tree type) { + // Should not get here. + abort(); + } + void EnterField(unsigned FieldNo, const llvm::Type *StructTy) { NameStack.push_back(NameStack.back()+"."+utostr(FieldNo)); @@ -663,9 +668,12 @@ const char *Name = "unnamed_arg"; if (DECL_NAME(Args)) Name = IDENTIFIER_POINTER(DECL_NAME(Args)); - if (isPassedByInvisibleReference(TREE_TYPE(Args))) { - // If the value is passed by 'invisible reference', the l-value for the - // argument IS the argument itself. + const Type *ArgTy = ConvertType(TREE_TYPE(Args)); + if (isPassedByInvisibleReference(TREE_TYPE(Args)) || + (!ArgTy->isFirstClassType() && + LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(TREE_TYPE(Args)))) { + // If the value is passed by 'invisible reference' or 'byval reference', + // the l-value for the argument IS the argument itself. SET_DECL_LLVM(Args, AI); AI->setName(Name); ++AI; @@ -673,7 +681,6 @@ // Otherwise, we create an alloca to hold the argument value and provide // an l-value. On entry to the function, we copy formal argument values // into the alloca. - const Type *ArgTy = ConvertType(TREE_TYPE(Args)); Value *Tmp = CreateTemporary(ArgTy); Tmp->setName(std::string(Name)+"_addr"); SET_DECL_LLVM(Args, Tmp); @@ -2372,6 +2379,16 @@ CallOperands.push_back(Builder.CreateLoad(Loc, "tmp")); } + /// HandleByValArgument - This callback is invoked if the aggregate function + /// argument is passed by value. It is lowered to a parameter passed by + /// reference with an additional parameter attribute "ByVal". + void HandleByValArgument(const llvm::Type *LLVMTy, tree type) { + assert(!LocStack.empty()); + Value *Loc = LocStack.back(); + assert(PointerType::getUnqual(LLVMTy) == Loc->getType()); + CallOperands.push_back(Loc); + } + void EnterField(unsigned FieldNo, const llvm::Type *StructTy) { Constant *Zero = Constant::getNullValue(Type::Int32Ty); Constant *FIdx = ConstantInt::get(Type::Int32Ty, FieldNo); @@ -2477,7 +2494,10 @@ LValue LV = EmitLV(TREE_VALUE(arg)); assert(!LV.isBitfield() && "Bitfields are first-class types!"); Client.setLocation(LV.Ptr); - ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg))); + uint16_t Attributes = ParamAttr::None; + ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)), &Attributes); + if (Attributes != ParamAttr::None) + PAL= ParamAttrsList::includeAttrs(PAL, CallOperands.size(), Attributes); } } Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=45907&r1=45906&r2=45907&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sat Jan 12 03:22:43 2008 @@ -999,6 +999,13 @@ } ArgTypes.push_back(LLVMTy); } + + /// HandleByValArgument - This callback is invoked if the aggregate function + /// argument is passed by value. It is lowered to a parameter passed by + /// reference with an additional parameter attribute "ByVal". + void HandleByValArgument(const llvm::Type *LLVMTy, tree type) { + HandleScalarArgument(PointerType::getUnqual(LLVMTy), type); + } }; } @@ -1057,11 +1064,12 @@ for (; Args && TREE_TYPE(Args) != void_type_node; Args = TREE_CHAIN(Args)) { tree ArgTy = TREE_TYPE(Args); - ABIConverter.HandleArgument(ArgTy); // Determine if there are any attributes for this param. uint16_t Attributes = ParamAttr::None; + ABIConverter.HandleArgument(ArgTy, &Attributes); + // Compute zext/sext attributes. Attributes |= HandleArgumentExtension(ArgTy); @@ -1174,11 +1182,11 @@ break; } - ABIConverter.HandleArgument(ArgTy); - // Determine if there are any attributes for this param. uint16_t Attributes = ParamAttr::None; + ABIConverter.HandleArgument(ArgTy, &Attributes); + // Compute zext/sext attributes. Attributes |= HandleArgumentExtension(ArgTy); From evan.cheng at apple.com Sat Jan 12 03:56:57 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 09:56:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45908 - /llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Message-ID: <200801120956.m0C9uvww022006@zion.cs.uiuc.edu> Author: evancheng Date: Sat Jan 12 03:56:53 2008 New Revision: 45908 URL: http://llvm.org/viewvc/llvm-project?rev=45908&view=rev Log: Turns on byval aggregate parameter passing for x86-32. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=45908&r1=45907&r2=45908&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Sat Jan 12 03:56:53 2008 @@ -62,5 +62,8 @@ } \ } +#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X) \ + (!TARGET_64BIT) + /* LLVM LOCAL end (ENTIRE FILE!) */ From baldrick at free.fr Sat Jan 12 10:42:02 2008 From: baldrick at free.fr (Duncan Sands) Date: Sat, 12 Jan 2008 16:42:02 -0000 Subject: [llvm-commits] [llvm] r45909 - in /llvm/trunk: include/llvm/ParameterAttributes.h lib/VMCore/Verifier.cpp test/Verifier/2008-01-11-VarargAttrs.ll Message-ID: <200801121642.m0CGg2fj010866@zion.cs.uiuc.edu> Author: baldrick Date: Sat Jan 12 10:42:01 2008 New Revision: 45909 URL: http://llvm.org/viewvc/llvm-project?rev=45909&view=rev Log: Be more liberal in what parameter attributes are allowed on the vararg arguments of a call. Modified: llvm/trunk/include/llvm/ParameterAttributes.h llvm/trunk/lib/VMCore/Verifier.cpp llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll Modified: llvm/trunk/include/llvm/ParameterAttributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=45909&r1=45908&r2=45909&view=diff ============================================================================== --- llvm/trunk/include/llvm/ParameterAttributes.h (original) +++ llvm/trunk/include/llvm/ParameterAttributes.h Sat Jan 12 10:42:01 2008 @@ -52,8 +52,8 @@ /// @brief Attributes that only apply to function return values. const uint16_t ReturnOnly = NoReturn | NoUnwind | ReadNone | ReadOnly; -/// @brief Attributes that can apply to vararg call arguments. -const uint16_t VarArgsCompatible = ByVal; +/// @brief Parameter attributes that do not apply to vararg call arguments. +const uint16_t VarArgsIncompatible = Nest | StructRet; /// @brief Attributes that are mutually incompatible. const uint16_t MutuallyIncompatible[3] = { Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=45909&r1=45908&r2=45909&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Sat Jan 12 10:42:01 2008 @@ -261,8 +261,10 @@ void VerifyCallSite(CallSite CS); void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, unsigned Count, ...); - void VerifyParamAttrs(const FunctionType *FT, const ParamAttrsList *Attrs, - const Value *V); + void VerifyAttrs(uint16_t Attrs, const Type *Ty, bool isReturnValue, + const Value *V); + void VerifyFunctionAttrs(const FunctionType *FT, const ParamAttrsList *Attrs, + const Value *V); void WriteValue(const Value *V) { if (!V) return; @@ -382,11 +384,40 @@ void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) { } -// VerifyParamAttrs - Check parameter attributes against a function type. +// VerifyAttrs - Check the given parameter attributes for an argument or return +// value of the specified type. The value V is printed in error messages. +void Verifier::VerifyAttrs(uint16_t Attrs, const Type *Ty, bool isReturnValue, + const Value *V) { + if (Attrs == ParamAttr::None) + return; + + if (isReturnValue) { + uint16_t RetI = Attrs & ParamAttr::ParameterOnly; + Assert1(!RetI, "Attribute " + ParamAttrsList::getParamAttrsText(RetI) + + "does not apply to return values!", V); + } else { + uint16_t ParmI = Attrs & ParamAttr::ReturnOnly; + Assert1(!ParmI, "Attribute " + ParamAttrsList::getParamAttrsText(ParmI) + + "only applies to return values!", V); + } + + for (unsigned i = 0; + i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { + uint16_t MutI = Attrs & ParamAttr::MutuallyIncompatible[i]; + Assert1(!(MutI & (MutI - 1)), "Attributes " + + ParamAttrsList::getParamAttrsText(MutI) + "are incompatible!", V); + } + + uint16_t TypeI = Attrs & ParamAttr::typeIncompatible(Ty); + Assert1(!TypeI, "Wrong type for attribute " + + ParamAttrsList::getParamAttrsText(TypeI), V); +} + +// VerifyFunctionAttrs - Check parameter attributes against a function type. // The value V is printed in error messages. -void Verifier::VerifyParamAttrs(const FunctionType *FT, - const ParamAttrsList *Attrs, - const Value *V) { +void Verifier::VerifyFunctionAttrs(const FunctionType *FT, + const ParamAttrsList *Attrs, + const Value *V) { if (!Attrs) return; @@ -395,27 +426,7 @@ for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) { uint16_t Attr = Attrs->getParamAttrs(Idx); - if (!Idx) { - uint16_t RetI = Attr & ParamAttr::ParameterOnly; - Assert1(!RetI, "Attribute " + Attrs->getParamAttrsText(RetI) + - "does not apply to return values!", V); - } else { - uint16_t ParmI = Attr & ParamAttr::ReturnOnly; - Assert1(!ParmI, "Attribute " + Attrs->getParamAttrsText(ParmI) + - "only applies to return values!", V); - } - - for (unsigned i = 0; - i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { - uint16_t MutI = Attr & ParamAttr::MutuallyIncompatible[i]; - Assert1(!(MutI & (MutI - 1)), "Attributes " + - Attrs->getParamAttrsText(MutI) + "are incompatible!", V); - } - - uint16_t TypeI = - Attr & ParamAttr::typeIncompatible(FT->getParamType(Idx-1)); - Assert1(!TypeI, "Wrong type for attribute " + - Attrs->getParamAttrsText(TypeI), V); + VerifyAttrs(Attr, FT->getParamType(Idx-1), !Idx, V); if (Attr & ParamAttr::Nest) { Assert1(!SawNest, "More than one parameter has attribute nest!", V); @@ -453,7 +464,7 @@ "Attributes after last parameter!", &F); // Check function attributes. - VerifyParamAttrs(FT, Attrs, &F); + VerifyFunctionAttrs(FT, Attrs, &F); // Check that this function meets the restrictions on this calling convention. switch (F.getCallingConv()) { @@ -857,14 +868,17 @@ "Attributes after last argument!", I); // Verify call attributes. - VerifyParamAttrs(FTy, Attrs, I); + VerifyFunctionAttrs(FTy, Attrs, I); if (Attrs && FTy->isVarArg()) // Check attributes on the varargs part. for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { uint16_t Attr = Attrs->getParamAttrs(Idx); - uint16_t VArgI = Attr & ~ParamAttr::VarArgsCompatible; - Assert1(!VArgI, "Attribute " + Attrs->getParamAttrsText(VArgI) + + + VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I); + + uint16_t VArgI = Attr & ParamAttr::VarArgsIncompatible; + Assert1(!VArgI, "Attribute " + ParamAttrsList::getParamAttrsText(VArgI) + "cannot be used for vararg call arguments!", I); } Modified: llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll?rev=45909&r1=45908&r2=45909&view=diff ============================================================================== --- llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll (original) +++ llvm/trunk/test/Verifier/2008-01-11-VarargAttrs.ll Sat Jan 12 10:42:01 2008 @@ -1,10 +1,10 @@ -; RUN: not llvm-as < %s +; RUN: not llvm-as < %s -o /dev/null %struct = type { } declare void @foo(...) define void @bar() { - call void (...)* @foo(%struct* inreg null ) + call void (...)* @foo(%struct* sret null ) ret void } From evan.cheng at apple.com Sat Jan 12 12:53:07 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 18:53:07 -0000 Subject: [llvm-commits] [llvm] r45911 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200801121853.m0CIr7DT020292@zion.cs.uiuc.edu> Author: evancheng Date: Sat Jan 12 12:53:07 2008 New Revision: 45911 URL: http://llvm.org/viewvc/llvm-project?rev=45911&view=rev Log: Indirect call with byval parameter requires a cast first. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=45911&r1=45910&r2=45911&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat Jan 12 12:53:07 2008 @@ -453,9 +453,14 @@ unsigned Idx = 1; for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { + const Type *ArgTy = *I; + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa(ArgTy)); + ArgTy = cast(ArgTy)->getElementType(); + } if (I != FTy->param_begin()) FunctionInnards << ", "; - printType(FunctionInnards, *I, + printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ""); ++Idx; } @@ -495,6 +500,9 @@ isa(PTy->getElementType())) ptrName = "(" + ptrName + ")"; + if (PAL) + // Must be a function ptr cast! + return printType(Out, PTy->getElementType(), false, ptrName, true, PAL); return printType(Out, PTy->getElementType(), false, ptrName); } @@ -2632,6 +2640,7 @@ // If this is a call to a struct-return function, assign to the first // parameter instead of passing it to the call. const ParamAttrsList *PAL = I.getParamAttrs(); + bool hasByVal = I.hasByValArgument(); bool isStructRet = I.isStructReturn(); if (isStructRet) { bool isByVal = ByValParams.count(I.getOperand(1)); @@ -2645,8 +2654,8 @@ if (!WroteCallee) { // If this is an indirect call to a struct return function, we need to cast - // the pointer. - bool NeedsCast = isStructRet && !isa(Callee); + // the pointer. Ditto for indirect calls with byval arguments. + bool NeedsCast = (hasByVal || isStructRet) && !isa(Callee); // GCC is a real PITA. It does not permit codegening casts of functions to // function pointers if they are in a call (it generates a trap instruction @@ -2670,11 +2679,13 @@ if (NeedsCast) { // Ok, just cast the pointer type. Out << "(("; - if (!isStructRet) - printType(Out, I.getCalledValue()->getType()); - else + if (isStructRet) printStructReturnPointerFunctionType(Out, PAL, cast(I.getCalledValue()->getType())); + else if (hasByVal) + printType(Out, I.getCalledValue()->getType(), false, "", true, PAL); + else + printType(Out, I.getCalledValue()->getType()); Out << ")(void*)"; } writeOperand(Callee); From sabre at nondot.org Sat Jan 12 12:54:29 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 18:54:29 -0000 Subject: [llvm-commits] [llvm] r45912 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval2.ll Message-ID: <200801121854.m0CIsTOJ020370@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 12:54:29 2008 New Revision: 45912 URL: http://llvm.org/viewvc/llvm-project?rev=45912&view=rev Log: we don't have to make an explicit copy of a byval argument when inlining a function if we know that the function does not write to *any* memory. This implements test/Transforms/Inline/byval2.ll Added: llvm/trunk/test/Transforms/Inline/byval2.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=45912&r1=45911&r2=45912&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Sat Jan 12 12:54:29 2008 @@ -241,10 +241,12 @@ Value *ActualArg = *AI; // When byval arguments actually inlined, we need to make the copy implied - // by them actually explicit. - // TODO: If we know that the callee never modifies the struct, we can - // remove this copy. - if (CalledFunc->paramHasAttr(ArgNo+1, ParamAttr::ByVal)) { + // by them explicit. However, we don't do this if the callee is readonly + // or readnone, because the copy would be unneeded: the callee doesn't + // modify the struct. + if (CalledFunc->paramHasAttr(ArgNo+1, ParamAttr::ByVal) && + !CalledFunc->paramHasAttr(0, ParamAttr::ReadOnly) && + !CalledFunc->paramHasAttr(0, ParamAttr::ReadNone)) { const Type *AggTy = cast(I->getType())->getElementType(); const Type *VoidPtrTy = PointerType::getUnqual(Type::Int8Ty); Added: llvm/trunk/test/Transforms/Inline/byval2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval2.ll?rev=45912&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval2.ll (added) +++ llvm/trunk/test/Transforms/Inline/byval2.ll Sat Jan 12 12:54:29 2008 @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | opt -inline | llvm-dis | not grep {llvm.memcpy} + +; Inlining a byval struct should NOT cause an explicit copy +; into an alloca if the function is readonly + + %struct.ss = type { i32, i64 } + at .str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1] + +define internal i32 @f(%struct.ss* byval %b) nounwind readonly { +entry: + %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; [#uses=2] + %tmp1 = load i32* %tmp, align 4 ; [#uses=1] + %tmp2 = add i32 %tmp1, 1 ; [#uses=1] + ret i32 %tmp2 +} + +declare i32 @printf(i8*, ...) nounwind + +define i32 @main() nounwind { +entry: + %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] + %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] + store i32 1, i32* %tmp1, align 8 + %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; [#uses=1] + store i64 2, i64* %tmp4, align 4 + %X = call i32 @f( %struct.ss* byval %S ) nounwind + ret i32 %X +} From evan.cheng at apple.com Sat Jan 12 12:57:32 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Jan 2008 18:57:32 -0000 Subject: [llvm-commits] [llvm] r45913 - in /llvm/trunk: include/llvm/Instructions.h lib/VMCore/Instructions.cpp Message-ID: <200801121857.m0CIvWXs020574@zion.cs.uiuc.edu> Author: evancheng Date: Sat Jan 12 12:57:32 2008 New Revision: 45913 URL: http://llvm.org/viewvc/llvm-project?rev=45913&view=rev Log: Add hasByValArgument() to test if a call instruction has byval argument(s). Modified: llvm/trunk/include/llvm/Instructions.h llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=45913&r1=45912&r2=45913&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Sat Jan 12 12:57:32 2008 @@ -944,6 +944,9 @@ /// @brief Determine if the call returns a structure. bool isStructReturn() const; + /// @brief Determine if any call argument is an aggregate passed by value. + bool hasByValArgument() const; + /// getCalledFunction - Return the function being called by this instruction /// if it is a direct call. If it is a call through a function pointer, /// return null. Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=45913&r1=45912&r2=45913&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Sat Jan 12 12:57:32 2008 @@ -404,6 +404,17 @@ return paramHasAttr(1, ParamAttr::StructRet); } +/// @brief Determine if any call argument is an aggregate passed by value. +bool CallInst::hasByValArgument() const { + const Value *Callee = getCalledValue(); + const PointerType *CalleeTy = cast(Callee->getType()); + const FunctionType *FTy = cast(CalleeTy->getElementType()); + for (unsigned i = 1, e = FTy->getNumParams()+1; i != e; ++i) + if (paramHasAttr(i, ParamAttr::ByVal)) + return true; + return false; +} + void CallInst::setDoesNotThrow(bool doesNotThrow) { const ParamAttrsList *PAL = getParamAttrs(); if (doesNotThrow) From sabre at nondot.org Sat Jan 12 12:58:47 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 18:58:47 -0000 Subject: [llvm-commits] [llvm] r45914 - /llvm/trunk/lib/Target/README.txt Message-ID: <200801121858.m0CIwljc020644@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 12:58:46 2008 New Revision: 45914 URL: http://llvm.org/viewvc/llvm-project?rev=45914&view=rev Log: clarify a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=45914&r1=45913&r2=45914&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Jan 12 12:58:46 2008 @@ -610,6 +610,14 @@ arguments when the function is inlined. These functions can be inferred by various analysis passes such as the -globalsmodrefaa pass. +globalsmodrefaa pass. Note that getting #2 right is actually really tricky. +Consider this code: + +struct S; S G; +void caller(S byvalarg) { G.field = 1; ... } +void callee() { caller(G); } + +The fact that the caller does not modify byval arg is not enough, we need +to know that it doesn't modify G either. This is very tricky. //===---------------------------------------------------------------------===// From clattner at apple.com Sat Jan 12 13:00:48 2008 From: clattner at apple.com (Chris Lattner) Date: Sat, 12 Jan 2008 11:00:48 -0800 Subject: [llvm-commits] [llvm] r45913 - in /llvm/trunk: include/llvm/Instructions.h lib/VMCore/Instructions.cpp In-Reply-To: <200801121857.m0CIvWXs020574@zion.cs.uiuc.edu> References: <200801121857.m0CIvWXs020574@zion.cs.uiuc.edu> Message-ID: <90330A8C-D69A-4785-9BD9-C5B86BF3D1A9@apple.com> > URL: http://llvm.org/viewvc/llvm-project?rev=45913&view=rev > Log: > Add hasByValArgument() to test if a call instruction has byval > argument(s). Ok. > +/// @brief Determine if any call argument is an aggregate passed by > value. > +bool CallInst::hasByValArgument() const { > + const Value *Callee = getCalledValue(); > + const PointerType *CalleeTy = cast(Callee->getType()); > + const FunctionType *FTy = cast(CalleeTy- > >getElementType()); > + for (unsigned i = 1, e = FTy->getNumParams()+1; i != e; ++i) Instead of walking from 1 .. FTy->getNumParams(), you should walk from 1 .. CI->getNumOperands(). This handles varargs right and is simpler. -Chris > > + if (paramHasAttr(i, ParamAttr::ByVal)) > + return true; > + return false; > +} > + > void CallInst::setDoesNotThrow(bool doesNotThrow) { > const ParamAttrsList *PAL = getParamAttrs(); > if (doesNotThrow) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From duncan.sands at math.u-psud.fr Sat Jan 12 13:18:59 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Sat, 12 Jan 2008 20:18:59 +0100 Subject: [llvm-commits] [llvm] r45913 - in /llvm/trunk: include/llvm/Instructions.h lib/VMCore/Instructions.cpp In-Reply-To: <90330A8C-D69A-4785-9BD9-C5B86BF3D1A9@apple.com> References: <200801121857.m0CIvWXs020574@zion.cs.uiuc.edu> <90330A8C-D69A-4785-9BD9-C5B86BF3D1A9@apple.com> Message-ID: <200801122019.00437.duncan.sands@math.u-psud.fr> > Instead of walking from 1 .. FTy->getNumParams(), you should walk from > 1 .. CI->getNumOperands(). This handles varargs right and is simpler. Instead of either of these, grab the parameter attributes (PAL), walk from 0 to PAL->size()-1 and get the attributes using getParamAttrsAtIndex. That way the time taken is proportional to the number of parameters with attributes, rather than the number of parameters. D. From sabre at nondot.org Sat Jan 12 14:37:47 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 20:37:47 -0000 Subject: [llvm-commits] [test-suite] r45916 - /test-suite/trunk/MultiSource/Applications/Burg/Makefile Message-ID: <200801122037.m0CKblv0026681@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 14:37:45 2008 New Revision: 45916 URL: http://llvm.org/viewvc/llvm-project?rev=45916&view=rev Log: clean up this makefile, which allows it to pass with ENABLE_LTO Modified: test-suite/trunk/MultiSource/Applications/Burg/Makefile Modified: test-suite/trunk/MultiSource/Applications/Burg/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Applications/Burg/Makefile?rev=45916&r1=45915&r2=45916&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Applications/Burg/Makefile (original) +++ test-suite/trunk/MultiSource/Applications/Burg/Makefile Sat Jan 12 14:37:45 2008 @@ -1,7 +1,5 @@ LEVEL = ../../.. -include $(LEVEL)/Makefile.common - PROG = burg CPPFLAGS = -DDEBUG LDFLAGS = -lstdc++ @@ -10,11 +8,11 @@ STDIN_FILENAME = $(PROJ_SRC_DIR)/sample.gr -include $(LLVM_OBJ_ROOT)/Makefile.config +include $(LEVEL)/Makefile.config Source := $(ExtraSource) $(wildcard $(PROJ_SRC_DIR)/*.c) -include ../../Makefile.multisrc +include $(LEVEL)/MultiSource/Makefile.multisrc # # JTC - From sam at bishop.dhs.org Sat Jan 12 16:47:17 2008 From: sam at bishop.dhs.org (Sam Bishop) Date: Sat, 12 Jan 2008 15:47:17 -0700 Subject: [llvm-commits] fix for a compile error? Message-ID: <47894375.9090807@bishop.dhs.org> I just tried to compile a fresh copy of LLVM (from svn) under Cygwin, and I got the following compiler errors: llvm[2]: Compiling TargetData.cpp for Debug build llvm[3]: Compiling SPUISelLowering.cpp for Debug build SPUISelLowering.cpp: In function `llvm::SDOperand LowerLOAD(llvm::SDOperand, llvm::SelectionDAG&, const llvm::SPUSubtarget*)': SPUISelLowering.cpp:558: error: invalid initialization of reference of type 'unsigned int&' from expression of type 'llvm::MVT::ValueType' SPUISelLowering.cpp:457: error: in passing argument 8 of `llvm::SDOperand AlignedLoad(llvm::SDOperand, llvm::SelectionDAG&, const llvm::SPUSubtarget*, llvm::LSBaseSDNode*, unsigned int&, int&, int&, unsigned int&, bool&)' [ The message is repeated for line 673, for the same reason. ] I was able to fix this by changing the type of AlignedLoad()'s eighth argument to be llvm::MVT::ValueType. This seems to better fit the intentions of the original author, but it bothers me that I don't understand why the compiler was complaining about the original code. A trivial patch is attached. Thanks, Sam Bishop -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: SPUISelLowering.cpp.patch Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20080112/e3679b23/attachment.pl From sabre at nondot.org Sat Jan 12 16:54:07 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 12 Jan 2008 22:54:07 -0000 Subject: [llvm-commits] [llvm] r45917 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200801122254.m0CMs7vG003144@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 16:54:07 2008 New Revision: 45917 URL: http://llvm.org/viewvc/llvm-project?rev=45917&view=rev Log: improve cygwin compatibility, patch by Sam Bishop Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=45917&r1=45916&r2=45917&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Sat Jan 12 16:54:07 2008 @@ -453,7 +453,7 @@ AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST, LSBaseSDNode *LSN, unsigned &alignment, int &alignOffs, int &prefSlotOffs, - unsigned &VT, bool &was16aligned) + MVT::ValueType &VT, bool &was16aligned) { MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); const valtype_map_s *vtm = getValueTypeMapEntry(VT); From clattner at apple.com Sat Jan 12 16:54:42 2008 From: clattner at apple.com (Chris Lattner) Date: Sat, 12 Jan 2008 14:54:42 -0800 Subject: [llvm-commits] fix for a compile error? In-Reply-To: <47894375.9090807@bishop.dhs.org> References: <47894375.9090807@bishop.dhs.org> Message-ID: <1FCBB156-D443-470D-BB9D-1651FAD43584@apple.com> > I was able to fix this by changing the type of AlignedLoad()'s > eighth argument to be llvm::MVT::ValueType. This seems to better > fit the intentions of the original author, but it bothers me that I > don't understand why the compiler was complaining about the original > code. A trivial patch is attached. Thanks, applied! http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080107/057142.html -Chris From sabre at nondot.org Sat Jan 12 18:19:58 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 00:19:58 -0000 Subject: [llvm-commits] [llvm] r45918 - /llvm/trunk/test/C++Frontend/2008-01-12-VecInit.cpp Message-ID: <200801130019.m0D0JwPN008412@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 18:19:57 2008 New Revision: 45918 URL: http://llvm.org/viewvc/llvm-project?rev=45918&view=rev Log: new testcase for rdar://5685492 Added: llvm/trunk/test/C++Frontend/2008-01-12-VecInit.cpp Added: llvm/trunk/test/C++Frontend/2008-01-12-VecInit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B%2BFrontend/2008-01-12-VecInit.cpp?rev=45918&view=auto ============================================================================== --- llvm/trunk/test/C++Frontend/2008-01-12-VecInit.cpp (added) +++ llvm/trunk/test/C++Frontend/2008-01-12-VecInit.cpp Sat Jan 12 18:19:57 2008 @@ -0,0 +1,6 @@ +// RUN: %llvmgcc -xc++ %s -S -o - +// rdar://5685492 + +typedef int __attribute__((vector_size(16))) v; +v vt = {1, 2, 3, 4}; + From sabre at nondot.org Sat Jan 12 18:21:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 00:21:21 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r45919 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200801130021.m0D0LLTV008497@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 18:21:21 2008 New Revision: 45919 URL: http://llvm.org/viewvc/llvm-project?rev=45919&view=rev Log: Fix test/C++Frontend/2008-01-12-VecInit.cpp and rdar://5685492 Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=45919&r1=45918&r2=45919&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Sat Jan 12 18:21:21 2008 @@ -6065,28 +6065,32 @@ Constant *TreeConstantToLLVM::ConvertArrayCONSTRUCTOR(tree exp) { // Vectors are like arrays, but the domain is stored via an array // type indirectly. - assert(TREE_CODE(TREE_TYPE(exp)) != VECTOR_TYPE && - "VECTOR_TYPE's haven't been tested!"); - // If we have a lower bound for the range of the type, get it. */ - tree Domain = TYPE_DOMAIN(TREE_TYPE(exp)); + // If we have a lower bound for the range of the type, get it. + tree InitType = TREE_TYPE(exp); tree min_element = size_zero_node; - if (Domain && TYPE_MIN_VALUE(Domain)) - min_element = fold_convert(sizetype, TYPE_MIN_VALUE(Domain)); - std::vector ResultElts; - Constant *SomeVal = 0; - if (Domain && TYPE_MAX_VALUE(Domain)) { - tree max_element = fold_convert(sizetype, TYPE_MAX_VALUE(Domain)); - tree size = size_binop (MINUS_EXPR, max_element, min_element); - size = size_binop (PLUS_EXPR, size, size_one_node); - - if (host_integerp(size, 1)) - ResultElts.resize(tree_low_cst(size, 1)); + if (TREE_CODE(InitType) == VECTOR_TYPE) { + ResultElts.resize(TYPE_VECTOR_SUBPARTS(InitType)); + } else { + assert(TREE_CODE(InitType) == ARRAY_TYPE && "Unknown type for init"); + tree Domain = TYPE_DOMAIN(InitType); + if (Domain && TYPE_MIN_VALUE(Domain)) + min_element = fold_convert(sizetype, TYPE_MIN_VALUE(Domain)); + + if (Domain && TYPE_MAX_VALUE(Domain)) { + tree max_element = fold_convert(sizetype, TYPE_MAX_VALUE(Domain)); + tree size = size_binop (MINUS_EXPR, max_element, min_element); + size = size_binop (PLUS_EXPR, size, size_one_node); + + if (host_integerp(size, 1)) + ResultElts.resize(tree_low_cst(size, 1)); + } } - + unsigned NextFieldToFill = 0; + Constant *SomeVal = 0; for (tree elt = CONSTRUCTOR_ELTS(exp); elt; elt = TREE_CHAIN(elt)) { // Find and decode the constructor's value. Constant *Val = Convert(TREE_VALUE(elt)); @@ -6158,6 +6162,11 @@ AllEltsSameType = false; } + if (TREE_CODE(InitType) == VECTOR_TYPE) { + assert(AllEltsSameType && "Vector of heterogeneous element types?"); + return ConstantVector::get(ResultElts); + } + if (AllEltsSameType) return ConstantArray::get(ArrayType::get(ElTy, ResultElts.size()), ResultElts); From sabre at nondot.org Sat Jan 12 18:22:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 00:22:27 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45920 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200801130022.m0D0MSoj008557@zion.cs.uiuc.edu> Author: lattner Date: Sat Jan 12 18:22:27 2008 New Revision: 45920 URL: http://llvm.org/viewvc/llvm-project?rev=45920&view=rev Log: Fix test/C++Frontend/2008-01-12-VecInit.cpp and rdar://5685492 Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=45920&r1=45919&r2=45920&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat Jan 12 18:22:27 2008 @@ -5652,30 +5652,34 @@ Constant *TreeConstantToLLVM::ConvertArrayCONSTRUCTOR(tree exp) { // Vectors are like arrays, but the domain is stored via an array // type indirectly. - assert(TREE_CODE(TREE_TYPE(exp)) != VECTOR_TYPE && - "VECTOR_TYPE's haven't been tested!"); - - // If we have a lower bound for the range of the type, get it. */ - tree Domain = TYPE_DOMAIN(TREE_TYPE(exp)); + + // If we have a lower bound for the range of the type, get it. + tree InitType = TREE_TYPE(exp); tree min_element = size_zero_node; - if (Domain && TYPE_MIN_VALUE(Domain)) - min_element = fold_convert(sizetype, TYPE_MIN_VALUE(Domain)); - std::vector ResultElts; - Constant *SomeVal = 0; - if (Domain && TYPE_MAX_VALUE(Domain)) { - tree max_element = fold_convert(sizetype, TYPE_MAX_VALUE(Domain)); - tree size = size_binop (MINUS_EXPR, max_element, min_element); - size = size_binop (PLUS_EXPR, size, size_one_node); + if (TREE_CODE(InitType) == VECTOR_TYPE) { + ResultElts.resize(TYPE_VECTOR_SUBPARTS(InitType)); + } else { + assert(TREE_CODE(InitType) == ARRAY_TYPE && "Unknown type for init"); + tree Domain = TYPE_DOMAIN(InitType); + if (Domain && TYPE_MIN_VALUE(Domain)) + min_element = fold_convert(sizetype, TYPE_MIN_VALUE(Domain)); + + if (Domain && TYPE_MAX_VALUE(Domain)) { + tree max_element = fold_convert(sizetype, TYPE_MAX_VALUE(Domain)); + tree size = size_binop (MINUS_EXPR, max_element, min_element); + size = size_binop (PLUS_EXPR, size, size_one_node); - if (host_integerp(size, 1)) - ResultElts.resize(tree_low_cst(size, 1)); + if (host_integerp(size, 1)) + ResultElts.resize(tree_low_cst(size, 1)); + } } unsigned NextFieldToFill = 0; unsigned HOST_WIDE_INT ix; tree elt_index, elt_value; + Constant *SomeVal = 0; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), ix, elt_index, elt_value) { // Find and decode the constructor's value. Constant *Val = Convert(elt_value); @@ -5747,6 +5751,11 @@ AllEltsSameType = false; } + if (TREE_CODE(InitType) == VECTOR_TYPE) { + assert(AllEltsSameType && "Vector of heterogeneous element types?"); + return ConstantVector::get(ResultElts); + } + if (AllEltsSameType) return ConstantArray::get(ArrayType::get(ElTy, ResultElts.size()), ResultElts); From baldrick at free.fr Sun Jan 13 02:02:47 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 08:02:47 -0000 Subject: [llvm-commits] [llvm] r45931 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll Message-ID: <200801130802.m0D82lV6004909@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 02:02:44 2008 New Revision: 45931 URL: http://llvm.org/viewvc/llvm-project?rev=45931&view=rev Log: When turning a call to a bitcast function into a direct call, if this becomes a varargs call then deal correctly with any parameter attributes on the newly vararg call arguments. Added: llvm/trunk/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45931&r1=45930&r2=45931&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 02:02:44 2008 @@ -8142,9 +8142,9 @@ return false; // Cannot transform this return value. if (!Caller->use_empty() && - !CastInst::isCastable(FT->getReturnType(), OldRetTy) && // void -> non-void is handled specially - FT->getReturnType() != Type::VoidTy) + FT->getReturnType() != Type::VoidTy && + !CastInst::isCastable(FT->getReturnType(), OldRetTy)) return false; // Cannot transform this return value. if (CallerPAL && !Caller->use_empty()) { @@ -8200,14 +8200,17 @@ Callee->isDeclaration()) return false; // Do not delete arguments unless we have a function body... - if (FT->getNumParams() < NumActualArgs && FT->isVarArg()) + if (FT->getNumParams() < NumActualArgs && FT->isVarArg() && CallerPAL) // In this case we have more arguments than the new function type, but we - // won't be dropping them. Some of them may have attributes. If so, we - // cannot perform the transform because attributes are not allowed after - // the end of the function type. - if (CallerPAL && CallerPAL->size() && - CallerPAL->getParamIndex(CallerPAL->size()-1) > FT->getNumParams()) - return false; + // won't be dropping them. Check that these extra arguments have attributes + // that are compatible with being a vararg call argument. + for (unsigned i = CallerPAL->size(); i; --i) { + if (CallerPAL->getParamIndex(i - 1) <= FT->getNumParams()) + break; + uint16_t PAttrs = CallerPAL->getParamAttrsAtIndex(i - 1); + if (PAttrs & ParamAttr::VarArgsIncompatible) + return false; + } // Okay, we decided that this is a safe thing to do: go ahead and start // inserting cast instructions as necessary... @@ -8269,10 +8272,12 @@ } else { Args.push_back(*AI); } - } - // No need to add parameter attributes - we already checked that there - // aren't any. + // Add any parameter attributes. + uint16_t PAttrs = CallerPAL ? CallerPAL->getParamAttrs(i + 1) : 0; + if (PAttrs) + attrVec.push_back(ParamAttrsWithIndex::get(i + 1, PAttrs)); + } } if (FT->getReturnType() == Type::VoidTy) Modified: llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll?rev=45931&r1=45930&r2=45931&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll Sun Jan 13 02:02:44 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep bitcast | count 2 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep bitcast define void @a() { ret void @@ -17,7 +17,6 @@ call <2 x i32> bitcast (i32 (i32*)* @b to <2 x i32> (i32*)*)( i32* inreg null ) ; <<2 x i32>>:1 [#uses=0] %x = call i64 bitcast (i32 (i32*)* @b to i64 (i32)*)( i32 0 ) ; [#uses=0] call void bitcast (void (...)* @c to void (i32)*)( i32 0 ) - call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)( i32 zeroext 0 ) ; :2 [#uses=0] call void bitcast (void (...)* @c to void (i32)*)( i32 zeroext 0 ) ret void } Added: llvm/trunk/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll?rev=45931&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll Sun Jan 13 02:02:44 2008 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep bitcast | count 2 + +define i32 @b(i32* inreg %x) signext { + ret i32 0 +} + +define void @c(...) { + ret void +} + +define void @g(i32* %y) { + call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)( i32 zeroext 0 ) ; :2 [#uses=0] + call void bitcast (void (...)* @c to void (i32*)*)( i32* sret null ) + ret void +} From baldrick at free.fr Sun Jan 13 02:12:17 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 08:12:17 -0000 Subject: [llvm-commits] [llvm] r45932 - /llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Message-ID: <200801130812.m0D8CHoE005276@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 02:12:17 2008 New Revision: 45932 URL: http://llvm.org/viewvc/llvm-project?rev=45932&view=rev Log: Small simplification. Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=45932&r1=45931&r2=45932&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Sun Jan 13 02:12:17 2008 @@ -456,10 +456,7 @@ // Recompute the parameter attributes list based on the new arguments for // the function. - if (ParamAttrsVec.empty()) - PAL = 0; - else - PAL = ParamAttrsList::get(ParamAttrsVec); + PAL = ParamAttrsList::get(ParamAttrsVec); // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which // have zero fixed arguments. From baldrick at free.fr Sun Jan 13 02:18:43 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 09:18:43 +0100 Subject: [llvm-commits] [llvm] r45850 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <1859DD11-2B75-4134-A90A-E5345473F774@apple.com> References: <200801110213.m0B2DBvu014340@zion.cs.uiuc.edu> <200801110743.18251.duncan.sands@math.u-psud.fr> <1859DD11-2B75-4134-A90A-E5345473F774@apple.com> Message-ID: <200801130918.48618.baldrick@free.fr> > > there are some issues that need to be fixed: > > (1) the asm parser drops parameter attributes specified on the varargs > > part of a call/invoke; > > (2) when the DAE pass drops varargs call arguments, the parameter > > attributes need to be trimmed, since otherwise you can have attributes > > that don't correspond to a call argument any more; > > (3) when instcombine resolves calls to a bitcast of a function into > > a direct call, then parameter attributes will be lost on any varargs > > part of a call. These are all done. > One more. When llvm-extract remove a function with byval parameters, > it also drops the attribute. I don't know what llvm-extract is, so how about I leave that to you :) There is one more problem place: ArgumentPromotion. After rewriting a function, it rewrites all calls to the function, but doesn't adjust their parameter attributes. See DeadArgumentElimination for an example where parameter attributes are rewritten. I don't have time to fix this now. Ciao, D. From duncan.sands at math.u-psud.fr Sun Jan 13 03:54:47 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Sun, 13 Jan 2008 10:54:47 +0100 Subject: [llvm-commits] [llvm-gcc-4.2] r45907 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-types.cpp In-Reply-To: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> References: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> Message-ID: <200801131054.49034.duncan.sands@math.u-psud.fr> Hi Evan, this breaks the Ada build: Wrong type for attribute byval void ([4 x i8]*, i8, i8, i8, i8, [4 x i8]*)* @system__file_io__fopen_mode Is byval supposed to be able to handle passing arrays by value or only structs? The verifier, via ParamAttr::typeIncompatible, checks that byval is only applied to pointers to structs: if (const PointerType *PTy = dyn_cast(Ty)) { if (!isa(PTy->getElementType())) // Attributes that only apply to pointers to structs. Incompatible |= ParamAttr::ByVal; } else { Ciao, Duncan. From baldrick at free.fr Sun Jan 13 12:42:32 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 18:42:32 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r45934 - /llvm-gcc-4.2/trunk/gcc/tree-nested.c Message-ID: <200801131842.m0DIgWGt006640@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 12:42:27 2008 New Revision: 45934 URL: http://llvm.org/viewvc/llvm-project?rev=45934&view=rev Log: Fix [Bug tree-optimization/30927], which results in suboptimal code for gcc, but maybe wrong code for llvm-gcc. The problem occurs when one nested function, A, calls another nested function B, when the body of B is output after the body of A (so at the moment of the call, A only has the declaration of B). The bug results in the call thinking that B takes a static chain, whether or not B actually does. Since gcc does not have the static chain as an actual function parameter, but as an implicit one always passed in a register, it is fairly harmless if A sets the register value and B never uses it. But in LLVM the static chain is a normal function parameter, and the mismatch between the call and the callee can result in trouble, not to mention unpleasant warnings from instcombine about "While resolving call to function 'B' arguments were dropped!". Modified: llvm-gcc-4.2/trunk/gcc/tree-nested.c Modified: llvm-gcc-4.2/trunk/gcc/tree-nested.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree-nested.c?rev=45934&r1=45933&r2=45934&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree-nested.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree-nested.c Sun Jan 13 12:42:27 2008 @@ -35,6 +35,8 @@ #include "expr.h" #include "langhooks.h" #include "ggc.h" +/* LLVM local */ +#include "pointer-set.h" /* The object of this pass is to lower the representation of a set of nested @@ -89,6 +91,9 @@ struct nesting_info *inner; struct nesting_info *next; + /* LLVM local */ + struct nesting_info *next_with_chain; + htab_t GTY ((param_is (struct var_map_elt))) field_map; htab_t GTY ((param_is (struct var_map_elt))) var_map; bitmap suppress_expansion; @@ -102,12 +107,37 @@ tree chain_decl; tree nl_goto_field; + /* LLVM local */ + struct pointer_set_t * GTY ((skip)) callers; + bool any_parm_remapped; bool any_tramp_created; char static_chain_added; }; +/* LLVM local begin */ +/* Hash table used to look up nesting_info from nesting_info->context. */ + +static htab_t ni_map; + +/* Hashing and equality functions for ni_map. */ + +static hashval_t +ni_hash (const void *p) +{ + const struct nesting_info *i = p; + return (hashval_t) DECL_UID (i->context); +} + +static int +ni_eq (const void *p1, const void *p2) +{ + const struct nesting_info *i1 = p1, *i2 = p2; + return DECL_UID (i1->context) == DECL_UID (i2->context); +} +/* LLVM local end */ + /* Hashing and equality functions for nesting_info->var_map. */ static hashval_t @@ -776,11 +806,20 @@ static struct nesting_info * create_nesting_tree (struct cgraph_node *cgn) { + /* LLVM local */ + struct nesting_info **slot; struct nesting_info *info = GGC_CNEW (struct nesting_info); info->field_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free); info->var_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free); info->suppress_expansion = BITMAP_GGC_ALLOC (); info->context = cgn->decl; + /* LLVM local begin */ + info->callers = pointer_set_create (); + + slot = (struct nesting_info **) htab_find_slot (ni_map, info, INSERT); + gcc_assert (*slot == NULL); + *slot = info; + /* LLVM local end */ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) { @@ -1614,6 +1653,123 @@ return NULL_TREE; } +/* LLVM local begin */ +/* Find the nesting context for FNDECL, a function declaration. */ + +static struct nesting_info * +lookup_context_for_decl (tree fndecl) +{ + struct nesting_info dummy; + struct nesting_info **slot; + + dummy.context = fndecl; + slot = (struct nesting_info **) htab_find_slot (ni_map, &dummy, NO_INSERT); + gcc_assert (slot != NULL); + return *slot; +} + +/* Called via walk_function+walk_tree, discover all nested functions that + might be called from this one. For each such function, add an edge from + the callee function back to this one. */ + +static tree +construct_reverse_callgraph (tree *tp, int *walk_subtrees, void *data) +{ + struct walk_stmt_info *wi = (struct walk_stmt_info *) data; + struct nesting_info *info = wi->info; + tree t = *tp, decl; + + *walk_subtrees = 0; + switch (TREE_CODE (t)) + { + case ADDR_EXPR: + decl = TREE_OPERAND (t, 0); + + /* Only need to process nested functions. */ + if (TREE_CODE (decl) != FUNCTION_DECL) + break; + + if (!decl_function_context (decl)) + break; + + /* Add an edge from the callee to the caller. */ + pointer_set_insert (lookup_context_for_decl (decl)->callers, info); + break; + + default: + if (!IS_TYPE_OR_DECL_P (t)) + *walk_subtrees = 1; + break; + } + + return NULL_TREE; +} + +/* Worklist of nested functions with a static chain to propagate. */ +static struct nesting_info *with_chain_worklist; + +/* Helper for propagate_chains. Set the chain flag for nested functions + that clearly require a static chain, and add them to the worklist. */ + +static void +initialize_chains (struct nesting_info *root) { + do + { + if (root->inner) + initialize_chains (root->inner); + + DECL_NO_STATIC_CHAIN (root->context) = 1; + if (root->chain_decl || root->chain_field) { + /* Requires a static chain - add it to the worklist. */ + DECL_NO_STATIC_CHAIN (root->context) = 0; + root->next_with_chain = with_chain_worklist; + with_chain_worklist = root; + } + + root = root->next; + } + while (root); +} + +/* Helper for propagate_chains. Set the chain flag on a function and all of + its ancestors deeper than 'data'. Propagate any new flag settings. */ + +static bool +propagate_to_caller (void *ptr, void *data) { + struct nesting_info *target = data; + struct nesting_info *caller; + + for (caller = ptr; caller != target; caller = caller->outer) + if (DECL_NO_STATIC_CHAIN (caller->context)) { + /* Give this function a static chain and propagate it. */ + DECL_NO_STATIC_CHAIN (caller->context) = 0; + caller->next_with_chain = with_chain_worklist; + with_chain_worklist = caller; + } + + return true; +} + +/* If a call is made to a nested function that takes a static chain parameter, + then the callee may also require a static chain parameter. Determine all + nested functions which require a static chain parameter. */ + +static void +propagate_chains (struct nesting_info *root) { + /* Fill the worklist and initialize the chain flag, !DECL_NO_STATIC_CHAIN. */ + initialize_chains (root->inner); + + while (with_chain_worklist) { + /* Pop a context off the worklist. */ + struct nesting_info *info = with_chain_worklist; + with_chain_worklist = with_chain_worklist->next_with_chain; + + /* Propagate the static chain to any callers. */ + pointer_set_traverse (info->callers, propagate_to_caller, info->outer); + } +} +/* LLVM local end */ + /* Called via walk_function+walk_tree, rewrite all references to addresses of nested functions that require the use of trampolines. The rewrite will involve a reference a trampoline generated for the occasion. */ @@ -1772,11 +1928,11 @@ walk_function (convert_tramp_reference, root); walk_function (convert_call_expr, root); - /* If the function does not use a static chain, then remember that. */ - if (root->outer && !root->chain_decl && !root->chain_field) - DECL_NO_STATIC_CHAIN (root->context) = 1; - else - gcc_assert (!DECL_NO_STATIC_CHAIN (root->context)); + /* LLVM local begin */ + gcc_assert (!root->outer || + DECL_NO_STATIC_CHAIN (root->context) == + !(root->chain_decl || root->chain_field)); + /* LLVM local end */ root = root->next; } @@ -1982,6 +2138,10 @@ if (root->inner) free_nesting_tree (root->inner); htab_delete (root->var_map); + /* LLVM local begin */ + htab_delete (root->field_map); + pointer_set_destroy (root->callers); + /* LLVM local end */ next = root->next; ggc_free (root); root = next; @@ -2004,16 +2164,24 @@ if (!cgn->nested) return; + /* LLVM local */ + ni_map = htab_create (11, ni_hash, ni_eq, NULL); root = create_nesting_tree (cgn); walk_all_functions (convert_nonlocal_reference, root); walk_all_functions (convert_local_reference, root); walk_all_functions (convert_nl_goto_reference, root); walk_all_functions (convert_nl_goto_receiver, root); + /* LLVM local begin */ + walk_all_functions (construct_reverse_callgraph, root); + propagate_chains (root); + /* LLVM local end */ convert_all_function_calls (root); finalize_nesting_tree (root); unnest_nesting_tree (root); free_nesting_tree (root); root = NULL; + /* LLVM local */ + htab_delete (ni_map); } #include "gt-tree-nested.h" From baldrick at free.fr Sun Jan 13 12:42:57 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 18:42:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r45935 - in /llvm-gcc-4.0/trunk/gcc: pointer-set.c pointer-set.h tree-nested.c Message-ID: <200801131842.m0DIgvnK006680@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 12:42:52 2008 New Revision: 45935 URL: http://llvm.org/viewvc/llvm-project?rev=45935&view=rev Log: Fix [Bug tree-optimization/30927], which results in suboptimal code for gcc, but maybe wrong code for llvm-gcc. The problem occurs when one nested function, A, calls another nested function B, when the body of B is output after the body of A (so at the moment of the call, A only has the declaration of B). The bug results in the call thinking that B takes a static chain, whether or not B actually does. Since gcc does not have the static chain as an actual function parameter, but as an implicit one always passed in a register, it is fairly harmless if A sets the register value and B never uses it. But in LLVM the static chain is a normal function parameter, and the mismatch between the call and the callee can result in trouble, not to mention unpleasant warnings from instcombine about "While resolving call to function 'B' arguments were dropped!". Modified: llvm-gcc-4.0/trunk/gcc/pointer-set.c llvm-gcc-4.0/trunk/gcc/pointer-set.h llvm-gcc-4.0/trunk/gcc/tree-nested.c Modified: llvm-gcc-4.0/trunk/gcc/pointer-set.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/pointer-set.c?rev=45935&r1=45934&r2=45935&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/pointer-set.c (original) +++ llvm-gcc-4.0/trunk/gcc/pointer-set.c Sun Jan 13 12:42:52 2008 @@ -170,3 +170,17 @@ return 0; } + +/* LLVM local begin */ +/* Pass each pointer in PSET to the function in FN, together with the fixed + parameter DATA. If FN returns false, the iteration stops. */ + +void pointer_set_traverse (struct pointer_set_t *pset, + bool (*fn) (void *, void *), void *data) +{ + size_t i; + for (i = 0; i < pset->n_slots; ++i) + if (pset->slots[i] && !fn (pset->slots[i], data)) + break; +} +/* LLVM local end */ Modified: llvm-gcc-4.0/trunk/gcc/pointer-set.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/pointer-set.h?rev=45935&r1=45934&r2=45935&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/pointer-set.h (original) +++ llvm-gcc-4.0/trunk/gcc/pointer-set.h Sun Jan 13 12:42:52 2008 @@ -28,5 +28,9 @@ int pointer_set_contains (struct pointer_set_t *pset, void *p); int pointer_set_insert (struct pointer_set_t *pset, void *p); +/* LLVM local begin */ +void pointer_set_traverse (struct pointer_set_t *, bool (*) (void *, void *), + void *); +/* LLVM local end */ #endif /* POINTER_SET_H */ Modified: llvm-gcc-4.0/trunk/gcc/tree-nested.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/tree-nested.c?rev=45935&r1=45934&r2=45935&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/tree-nested.c (original) +++ llvm-gcc-4.0/trunk/gcc/tree-nested.c Sun Jan 13 12:42:52 2008 @@ -35,6 +35,8 @@ #include "expr.h" #include "langhooks.h" #include "ggc.h" +/* LLVM local */ +#include "pointer-set.h" /* The object of this pass is to lower the representation of a set of nested @@ -89,6 +91,9 @@ struct nesting_info *inner; struct nesting_info *next; + /* LLVM local */ + struct nesting_info *next_with_chain; + htab_t var_map; tree context; tree new_local_var_chain; @@ -98,11 +103,36 @@ tree chain_decl; tree nl_goto_field; + /* LLVM local */ + struct pointer_set_t *callers; + bool any_parm_remapped; bool any_tramp_created; }; +/* LLVM local begin */ +/* Hash table used to look up nesting_info from nesting_info->context. */ + +static htab_t ni_map; + +/* Hashing and equality functions for ni_map. */ + +static hashval_t +ni_hash (const void *p) +{ + const struct nesting_info *i = p; + return (hashval_t) DECL_UID (i->context); +} + +static int +ni_eq (const void *p1, const void *p2) +{ + const struct nesting_info *i1 = p1, *i2 = p2; + return DECL_UID (i1->context) == DECL_UID (i2->context); +} +/* LLVM local end */ + /* Hashing and equality functions for nesting_info->var_map. */ static hashval_t @@ -694,9 +724,18 @@ static struct nesting_info * create_nesting_tree (struct cgraph_node *cgn) { + /* LLVM local */ + struct nesting_info **slot; struct nesting_info *info = xcalloc (1, sizeof (*info)); info->var_map = htab_create (7, var_map_hash, var_map_eq, free); info->context = cgn->decl; + /* LLVM local begin */ + info->callers = pointer_set_create (); + + slot = (struct nesting_info **) htab_find_slot (ni_map, info, INSERT); + gcc_assert (*slot == NULL); + *slot = info; + /* LLVM local end */ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) { @@ -1186,6 +1225,123 @@ return NULL_TREE; } +/* LLVM local begin */ +/* Find the nesting context for FNDECL, a function declaration. */ + +static struct nesting_info * +lookup_context_for_decl (tree fndecl) +{ + struct nesting_info dummy; + struct nesting_info **slot; + + dummy.context = fndecl; + slot = (struct nesting_info **) htab_find_slot (ni_map, &dummy, NO_INSERT); + gcc_assert (slot != NULL); + return *slot; +} + +/* Called via walk_function+walk_tree, discover all nested functions that + might be called from this one. For each such function, add an edge from + the callee function back to this one. */ + +static tree +construct_reverse_callgraph (tree *tp, int *walk_subtrees, void *data) +{ + struct walk_stmt_info *wi = (struct walk_stmt_info *) data; + struct nesting_info *info = wi->info; + tree t = *tp, decl; + + *walk_subtrees = 0; + switch (TREE_CODE (t)) + { + case ADDR_EXPR: + decl = TREE_OPERAND (t, 0); + + /* Only need to process nested functions. */ + if (TREE_CODE (decl) != FUNCTION_DECL) + break; + + if (!decl_function_context (decl)) + break; + + /* Add an edge from the callee to the caller. */ + pointer_set_insert (lookup_context_for_decl (decl)->callers, info); + break; + + default: + if (!IS_TYPE_OR_DECL_P (t)) + *walk_subtrees = 1; + break; + } + + return NULL_TREE; +} + +/* Worklist of nested functions with a static chain to propagate. */ +static struct nesting_info *with_chain_worklist; + +/* Helper for propagate_chains. Set the chain flag for nested functions + that clearly require a static chain, and add them to the worklist. */ + +static void +initialize_chains (struct nesting_info *root) { + do + { + if (root->inner) + initialize_chains (root->inner); + + DECL_NO_STATIC_CHAIN (root->context) = 1; + if (root->chain_decl || root->chain_field) { + /* Requires a static chain - add it to the worklist. */ + DECL_NO_STATIC_CHAIN (root->context) = 0; + root->next_with_chain = with_chain_worklist; + with_chain_worklist = root; + } + + root = root->next; + } + while (root); +} + +/* Helper for propagate_chains. Set the chain flag on a function and all of + its ancestors deeper than 'data'. Propagate any new flag settings. */ + +static bool +propagate_to_caller (void *ptr, void *data) { + struct nesting_info *target = data; + struct nesting_info *caller; + + for (caller = ptr; caller != target; caller = caller->outer) + if (DECL_NO_STATIC_CHAIN (caller->context)) { + /* Give this function a static chain and propagate it. */ + DECL_NO_STATIC_CHAIN (caller->context) = 0; + caller->next_with_chain = with_chain_worklist; + with_chain_worklist = caller; + } + + return true; +} + +/* If a call is made to a nested function that takes a static chain parameter, + then the callee may also require a static chain parameter. Determine all + nested functions which require a static chain parameter. */ + +static void +propagate_chains (struct nesting_info *root) { + /* Fill the worklist and initialize the chain flag, !DECL_NO_STATIC_CHAIN. */ + initialize_chains (root->inner); + + while (with_chain_worklist) { + /* Pop a context off the worklist. */ + struct nesting_info *info = with_chain_worklist; + with_chain_worklist = with_chain_worklist->next_with_chain; + + /* Propagate the static chain to any callers. */ + pointer_set_traverse (info->callers, propagate_to_caller, info->outer); + } +} +/* LLVM local end */ + /* Called via walk_function+walk_tree, rewrite all references to addresses of nested functions that require the use of trampolines. The rewrite will involve a reference a trampoline generated for the occasion. */ @@ -1301,11 +1457,11 @@ walk_function (convert_tramp_reference, root); walk_function (convert_call_expr, root); - /* If the function does not use a static chain, then remember that. */ - if (root->outer && !root->chain_decl && !root->chain_field) - DECL_NO_STATIC_CHAIN (root->context) = 1; - else - gcc_assert (!DECL_NO_STATIC_CHAIN (root->context)); + /* LLVM local begin */ + gcc_assert (!root->outer || + DECL_NO_STATIC_CHAIN (root->context) == + !(root->chain_decl || root->chain_field)); + /* LLVM local end */ root = root->next; } @@ -1491,6 +1647,8 @@ if (root->inner) free_nesting_tree (root->inner); htab_delete (root->var_map); + /* LLVM local */ + pointer_set_destroy (root->callers); next = root->next; free (root); root = next; @@ -1512,14 +1670,22 @@ if (!cgn->nested) return; + /* LLVM local */ + ni_map = htab_create (11, ni_hash, ni_eq, NULL); root = create_nesting_tree (cgn); walk_all_functions (convert_nonlocal_reference, root); walk_all_functions (convert_local_reference, root); walk_all_functions (convert_nl_goto_reference, root); walk_all_functions (convert_nl_goto_receiver, root); + /* LLVM local begin */ + walk_all_functions (construct_reverse_callgraph, root); + propagate_chains (root); + /* LLVM local end */ convert_all_function_calls (root); finalize_nesting_tree (root); free_nesting_tree (root); + /* LLVM local */ + htab_delete (ni_map); } #include "gt-tree-nested.h" From baldrick at free.fr Sun Jan 13 12:44:12 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 18:44:12 -0000 Subject: [llvm-commits] [llvm] r45936 - /llvm/trunk/test/CFrontend/2008-01-11-ChainConsistency.c Message-ID: <200801131844.m0DIiCPY006755@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 12:44:12 2008 New Revision: 45936 URL: http://llvm.org/viewvc/llvm-project?rev=45936&view=rev Log: Check that nested functions don't get pointless static chains. Added: llvm/trunk/test/CFrontend/2008-01-11-ChainConsistency.c Added: llvm/trunk/test/CFrontend/2008-01-11-ChainConsistency.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2008-01-11-ChainConsistency.c?rev=45936&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/2008-01-11-ChainConsistency.c (added) +++ llvm/trunk/test/CFrontend/2008-01-11-ChainConsistency.c Sun Jan 13 12:44:12 2008 @@ -0,0 +1,3 @@ +// RUN: %llvmgcc -S %s -o - -fnested-functions | not grep nest + +void n1(void) { void a(void) { a(); } a(); } From clattner at apple.com Sun Jan 13 13:59:40 2008 From: clattner at apple.com (Chris Lattner) Date: Sun, 13 Jan 2008 11:59:40 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45907 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-types.cpp In-Reply-To: <200801131054.49034.duncan.sands@math.u-psud.fr> References: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> <200801131054.49034.duncan.sands@math.u-psud.fr> Message-ID: <0F5C42A0-9BD2-485F-AA0B-9D87CEDCBB8D@apple.com> On Jan 13, 2008, at 1:54 AM, Duncan Sands wrote: > Hi Evan, this breaks the Ada build: > > Wrong type for attribute byval > void ([4 x i8]*, i8, i8, i8, i8, [4 x i8]*)* > @system__file_io__fopen_mode > > Is byval supposed to be able to handle passing arrays by value or only > structs? The verifier, via ParamAttr::typeIncompatible, checks that > byval is only applied to pointers to structs: > > if (const PointerType *PTy = dyn_cast(Ty)) { > if (!isa(PTy->getElementType())) > // Attributes that only apply to pointers to structs. > Incompatible |= ParamAttr::ByVal; > } else { byval makes sense semantically for any pointer to sized type, I think it would be reasonable to expand it to allow any of these pointers, including the one above. -Chris From duncan.sands at math.u-psud.fr Sun Jan 13 14:37:19 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Sun, 13 Jan 2008 21:37:19 +0100 Subject: [llvm-commits] =?iso-8859-1?q?=5Bllvm-gcc-4=2E2=5D_r45907_-_in=09?= =?iso-8859-1?q?/llvm-gcc-4=2E2/trunk/gcc=3A_llvm-abi=2Eh_llvm-convert=2Ec?= =?iso-8859-1?q?pp_llvm-types=2Ecpp?= In-Reply-To: <0F5C42A0-9BD2-485F-AA0B-9D87CEDCBB8D@apple.com> References: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> <200801131054.49034.duncan.sands@math.u-psud.fr> <0F5C42A0-9BD2-485F-AA0B-9D87CEDCBB8D@apple.com> Message-ID: <200801132137.20842.duncan.sands@math.u-psud.fr> Hi Chris, > byval makes sense semantically for any pointer to sized type, I think > it would be reasonable to expand it to allow any of these pointers, > including the one above. I adjusted the check to allow pointers to arrays, but got a crash in SelectionDAGISel.cpp: if (F.paramHasAttr(j, ParamAttr::ByVal)) { Flags |= ISD::ParamFlags::ByVal; const PointerType *Ty = cast(I->getType()); const StructType *STy = cast(Ty->getElementType()); <== HERE Ciao, Duncan. From sabre at nondot.org Sun Jan 13 14:59:05 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 20:59:05 -0000 Subject: [llvm-commits] [llvm] r45937 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll Message-ID: <200801132059.m0DKx5UR013742@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 14:59:02 2008 New Revision: 45937 URL: http://llvm.org/viewvc/llvm-project?rev=45937&view=rev Log: Fix PR1907, a nasty miscompilation because instcombine didn't realize that ne & sgt was a signed comparison (it was only looking at whether the left compare was signed). Added: llvm/trunk/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45937&r1=45936&r2=45937&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 14:59:02 2008 @@ -3495,8 +3495,14 @@ ICmpInst::isSignedPredicate(LHSCC) == ICmpInst::isSignedPredicate(RHSCC))) { // Ensure that the larger constant is on the RHS. - ICmpInst::Predicate GT = ICmpInst::isSignedPredicate(LHSCC) ? - ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; + ICmpInst::Predicate GT; + if (ICmpInst::isSignedPredicate(LHSCC) || + (ICmpInst::isEquality(LHSCC) && + ICmpInst::isSignedPredicate(RHSCC))) + GT = ICmpInst::ICMP_SGT; + else + GT = ICmpInst::ICMP_UGT; + Constant *Cmp = ConstantExpr::getICmp(GT, LHSCst, RHSCst); ICmpInst *LHS = cast(Op0); if (cast(Cmp)->getZExtValue()) { Added: llvm/trunk/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll?rev=45937&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll Sun Jan 13 14:59:02 2008 @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep and +; PR1907 + +define i1 @test(i32 %c84.17) { + %tmp2696 = icmp ne i32 %c84.17, 34 ; [#uses=2] + %tmp2699 = icmp sgt i32 %c84.17, -1 ; [#uses=1] + %tmp2703 = and i1 %tmp2696, %tmp2699 ; [#uses=1] + ret i1 %tmp2703 +} From baldrick at free.fr Sun Jan 13 15:19:12 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 21:19:12 -0000 Subject: [llvm-commits] [llvm] r45938 - /llvm/trunk/lib/VMCore/ParameterAttributes.cpp Message-ID: <200801132119.m0DLJCT9014826@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 15:19:12 2008 New Revision: 45938 URL: http://llvm.org/viewvc/llvm-project?rev=45938&view=rev Log: Allow the byval attribute for pointers to any type with a size, not just structs. Modified: llvm/trunk/lib/VMCore/ParameterAttributes.cpp Modified: llvm/trunk/lib/VMCore/ParameterAttributes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ParameterAttributes.cpp?rev=45938&r1=45937&r2=45938&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ParameterAttributes.cpp (original) +++ llvm/trunk/lib/VMCore/ParameterAttributes.cpp Sun Jan 13 15:19:12 2008 @@ -194,8 +194,8 @@ Incompatible |= SExt | ZExt; if (const PointerType *PTy = dyn_cast(Ty)) { - if (!isa(PTy->getElementType())) - // Attributes that only apply to pointers to structs. + if (!PTy->getElementType()->isSized()) + // The byval attribute only applies to pointers to types with a size. Incompatible |= ParamAttr::ByVal; } else { // Attributes that only apply to pointers. From baldrick at free.fr Sun Jan 13 15:19:59 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 21:19:59 -0000 Subject: [llvm-commits] [llvm] r45939 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200801132119.m0DLJx2q014920@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 15:19:59 2008 New Revision: 45939 URL: http://llvm.org/viewvc/llvm-project?rev=45939&view=rev Log: Remove the assumption that byval has been applied to a pointer to a struct. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=45939&r1=45938&r2=45939&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun Jan 13 15:19:59 2008 @@ -3916,12 +3916,12 @@ if (F.paramHasAttr(j, ParamAttr::ByVal)) { Flags |= ISD::ParamFlags::ByVal; const PointerType *Ty = cast(I->getType()); - const StructType *STy = cast(Ty->getElementType()); - unsigned StructAlign = - Log2_32(getTargetData()->getCallFrameTypeAlignment(STy)); - unsigned StructSize = getTargetData()->getABITypeSize(STy); - Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs); - Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs); + const Type *ElementTy = Ty->getElementType(); + unsigned FrameAlign = + Log2_32(getTargetData()->getCallFrameTypeAlignment(ElementTy)); + unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy); + Flags |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs); + Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs); } if (F.paramHasAttr(j, ParamAttr::Nest)) Flags |= ISD::ParamFlags::Nest; @@ -4046,12 +4046,12 @@ if (Args[i].isByVal) { Flags |= ISD::ParamFlags::ByVal; const PointerType *Ty = cast(Args[i].Ty); - const StructType *STy = cast(Ty->getElementType()); - unsigned StructAlign = - Log2_32(getTargetData()->getCallFrameTypeAlignment(STy)); - unsigned StructSize = getTargetData()->getABITypeSize(STy); - Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs); - Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs); + const Type *ElementTy = Ty->getElementType(); + unsigned FrameAlign = + Log2_32(getTargetData()->getCallFrameTypeAlignment(ElementTy)); + unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy); + Flags |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs); + Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs); } if (Args[i].isNest) Flags |= ISD::ParamFlags::Nest; From baldrick at free.fr Sun Jan 13 15:20:30 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 13 Jan 2008 21:20:30 -0000 Subject: [llvm-commits] [llvm] r45940 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200801132120.m0DLKUOu014955@zion.cs.uiuc.edu> Author: baldrick Date: Sun Jan 13 15:20:29 2008 New Revision: 45940 URL: http://llvm.org/viewvc/llvm-project?rev=45940&view=rev Log: Whitespace tweak. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=45940&r1=45939&r2=45940&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sun Jan 13 15:20:29 2008 @@ -1445,7 +1445,7 @@ StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); Source = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, Source); if ((Flags & ISD::ParamFlags::ByVal)==0) - Source = DAG.getLoad(VA.getValVT(), Chain, Source,NULL, 0); + Source = DAG.getLoad(VA.getValVT(), Chain, Source, NULL, 0); } if (Flags & ISD::ParamFlags::ByVal) { From sabre at nondot.org Sun Jan 13 15:54:54 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 21:54:54 -0000 Subject: [llvm-commits] [test-suite] r45941 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/stepanov_v1p2.cpp Message-ID: <200801132154.m0DLssTN016926@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 15:54:54 2008 New Revision: 45941 URL: http://llvm.org/viewvc/llvm-project?rev=45941&view=rev Log: factor the hack so that it is easier to disable. Modified: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/stepanov_v1p2.cpp Modified: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/stepanov_v1p2.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc-C%2B%2B/stepanov_v1p2.cpp?rev=45941&r1=45940&r2=45941&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Benchmarks/Misc-C++/stepanov_v1p2.cpp (original) +++ test-suite/trunk/SingleSource/Benchmarks/Misc-C++/stepanov_v1p2.cpp Sun Jan 13 15:54:54 2008 @@ -203,6 +203,9 @@ double result_times[20]; +/* This is an llvm hack to make the output not cause spurious diffs. */ +#define STABILIZE(X) (X)*0.0000001 + void summarize() { printf("\ntest absolute additions ratio with\n"); printf("number time per second test0\n\n"); @@ -211,9 +214,9 @@ for (i = 0; i < current_test; ++i) printf("%2i %5.2fsec %5.2fM %.2f\n", i, - result_times[i]/*make the output stable*/ * 0.00001, - millions/result_times[i]/*make the output stable*/ * 0.00001, - result_times[i]/result_times[0]/*make the output stable*/ * 0.00001); + STABILIZE(result_times[i]), + STABILIZE(millions/result_times[i]), + STABILIZE(result_times[i]/result_times[0])); double gmean_times = 0.; double total_absolute_times = 0.; // sam added 12/05/95 double gmean_rate = 0.; @@ -225,13 +228,13 @@ gmean_ratio += log(result_times[i]/result_times[0]); } printf("mean: %5.2fsec %5.2fM %.2f\n", - exp(gmean_times/current_test/*make the output stable*/ * 0.00001), - exp(gmean_rate/current_test/*make the output stable*/ * 0.00001), - exp(gmean_ratio/current_test)/*make the output stable*/ * 0.00001); - printf("\nTotal absolute time: %.2f sec\n", total_absolute_times - /*make the output stable*/ * 0.00001); // sam added 12/05/95 - printf("\nAbstraction Penalty: %.2f\n\n", exp(gmean_ratio/current_test) - /*make the output stable*/ * 0.00001); + exp(STABILIZE(gmean_times/current_test)), + exp(STABILIZE(gmean_rate/current_test)), + exp(STABILIZE(gmean_ratio/current_test))); + printf("\nTotal absolute time: %.2f sec\n", STABILIZE(total_absolute_times)); + // sam added 12/05/95 + printf("\nAbstraction Penalty: %.2f\n\n", + STABILIZE(exp(gmean_ratio/current_test))); } clock_t start_time, end_time; From sabre at nondot.org Sun Jan 13 16:23:26 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 22:23:26 -0000 Subject: [llvm-commits] [llvm] r45942 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200801132223.m0DMNQhs018895@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 16:23:22 2008 New Revision: 45942 URL: http://llvm.org/viewvc/llvm-project?rev=45942&view=rev Log: simplify some code by adding a InsertBitCastBefore method, make memmove->memcpy conversion a bit simpler. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45942&r1=45941&r2=45942&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 16:23:22 2008 @@ -264,6 +264,11 @@ AddToWorkList(C); return C; } + + Value *InsertBitCastBefore(Value *V, const Type *Ty, Instruction &Pos) { + return InsertCastBefore(Instruction::BitCast, V, Ty, Pos); + } + // ReplaceInstUsesWith - This method is to be used when an instruction is // found to be dead, replacable with another preexisting expression. Here @@ -2123,8 +2128,8 @@ && isa(CI->getOperand(0)->getType())) { unsigned AS = cast(CI->getOperand(0)->getType())->getAddressSpace(); - Value *I2 = InsertCastBefore(Instruction::BitCast, CI->getOperand(0), - PointerType::get(Type::Int8Ty, AS), I); + Value *I2 = InsertBitCastBefore(CI->getOperand(0), + PointerType::get(Type::Int8Ty, AS), I); I2 = InsertNewInstBefore(new GetElementPtrInst(I2, Other, "ctg2"), I); return new PtrToIntInst(I2, CI->getType()); } @@ -5116,7 +5121,7 @@ Op1 = ConstantExpr::getBitCast(Op1C, Op0->getType()); } else { // Otherwise, cast the RHS right before the icmp - Op1 = InsertCastBefore(Instruction::BitCast, Op1, Op0->getType(), I); + Op1 = InsertBitCastBefore(Op1, Op0->getType(), I); } return new ICmpInst(I.getPredicate(), Op0, Op1); } @@ -5790,8 +5795,7 @@ RHSOp = RHSC->getOperand(0); // If the pointer types don't match, insert a bitcast. if (LHSCIOp->getType() != RHSOp->getType()) - RHSOp = InsertCastBefore(Instruction::BitCast, RHSOp, - LHSCIOp->getType(), ICI); + RHSOp = InsertBitCastBefore(RHSOp, LHSCIOp->getType(), ICI); } if (RHSOp) @@ -7837,15 +7841,12 @@ if (GlobalVariable *GVSrc = dyn_cast(MMI->getSource())) if (GVSrc->isConstant()) { Module *M = CI.getParent()->getParent()->getParent(); - const char *Name; - if (CI.getCalledFunction()->getFunctionType()->getParamType(2) == - Type::Int32Ty) - Name = "llvm.memcpy.i32"; + Intrinsic::ID MemCpyID; + if (CI.getOperand(3)->getType() == Type::Int32Ty) + MemCpyID = Intrinsic::memcpy_i32; else - Name = "llvm.memcpy.i64"; - Constant *MemCpy = M->getOrInsertFunction(Name, - CI.getCalledFunction()->getFunctionType()); - CI.setOperand(0, MemCpy); + MemCpyID = Intrinsic::memcpy_i64; + CI.setOperand(0, Intrinsic::getDeclaration(M, MemCpyID)); Changed = true; } } @@ -7877,10 +7878,8 @@ NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); if (NewPtrTy) { - Value *Src = InsertCastBefore(Instruction::BitCast, CI.getOperand(2), - NewPtrTy, CI); - Value *Dest = InsertCastBefore(Instruction::BitCast, CI.getOperand(1), - NewPtrTy, CI); + Value *Src = InsertBitCastBefore(CI.getOperand(2), NewPtrTy, CI); + Value *Dest = InsertBitCastBefore(CI.getOperand(1), NewPtrTy, CI); Value *L = new LoadInst(Src, "tmp", false, Align, &CI); Value *NS = new StoreInst(L, Dest, false, Align, &CI); CI.replaceAllUsesWith(NS); @@ -7908,9 +7907,9 @@ // Turn PPC lvx -> load if the pointer is known aligned. // Turn X86 loadups -> load if the pointer is known aligned. if (GetOrEnforceKnownAlignment(II->getOperand(1), TD, 16) >= 16) { - Value *Ptr = - InsertCastBefore(Instruction::BitCast, II->getOperand(1), - PointerType::getUnqual(II->getType()), CI); + Value *Ptr = InsertBitCastBefore(II->getOperand(1), + PointerType::getUnqual(II->getType()), + CI); return new LoadInst(Ptr); } break; @@ -7920,8 +7919,7 @@ if (GetOrEnforceKnownAlignment(II->getOperand(2), TD, 16) >= 16) { const Type *OpPtrTy = PointerType::getUnqual(II->getOperand(1)->getType()); - Value *Ptr = InsertCastBefore(Instruction::BitCast, II->getOperand(2), - OpPtrTy, CI); + Value *Ptr = InsertBitCastBefore(II->getOperand(2), OpPtrTy, CI); return new StoreInst(II->getOperand(1), Ptr); } break; @@ -7933,8 +7931,7 @@ if (GetOrEnforceKnownAlignment(II->getOperand(1), TD, 16) >= 16) { const Type *OpPtrTy = PointerType::getUnqual(II->getOperand(2)->getType()); - Value *Ptr = InsertCastBefore(Instruction::BitCast, II->getOperand(1), - OpPtrTy, CI); + Value *Ptr = InsertBitCastBefore(II->getOperand(1), OpPtrTy, CI); return new StoreInst(II->getOperand(2), Ptr); } break; @@ -7968,10 +7965,8 @@ if (AllEltsOk) { // Cast the input vectors to byte vectors. - Value *Op0 = InsertCastBefore(Instruction::BitCast, - II->getOperand(1), Mask->getType(), CI); - Value *Op1 = InsertCastBefore(Instruction::BitCast, - II->getOperand(2), Mask->getType(), CI); + Value *Op0 =InsertBitCastBefore(II->getOperand(1),Mask->getType(),CI); + Value *Op1 =InsertBitCastBefore(II->getOperand(2),Mask->getType(),CI); Value *Result = UndefValue::get(Op0->getType()); // Only extract each element once. @@ -10040,8 +10035,8 @@ } else if (isa(I)) { unsigned AS = cast(I->getOperand(0)->getType())->getAddressSpace(); - Value *Ptr = InsertCastBefore(Instruction::BitCast, I->getOperand(0), - PointerType::get(EI.getType(), AS), EI); + Value *Ptr = InsertBitCastBefore(I->getOperand(0), + PointerType::get(EI.getType(), AS),EI); GetElementPtrInst *GEP = new GetElementPtrInst(Ptr, EI.getOperand(1), I->getName() + ".gep"); InsertNewInstBefore(GEP, EI); From sabre at nondot.org Sun Jan 13 16:30:29 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 22:30:29 -0000 Subject: [llvm-commits] [llvm] r45943 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200801132230.m0DMUT5o019402@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 16:30:28 2008 New Revision: 45943 URL: http://llvm.org/viewvc/llvm-project?rev=45943&view=rev Log: simplify some code. If we can infer alignment for source and dest that are greater than memcpy alignment, and if we lower to load/store, use the best alignment info we have. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45943&r1=45942&r2=45943&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 16:30:28 2008 @@ -7854,34 +7854,35 @@ // If we can determine a pointer alignment that is bigger than currently // set, update the alignment. if (isa(MI) || isa(MI)) { - unsigned Alignment1 = GetOrEnforceKnownAlignment(MI->getOperand(1), TD); - unsigned Alignment2 = GetOrEnforceKnownAlignment(MI->getOperand(2), TD); - unsigned Align = std::min(Alignment1, Alignment2); - if (MI->getAlignment()->getZExtValue() < Align) { - MI->setAlignment(ConstantInt::get(Type::Int32Ty, Align)); + unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1), TD); + unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2), TD); + unsigned MinAlign = std::min(DstAlign, SrcAlign); + unsigned CopyAlign = MI->getAlignment()->getZExtValue(); + if (CopyAlign < MinAlign) { + MI->setAlignment(ConstantInt::get(Type::Int32Ty, MinAlign)); Changed = true; } - + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with // load/store. - ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3)); - if (MemOpLength) { + if (ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3))) { + // Source and destination pointer types are always "i8*" for intrinsic. + // If Size is 8 then use Int64Ty + // If Size is 4 then use Int32Ty + // If Size is 2 then use Int16Ty + // If Size is 1 then use Int8Ty unsigned Size = MemOpLength->getZExtValue(); - unsigned Align = cast(CI.getOperand(4))->getZExtValue(); - PointerType *NewPtrTy = NULL; - // Destination pointer type is always i8 * - // If Size is 8 then use Int64Ty - // If Size is 4 then use Int32Ty - // If Size is 2 then use Int16Ty - // If Size is 1 then use Int8Ty - if (Size && Size <=8 && !(Size&(Size-1))) - NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); - - if (NewPtrTy) { + if (Size && Size <= 8 && !(Size&(Size-1))) { + Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); + // If the memcpy/memmove provides better alignment info than we can + // infer, use it. + SrcAlign = std::max(SrcAlign, CopyAlign); + DstAlign = std::max(DstAlign, CopyAlign); + Value *Src = InsertBitCastBefore(CI.getOperand(2), NewPtrTy, CI); Value *Dest = InsertBitCastBefore(CI.getOperand(1), NewPtrTy, CI); - Value *L = new LoadInst(Src, "tmp", false, Align, &CI); - Value *NS = new StoreInst(L, Dest, false, Align, &CI); + Value *L = new LoadInst(Src, "tmp", false, SrcAlign, &CI); + Value *NS = new StoreInst(L, Dest, false, DstAlign, &CI); CI.replaceAllUsesWith(NS); Changed = true; return EraseInstFromFunction(CI); From sabre at nondot.org Sun Jan 13 17:50:24 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 13 Jan 2008 23:50:24 -0000 Subject: [llvm-commits] [llvm] r45944 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200801132350.m0DNoOlL023929@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 17:50:23 2008 New Revision: 45944 URL: http://llvm.org/viewvc/llvm-project?rev=45944&view=rev Log: factor memcpy/memmove simplification out to its own SimplifyMemTransfer method, no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45944&r1=45943&r2=45944&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 17:50:23 2008 @@ -366,6 +366,8 @@ Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocationInst &AI); Instruction *MatchBSwap(BinaryOperator &I); bool SimplifyStoreAtEndOfBlock(StoreInst &SI); + Instruction *SimplifyMemTransfer(MemIntrinsic *MI); + Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned); }; @@ -7808,6 +7810,43 @@ return 0; } +Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { + unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1), TD); + unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2), TD); + unsigned MinAlign = std::min(DstAlign, SrcAlign); + unsigned CopyAlign = MI->getAlignment()->getZExtValue(); + + if (CopyAlign < MinAlign) { + MI->setAlignment(ConstantInt::get(Type::Int32Ty, MinAlign)); + return MI; + } + + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with + // load/store. + ConstantInt *MemOpLength = dyn_cast(MI->getOperand(3)); + if (MemOpLength == 0) return 0; + + // Source and destination pointer types are always "i8*" for intrinsic. + // If Size is 8 then use Int64Ty + // If Size is 4 then use Int32Ty + // If Size is 2 then use Int16Ty + // If Size is 1 then use Int8Ty + unsigned Size = MemOpLength->getZExtValue(); + if (Size == 0 || Size > 8 || (Size&(Size-1))) + return 0; // If not 1/2/4/8, exit. + + Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); + // If the memcpy/memmove provides better alignment info than we can + // infer, use it. + SrcAlign = std::max(SrcAlign, CopyAlign); + DstAlign = std::max(DstAlign, CopyAlign); + + Value *Src = InsertBitCastBefore(MI->getOperand(2), NewPtrTy, *MI); + Value *Dest = InsertBitCastBefore(MI->getOperand(1), NewPtrTy, *MI); + Value *L = new LoadInst(Src, "tmp", false, SrcAlign, MI); + new StoreInst(L, Dest, false, DstAlign, MI); + return EraseInstFromFunction(*MI); +} /// visitCallInst - CallInst simplification. This mostly only handles folding /// of intrinsic instructions. For normal calls, it allows visitCallSite to do @@ -7837,7 +7876,7 @@ // If we have a memmove and the source operation is a constant global, // then the source and dest pointers can't alias, so we can change this // into a call to memcpy. - if (MemMoveInst *MMI = dyn_cast(II)) { + if (MemMoveInst *MMI = dyn_cast(MI)) { if (GlobalVariable *GVSrc = dyn_cast(MMI->getSource())) if (GVSrc->isConstant()) { Module *M = CI.getParent()->getParent()->getParent(); @@ -7854,40 +7893,8 @@ // If we can determine a pointer alignment that is bigger than currently // set, update the alignment. if (isa(MI) || isa(MI)) { - unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1), TD); - unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2), TD); - unsigned MinAlign = std::min(DstAlign, SrcAlign); - unsigned CopyAlign = MI->getAlignment()->getZExtValue(); - if (CopyAlign < MinAlign) { - MI->setAlignment(ConstantInt::get(Type::Int32Ty, MinAlign)); - Changed = true; - } - - // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with - // load/store. - if (ConstantInt *MemOpLength = dyn_cast(CI.getOperand(3))) { - // Source and destination pointer types are always "i8*" for intrinsic. - // If Size is 8 then use Int64Ty - // If Size is 4 then use Int32Ty - // If Size is 2 then use Int16Ty - // If Size is 1 then use Int8Ty - unsigned Size = MemOpLength->getZExtValue(); - if (Size && Size <= 8 && !(Size&(Size-1))) { - Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); - // If the memcpy/memmove provides better alignment info than we can - // infer, use it. - SrcAlign = std::max(SrcAlign, CopyAlign); - DstAlign = std::max(DstAlign, CopyAlign); - - Value *Src = InsertBitCastBefore(CI.getOperand(2), NewPtrTy, CI); - Value *Dest = InsertBitCastBefore(CI.getOperand(1), NewPtrTy, CI); - Value *L = new LoadInst(Src, "tmp", false, SrcAlign, &CI); - Value *NS = new StoreInst(L, Dest, false, DstAlign, &CI); - CI.replaceAllUsesWith(NS); - Changed = true; - return EraseInstFromFunction(CI); - } - } + if (Instruction *I = SimplifyMemTransfer(MI)) + return I; } else if (isa(MI)) { unsigned Alignment = GetOrEnforceKnownAlignment(MI->getDest(), TD); if (MI->getAlignment()->getZExtValue() < Alignment) { From sabre at nondot.org Sun Jan 13 18:28:35 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 14 Jan 2008 00:28:35 -0000 Subject: [llvm-commits] [llvm] r45945 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/memcpy-to-load.ll Message-ID: <200801140028.m0E0SaeD026862@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 18:28:35 2008 New Revision: 45945 URL: http://llvm.org/viewvc/llvm-project?rev=45945&view=rev Log: Turn a memcpy from a double* into a load/store of double instead of a load/store of i64. The later prevents promotion/scalarrepl of the source and dest in many cases. This fixes the 300% performance regression of the byval stuff on stepanov_v1p2. Added: llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45945&r1=45944&r2=45945&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 18:28:35 2008 @@ -7826,16 +7826,49 @@ ConstantInt *MemOpLength = dyn_cast(MI->getOperand(3)); if (MemOpLength == 0) return 0; - // Source and destination pointer types are always "i8*" for intrinsic. - // If Size is 8 then use Int64Ty - // If Size is 4 then use Int32Ty - // If Size is 2 then use Int16Ty - // If Size is 1 then use Int8Ty + // Source and destination pointer types are always "i8*" for intrinsic. See + // if the size is something we can handle with a single primitive load/store. + // A single load+store correctly handles overlapping memory in the memmove + // case. unsigned Size = MemOpLength->getZExtValue(); if (Size == 0 || Size > 8 || (Size&(Size-1))) - return 0; // If not 1/2/4/8, exit. + return 0; // If not 1/2/4/8 bytes, exit. + // Use an integer load+store unless we can find something better. Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); + + // Memcpy forces the use of i8* for the source and destination. That means + // that if you're using memcpy to move one double around, you'll get a cast + // from double* to i8*. We'd much rather use a double load+store rather than + // an i64 load+store, here because this improves the odds that the source or + // dest address will be promotable. See if we can find a better type than the + // integer datatype. + if (Value *Op = getBitCastOperand(MI->getOperand(1))) { + const Type *SrcETy = cast(Op->getType())->getElementType(); + if (SrcETy->isSized() && TD->getTypeStoreSize(SrcETy) == Size) { + // The SrcETy might be something like {{{double}}} or [1 x double]. Rip + // down through these levels if so. + while (!SrcETy->isFirstClassType()) { + if (const StructType *STy = dyn_cast(SrcETy)) { + if (STy->getNumElements() == 1) + SrcETy = STy->getElementType(0); + else + break; + } else if (const ArrayType *ATy = dyn_cast(SrcETy)) { + if (ATy->getNumElements() == 1) + SrcETy = ATy->getElementType(); + else + break; + } else + break; + } + + if (SrcETy->isFirstClassType()) + NewPtrTy = PointerType::getUnqual(SrcETy); + } + } + + // If the memcpy/memmove provides better alignment info than we can // infer, use it. SrcAlign = std::max(SrcAlign, CopyAlign); @@ -7843,9 +7876,13 @@ Value *Src = InsertBitCastBefore(MI->getOperand(2), NewPtrTy, *MI); Value *Dest = InsertBitCastBefore(MI->getOperand(1), NewPtrTy, *MI); - Value *L = new LoadInst(Src, "tmp", false, SrcAlign, MI); - new StoreInst(L, Dest, false, DstAlign, MI); - return EraseInstFromFunction(*MI); + Instruction *L = new LoadInst(Src, "tmp", false, SrcAlign); + InsertNewInstBefore(L, *MI); + InsertNewInstBefore(new StoreInst(L, Dest, false, DstAlign), *MI); + + // Set the size of the copy to 0, it will be deleted on the next iteration. + MI->setOperand(3, Constant::getNullValue(MemOpLength->getType())); + return MI; } /// visitCallInst - CallInst simplification. This mostly only handles folding Added: llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll?rev=45945&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll Sun Jan 13 18:28:35 2008 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {load double} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i686-apple-darwin8" + +define void @foo(double* %X, double* %Y) { +entry: + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %tmp2 = bitcast double* %X to i8* ; [#uses=1] + %tmp13 = bitcast double* %Y to i8* ; [#uses=1] + call void @llvm.memcpy.i32( i8* %tmp2, i8* %tmp13, i32 8, i32 1 ) + ret void +} + +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind From sabre at nondot.org Sun Jan 13 19:17:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 14 Jan 2008 01:17:46 -0000 Subject: [llvm-commits] [llvm] r45946 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200801140117.m0E1HkVh029218@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 19:17:44 2008 New Revision: 45946 URL: http://llvm.org/viewvc/llvm-project?rev=45946&view=rev Log: Make the 'shrink global to bool' optimization more self contained, and thus easier to show that its safe. No functionality change. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=45946&r1=45945&r2=45946&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Jan 13 19:17:44 2008 @@ -1257,9 +1257,28 @@ return false; } -/// ShrinkGlobalToBoolean - At this point, we have learned that the only two -/// values ever stored into GV are its initializer and OtherVal. -static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { +/// TryToShrinkGlobalToBoolean - At this point, we have learned that the only +/// two values ever stored into GV are its initializer and OtherVal. See if we +/// can shrink the global into a boolean and select between the two values +/// whenever it is used. This exposes the values to other scalar optimizations. +static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { + const Type *GVElType = GV->getType()->getElementType(); + + // If GVElType is already i1, it is already shrunk. If the type of the GV is + // an FP value or vector, don't do this optimization because a select between + // them is very expensive and unlikely to lead to later simplification. + if (GVElType == Type::Int1Ty || GVElType->isFloatingPoint() || + isa(GVElType)) + return false; + + // Walk the use list of the global seeing if all the uses are load or store. + // If there is anything else, bail out. + for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I) + if (!isa(I) && !isa(I)) + return false; + + DOUT << " *** SHRINKING TO BOOL: " << *GV; + // Create the new global, initializing it to false. GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage, ConstantInt::getFalse(), @@ -1307,7 +1326,7 @@ } } new StoreInst(StoreVal, NewGV, SI); - } else if (!UI->use_empty()) { + } else { // Change the load into a load of bool then a select. LoadInst *LI = cast(UI); LoadInst *NLI = new LoadInst(NewGV, LI->getName()+".b", LI); @@ -1323,6 +1342,7 @@ } GV->eraseFromParent(); + return true; } @@ -1464,12 +1484,7 @@ // Otherwise, if the global was not a boolean, we can shrink it to be a // boolean. if (Constant *SOVConstant = dyn_cast(GS.StoredOnceValue)) - if (GV->getType()->getElementType() != Type::Int1Ty && - !GV->getType()->getElementType()->isFloatingPoint() && - !isa(GV->getType()->getElementType()) && - !GS.HasPHIUser && !GS.isNotSuitableForSRA) { - DOUT << " *** SHRINKING TO BOOL: " << *GV; - ShrinkGlobalToBoolean(GV, SOVConstant); + if (TryToShrinkGlobalToBoolean(GV, SOVConstant)) { ++NumShrunkToBool; return true; } From sabre at nondot.org Sun Jan 13 19:31:05 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 14 Jan 2008 01:31:05 -0000 Subject: [llvm-commits] [llvm] r45947 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200801140131.m0E1V5uW029698@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 19:31:05 2008 New Revision: 45947 URL: http://llvm.org/viewvc/llvm-project?rev=45947&view=rev Log: Change SRAGlobal to not depend on isNotSuitableForSRA, which makes it very difficult to understand the invariants. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=45947&r1=45946&r2=45947&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Jan 13 19:31:05 2008 @@ -378,12 +378,86 @@ return Changed; } + +/// UsersSafeToSRA - Look at all uses of the global and decide whether it is +/// safe for us to perform this transformation. +/// +static bool UsersSafeToSRA(Value *V) { + for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){ + if (ConstantExpr *CE = dyn_cast(*UI)) { + if (CE->getOpcode() != Instruction::GetElementPtr) + return false; + + // Check to see if this ConstantExpr GEP is SRA'able. In particular, we + // don't like < 3 operand CE's, and we don't like non-constant integer + // indices. + if (CE->getNumOperands() < 3 || !CE->getOperand(1)->isNullValue()) + return false; + + for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) + if (!isa(CE->getOperand(i))) + return false; + + if (!UsersSafeToSRA(CE)) return false; + continue; + } + + if (Instruction *I = dyn_cast(*UI)) { + if (isa(I)) continue; + + if (StoreInst *SI = dyn_cast(I)) { + // Don't allow a store OF the address, only stores TO the address. + if (SI->getOperand(0) == V) return false; + continue; + } + + if (isa(I)) { + if (!UsersSafeToSRA(I)) return false; + + // If the first two indices are constants, this can be SRA'd. + if (isa(I->getOperand(0))) { + if (I->getNumOperands() < 3 || !isa(I->getOperand(1)) || + !cast(I->getOperand(1))->isNullValue() || + !isa(I->getOperand(2))) + return false; + continue; + } + + if (ConstantExpr *CE = dyn_cast(I->getOperand(0))){ + if (CE->getOpcode() != Instruction::GetElementPtr || + CE->getNumOperands() < 3 || I->getNumOperands() < 2 || + !isa(I->getOperand(0)) || + !cast(I->getOperand(0))->isNullValue()) + return false; + continue; + } + return false; + } + return false; // Any other instruction is not safe. + } + if (Constant *C = dyn_cast(*UI)) { + // We might have a dead and dangling constant hanging off of here. + if (!ConstantIsDead(C)) + return false; + continue; + } + // Otherwise must be some other user. + return false; + } + + return true; +} + /// SRAGlobal - Perform scalar replacement of aggregates on the specified global /// variable. This opens the door for other optimizations by exposing the /// behavior of the program in a more fine-grained way. We have determined that /// this transformation is safe already. We return the first global variable we /// insert so that the caller can reprocess it. static GlobalVariable *SRAGlobal(GlobalVariable *GV) { + // Make sure this global only has simple uses that we can SRA. + if (!UsersSafeToSRA(GV)) + return 0; + assert(GV->hasInternalLinkage() && !GV->isConstant()); Constant *Init = GV->getInitializer(); const Type *Ty = Init->getType(); @@ -1444,8 +1518,7 @@ ++NumMarked; return true; - } else if (!GS.isNotSuitableForSRA && - !GV->getInitializer()->getType()->isFirstClassType()) { + } else if (!GV->getInitializer()->getType()->isFirstClassType()) { if (GlobalVariable *FirstNewGV = SRAGlobal(GV)) { GVI = FirstNewGV; // Don't skip the newly produced globals! return true; From sabre at nondot.org Sun Jan 13 19:32:52 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 14 Jan 2008 01:32:52 -0000 Subject: [llvm-commits] [llvm] r45948 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <200801140132.m0E1WqL2029770@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 19:32:52 2008 New Revision: 45948 URL: http://llvm.org/viewvc/llvm-project?rev=45948&view=rev Log: The isNotSuitableForSRA property is now dead, don't compute it. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=45948&r1=45947&r2=45948&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Jan 13 19:32:52 2008 @@ -119,15 +119,9 @@ /// HasPHIUser - Set to true if this global has a user that is a PHI node. bool HasPHIUser; - /// isNotSuitableForSRA - Keep track of whether any SRA preventing users of - /// the global exist. Such users include GEP instruction with variable - /// indexes, and non-gep/load/store users like constant expr casts. - bool isNotSuitableForSRA; - GlobalStatus() : isLoaded(false), StoredType(NotStored), StoredOnceValue(0), AccessingFunction(0), HasMultipleAccessingFunctions(false), - HasNonInstructionUser(false), HasPHIUser(false), - isNotSuitableForSRA(false) {} + HasNonInstructionUser(false), HasPHIUser(false) {} }; @@ -159,22 +153,6 @@ GS.HasNonInstructionUser = true; if (AnalyzeGlobal(CE, GS, PHIUsers)) return true; - if (CE->getOpcode() != Instruction::GetElementPtr) - GS.isNotSuitableForSRA = true; - else if (!GS.isNotSuitableForSRA) { - // Check to see if this ConstantExpr GEP is SRA'able. In particular, we - // don't like < 3 operand CE's, and we don't like non-constant integer - // indices. - if (CE->getNumOperands() < 3 || !CE->getOperand(1)->isNullValue()) - GS.isNotSuitableForSRA = true; - else { - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) - if (!isa(CE->getOperand(i))) { - GS.isNotSuitableForSRA = true; - break; - } - } - } } else if (Instruction *I = dyn_cast(*UI)) { if (!GS.HasMultipleAccessingFunctions) { @@ -218,44 +196,23 @@ } } else if (isa(I)) { if (AnalyzeGlobal(I, GS, PHIUsers)) return true; - - // If the first two indices are constants, this can be SRA'd. - if (isa(I->getOperand(0))) { - if (I->getNumOperands() < 3 || !isa(I->getOperand(1)) || - !cast(I->getOperand(1))->isNullValue() || - !isa(I->getOperand(2))) - GS.isNotSuitableForSRA = true; - } else if (ConstantExpr *CE = dyn_cast(I->getOperand(0))){ - if (CE->getOpcode() != Instruction::GetElementPtr || - CE->getNumOperands() < 3 || I->getNumOperands() < 2 || - !isa(I->getOperand(0)) || - !cast(I->getOperand(0))->isNullValue()) - GS.isNotSuitableForSRA = true; - } else { - GS.isNotSuitableForSRA = true; - } } else if (isa(I)) { if (AnalyzeGlobal(I, GS, PHIUsers)) return true; - GS.isNotSuitableForSRA = true; } else if (PHINode *PN = dyn_cast(I)) { // PHI nodes we can check just like select or GEP instructions, but we // have to be careful about infinite recursion. if (PHIUsers.insert(PN).second) // Not already visited. if (AnalyzeGlobal(I, GS, PHIUsers)) return true; - GS.isNotSuitableForSRA = true; GS.HasPHIUser = true; } else if (isa(I)) { - GS.isNotSuitableForSRA = true; } else if (isa(I) || isa(I)) { if (I->getOperand(1) == V) GS.StoredType = GlobalStatus::isStored; if (I->getOperand(2) == V) GS.isLoaded = true; - GS.isNotSuitableForSRA = true; } else if (isa(I)) { assert(I->getOperand(1) == V && "Memset only takes one pointer!"); GS.StoredType = GlobalStatus::isStored; - GS.isNotSuitableForSRA = true; } else { return true; // Any other non-load instruction might take address! } @@ -1454,7 +1411,6 @@ cerr << " HasMultipleAccessingFunctions = " << GS.HasMultipleAccessingFunctions << "\n"; cerr << " HasNonInstructionUser = " << GS.HasNonInstructionUser<<"\n"; - cerr << " isNotSuitableForSRA = " << GS.isNotSuitableForSRA << "\n"; cerr << "\n"; #endif From sabre at nondot.org Sun Jan 13 20:09:12 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 14 Jan 2008 02:09:12 -0000 Subject: [llvm-commits] [llvm] r45949 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll Message-ID: <200801140209.m0E29DkL031083@zion.cs.uiuc.edu> Author: lattner Date: Sun Jan 13 20:09:12 2008 New Revision: 45949 URL: http://llvm.org/viewvc/llvm-project?rev=45949&view=rev Log: Fix the miscompilation of MiBench/consumer-lame that was exposed by Evan's byval work. This miscompilation is due to the program indexing an array out of range and us doing a transformation that broke this. Added: llvm/trunk/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=45949&r1=45948&r2=45949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Jan 13 20:09:12 2008 @@ -26,6 +26,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -335,76 +336,113 @@ return Changed; } +/// isSafeSROAElementUse - Return true if the specified instruction is a safe +/// user of a derived expression from a global that we want to SROA. +static bool isSafeSROAElementUse(Value *V) { + // We might have a dead and dangling constant hanging off of here. + if (Constant *C = dyn_cast(V)) + return ConstantIsDead(C); + + Instruction *I = dyn_cast(V); + if (!I) return false; + + // Loads are ok. + if (isa(I)) return true; + + // Stores *to* the pointer are ok. + if (StoreInst *SI = dyn_cast(I)) + return SI->getOperand(0) != V; + + // Otherwise, it must be a GEP. + GetElementPtrInst *GEPI = dyn_cast(I); + if (GEPI == 0) return false; + + if (GEPI->getNumOperands() < 3 || !isa(GEPI->getOperand(1)) || + !cast(GEPI->getOperand(1))->isNullValue()) + return false; + + for (Value::use_iterator I = GEPI->use_begin(), E = GEPI->use_end(); + I != E; ++I) + if (!isSafeSROAElementUse(*I)) + return false; + return true; +} -/// UsersSafeToSRA - Look at all uses of the global and decide whether it is -/// safe for us to perform this transformation. + +/// IsUserOfGlobalSafeForSRA - U is a direct user of the specified global value. +/// Look at it and its uses and decide whether it is safe to SROA this global. /// -static bool UsersSafeToSRA(Value *V) { - for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){ - if (ConstantExpr *CE = dyn_cast(*UI)) { - if (CE->getOpcode() != Instruction::GetElementPtr) - return false; +static bool IsUserOfGlobalSafeForSRA(User *U, GlobalValue *GV) { + // The user of the global must be a GEP Inst or a ConstantExpr GEP. + if (!isa(U) && + (!isa(U) || + cast(U)->getOpcode() != Instruction::GetElementPtr)) + return false; + + // Check to see if this ConstantExpr GEP is SRA'able. In particular, we + // don't like < 3 operand CE's, and we don't like non-constant integer + // indices. This enforces that all uses are 'gep GV, 0, C, ...' for some + // value of C. + if (U->getNumOperands() < 3 || !isa(U->getOperand(1)) || + !cast(U->getOperand(1))->isNullValue() || + !isa(U->getOperand(2))) + return false; - // Check to see if this ConstantExpr GEP is SRA'able. In particular, we - // don't like < 3 operand CE's, and we don't like non-constant integer - // indices. - if (CE->getNumOperands() < 3 || !CE->getOperand(1)->isNullValue()) - return false; - - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) - if (!isa(CE->getOperand(i))) - return false; - - if (!UsersSafeToSRA(CE)) return false; - continue; - } + gep_type_iterator GEPI = gep_type_begin(U), E = gep_type_end(U); + ++GEPI; // Skip over the pointer index. + + // If this is a use of an array allocation, do a bit more checking for sanity. + if (const ArrayType *AT = dyn_cast(*GEPI)) { + uint64_t NumElements = AT->getNumElements(); + ConstantInt *Idx = cast(U->getOperand(2)); - if (Instruction *I = dyn_cast(*UI)) { - if (isa(I)) continue; + // Check to make sure that index falls within the array. If not, + // something funny is going on, so we won't do the optimization. + // + if (Idx->getZExtValue() >= NumElements) + return false; - if (StoreInst *SI = dyn_cast(I)) { - // Don't allow a store OF the address, only stores TO the address. - if (SI->getOperand(0) == V) return false; - continue; - } + // We cannot scalar repl this level of the array unless any array + // sub-indices are in-range constants. In particular, consider: + // A[0][i]. We cannot know that the user isn't doing invalid things like + // allowing i to index an out-of-range subscript that accesses A[1]. + // + // Scalar replacing *just* the outer index of the array is probably not + // going to be a win anyway, so just give up. + for (++GEPI; // Skip array index. + GEPI != E && (isa(*GEPI) || isa(*GEPI)); + ++GEPI) { + uint64_t NumElements; + if (const ArrayType *SubArrayTy = dyn_cast(*GEPI)) + NumElements = SubArrayTy->getNumElements(); + else + NumElements = cast(*GEPI)->getNumElements(); - if (isa(I)) { - if (!UsersSafeToSRA(I)) return false; - - // If the first two indices are constants, this can be SRA'd. - if (isa(I->getOperand(0))) { - if (I->getNumOperands() < 3 || !isa(I->getOperand(1)) || - !cast(I->getOperand(1))->isNullValue() || - !isa(I->getOperand(2))) - return false; - continue; - } - - if (ConstantExpr *CE = dyn_cast(I->getOperand(0))){ - if (CE->getOpcode() != Instruction::GetElementPtr || - CE->getNumOperands() < 3 || I->getNumOperands() < 2 || - !isa(I->getOperand(0)) || - !cast(I->getOperand(0))->isNullValue()) - return false; - continue; - } - return false; - } - return false; // Any other instruction is not safe. - } - if (Constant *C = dyn_cast(*UI)) { - // We might have a dead and dangling constant hanging off of here. - if (!ConstantIsDead(C)) + ConstantInt *IdxVal = dyn_cast(GEPI.getOperand()); + if (!IdxVal || IdxVal->getZExtValue() >= NumElements) return false; - continue; } - // Otherwise must be some other user. - return false; } - + + for (Value::use_iterator I = U->use_begin(), E = U->use_end(); I != E; ++I) + if (!isSafeSROAElementUse(*I)) + return false; return true; } +/// GlobalUsersSafeToSRA - Look at all uses of the global and decide whether it +/// is safe for us to perform this transformation. +/// +static bool GlobalUsersSafeToSRA(GlobalValue *GV) { + for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); + UI != E; ++UI) { + if (!IsUserOfGlobalSafeForSRA(*UI, GV)) + return false; + } + return true; +} + + /// SRAGlobal - Perform scalar replacement of aggregates on the specified global /// variable. This opens the door for other optimizations by exposing the /// behavior of the program in a more fine-grained way. We have determined that @@ -412,7 +450,7 @@ /// insert so that the caller can reprocess it. static GlobalVariable *SRAGlobal(GlobalVariable *GV) { // Make sure this global only has simple uses that we can SRA. - if (!UsersSafeToSRA(GV)) + if (!GlobalUsersSafeToSRA(GV)) return 0; assert(GV->hasInternalLinkage() && !GV->isConstant()); Added: llvm/trunk/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll?rev=45949&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll (added) +++ llvm/trunk/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll Sun Jan 13 20:09:12 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -globalopt | llvm-dis | grep {16 x .31 x double.. zeroinitializer} + +; The 'X' indices could be larger than 31. Do not SROA the outer indices of this array. + at mm = internal global [16 x [31 x double]] zeroinitializer, align 32 + +define void @test(i32 %X) { + %P = getelementptr [16 x [31 x double]]* @mm, i32 0, i32 0, i32 %X + store double 1.0, double* %P + ret void +} + +define double @get(i32 %X) { + %P = getelementptr [16 x [31 x double]]* @mm, i32 0, i32 0, i32 %X + %V = load double* %P + ret double %V +} From evan.cheng at apple.com Sun Jan 13 20:22:01 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 13 Jan 2008 18:22:01 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r45907 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-types.cpp In-Reply-To: <200801132137.20842.duncan.sands@math.u-psud.fr> References: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> <200801131054.49034.duncan.sands@math.u-psud.fr> <0F5C42A0-9BD2-485F-AA0B-9D87CEDCBB8D@apple.com> <200801132137.20842.duncan.sands@math.u-psud.fr> Message-ID: On Jan 13, 2008, at 12:37 PM, Duncan Sands wrote: > Hi Chris, > >> byval makes sense semantically for any pointer to sized type, I think >> it would be reasonable to expand it to allow any of these pointers, >> including the one above. > > I adjusted the check to allow pointers to arrays, but got a crash in > SelectionDAGISel.cpp: > > if (F.paramHasAttr(j, ParamAttr::ByVal)) { > Flags |= ISD::ParamFlags::ByVal; > const PointerType *Ty = cast(I->getType()); > const StructType *STy = cast(Ty->getElementType()); > <== HERE Thanks. I see you have fixed the crash in SelectionDAGISel.cpp? Evan > > Ciao, > > Duncan. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Sun Jan 13 20:38:47 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Jan 2008 02:38:47 -0000 Subject: [llvm-commits] [llvm] r45950 - /llvm/trunk/lib/VMCore/Instructions.cpp Message-ID: <200801140238.m0E2clkn032185@zion.cs.uiuc.edu> Author: evancheng Date: Sun Jan 13 20:38:45 2008 New Revision: 45950 URL: http://llvm.org/viewvc/llvm-project?rev=45950&view=rev Log: Simplify code. Modified: llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=45950&r1=45949&r2=45950&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Sun Jan 13 20:38:45 2008 @@ -406,10 +406,7 @@ /// @brief Determine if any call argument is an aggregate passed by value. bool CallInst::hasByValArgument() const { - const Value *Callee = getCalledValue(); - const PointerType *CalleeTy = cast(Callee->getType()); - const FunctionType *FTy = cast(CalleeTy->getElementType()); - for (unsigned i = 1, e = FTy->getNumParams()+1; i != e; ++i) + for (unsigned i = 1, e = getNumOperands(); i != e; ++i) if (paramHasAttr(i, ParamAttr::ByVal)) return true; return false; From duncan.sands at math.u-psud.fr Sun Jan 13 22:15:58 2008 From: duncan.sands at math.u-psud.fr (Duncan Sands) Date: Mon, 14 Jan 2008 05:15:58 +0100 Subject: [llvm-commits] =?iso-8859-1?q?=5Bllvm-gcc-4=2E2=5D_r45907_-_in=09?= =?iso-8859-1?q?/llvm-gcc-4=2E2/trunk/gcc=3A_llvm-abi=2Eh_llvm-convert=2Ec?= =?iso-8859-1?q?pp_llvm-types=2Ecpp?= In-Reply-To: References: <200801120922.m0C9MiwB020154@zion.cs.uiuc.edu> <200801132137.20842.duncan.sands@math.u-psud.fr> Message-ID: <200801140515.59704.duncan.sands@math.u-psud.fr> > Thanks. I see you have fixed the crash in SelectionDAGISel.cpp? Yes, and this fixes the Ada build. Ciao, Duncan.