From lattner at cs.uiuc.edu Mon Aug 4 00:00:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:02 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200308031724.MAA23619@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.15 -> 1.16 --- Log message: Add support for instruction enum emission --- Diffs of the changes: Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.15 llvm/utils/TableGen/TableGen.cpp:1.16 --- llvm/utils/TableGen/TableGen.cpp:1.15 Fri Aug 1 15:35:01 2003 +++ llvm/utils/TableGen/TableGen.cpp Sun Aug 3 12:24:20 2003 @@ -14,6 +14,7 @@ #include "Support/FileUtilities.h" #include "CodeEmitterGen.h" #include "RegisterInfoEmitter.h" +#include "InstrInfoEmitter.h" #include #include @@ -21,6 +22,7 @@ PrintRecords, GenEmitter, GenRegisterEnums, GenRegister, GenRegisterHeader, + GenInstrEnums, PrintEnums, Parse, }; @@ -38,6 +40,8 @@ "Generate a register info description"), clEnumValN(GenRegisterHeader, "gen-register-desc-header", "Generate a register info description header"), + clEnumValN(GenInstrEnums, "gen-instr-enums", + "Generate enum values for instructions"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(Parse, "parse", @@ -417,6 +421,7 @@ case GenEmitter: CodeEmitterGen(Records).run(*Out); break; + case GenRegisterEnums: RegisterInfoEmitter(Records).runEnums(*Out); break; @@ -426,6 +431,11 @@ case GenRegisterHeader: RegisterInfoEmitter(Records).runHeader(*Out); break; + + case GenInstrEnums: + InstrInfoEmitter(Records).runEnums(*Out); + break; + case PrintEnums: std::vector Recs = Records.getAllDerivedDefinitions(Class); for (unsigned i = 0, e = Recs.size(); i != e; ++i) From lattner at cs.uiuc.edu Mon Aug 4 00:00:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:04 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200308032215.RAA02398@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.6 -> 1.7 --- Log message: Allow registers to specify a custom name --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.6 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.7 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.6 Sun Aug 3 13:17:54 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Sun Aug 3 17:14:50 2003 @@ -188,7 +188,12 @@ // descriptors now. for (unsigned i = 0, e = Registers.size(); i != e; ++i) { Record *Reg = Registers[i]; - OS << " { \"" << Reg->getName() << "\",\t"; + OS << " { \""; + if (!Reg->getValueAsString("Name").empty()) + OS << Reg->getValueAsString("Name"); + else + OS << Reg->getName(); + OS << "\",\t"; if (RegisterAliases.count(Reg)) OS << Reg->getName() << "_AliasSet,\t"; else From lattner at cs.uiuc.edu Mon Aug 4 00:00:06 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:06 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308032212.RAA01719@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.10 -> 1.11 --- Log message: Allow specifying custom names for registers --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.10 llvm/lib/Target/Target.td:1.11 --- llvm/lib/Target/Target.td:1.10 Sun Aug 3 16:52:28 2003 +++ llvm/lib/Target/Target.td Sun Aug 3 17:12:37 2003 @@ -35,6 +35,14 @@ // class Register { string Namespace = ""; + string Name = ""; +} + +// NamedReg - If the name for the 'def' of the register should not become the +// "name" of the register, you can use this to specify a custom name instead. +// +class NamedReg : Register { + set Name = n; } // RegisterAliases - You should define instances of this class to indicate which From lattner at cs.uiuc.edu Mon Aug 4 00:00:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:07 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.td Message-ID: <200308032212.RAA01726@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.td updated: 1.2 -> 1.3 --- Log message: Specify custom name for registers to get the ()'s in the name. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.2 llvm/lib/Target/X86/X86RegisterInfo.td:1.3 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.2 Sun Aug 3 13:18:48 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.td Sun Aug 3 17:12:47 2003 @@ -35,10 +35,10 @@ def FP6 : Register; // Floating point stack registers - def ST0 : Register; def ST1 : Register; - def ST2 : Register; def ST3 : Register; - def ST4 : Register; def ST5 : Register; - def ST6 : Register; def ST7 : Register; + def ST0 : NamedReg<"ST(0)">; def ST1 : NamedReg<"ST(1)">; + def ST2 : NamedReg<"ST(2)">; def ST3 : NamedReg<"ST(3)">; + def ST4 : NamedReg<"ST(4)">; def ST5 : NamedReg<"ST(5)">; + def ST6 : NamedReg<"ST(6)">; def ST7 : NamedReg<"ST(7)">; // Flags, Segment registers, etc... From lattner at cs.uiuc.edu Mon Aug 4 00:00:09 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:09 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200308032156.QAA30170@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.14 -> 1.15 --- Log message: * Start using tablegen'd instruction descriptions * Fix bug in the createNOP method, which was not marking the operands of the generated XCHG as useanddef. I don't think this method is actually used, so it wasn't breaking anything, but it should be fixed anyway... --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.14 llvm/lib/Target/X86/X86InstrInfo.cpp:1.15 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.14 Fri May 23 20:08:43 2003 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Sun Aug 3 16:55:55 2003 @@ -8,31 +8,7 @@ #include "X86.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) -#define IMPREGSLIST(NAME, ...) \ - static const unsigned NAME[] = { __VA_ARGS__ }; -#include "X86InstrInfo.def" - - -// X86Insts - Turn the InstrInfo.def file into a bunch of instruction -// descriptors -// -static const TargetInstrDescriptor X86Insts[] = { -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPUSES, IMPDEFS) \ - { NAME, \ - -1, /* Always vararg */ \ - ((TSFLAGS) & X86II::Void) ? -1 : 0, /* Result is in 0 */ \ - 0, /* maxImmedConst field */\ - false, /* immedIsSignExtended */\ - 0, /* numDelaySlots */\ - 0, /* latency */\ - 0, /* schedClass */\ - FLAGS, /* Flags */\ - TSFLAGS, /* TSFlags */\ - IMPUSES, /* ImplicitUses */\ - IMPDEFS }, /* ImplicitDefs */ -#include "X86InstrInfo.def" -}; +#include "X86GenInstrInfo.inc" X86InstrInfo::X86InstrInfo() : TargetInstrInfo(X86Insts, sizeof(X86Insts)/sizeof(X86Insts[0]), 0) { @@ -44,7 +20,8 @@ // another instruction, e.g. X86: `xchg ax, ax'; SparcV9: `sethi r0, r0, r0' // MachineInstr* X86InstrInfo::createNOPinstr() const { - return BuildMI(X86::XCHGrr16, 2).addReg(X86::AX).addReg(X86::AX); + return BuildMI(X86::XCHGrr16, 2).addReg(X86::AX, MOTy::UseAndDef) + .addReg(X86::AX, MOTy::UseAndDef); } @@ -54,28 +31,14 @@ // bool X86InstrInfo::isNOPinstr(const MachineInstr &MI) const { // Make sure the instruction is EXACTLY `xchg ax, ax' - if (MI.getOpcode() == X86::XCHGrr16 && MI.getNumOperands() == 2) { + if (MI.getOpcode() == X86::XCHGrr16) { const MachineOperand &op0 = MI.getOperand(0), &op1 = MI.getOperand(1); if (op0.isMachineRegister() && op0.getMachineRegNum() == X86::AX && - op1.isMachineRegister() && op1.getMachineRegNum() == X86::AX) - { + op1.isMachineRegister() && op1.getMachineRegNum() == X86::AX) { return true; } } + // FIXME: there are several NOOP instructions, we should check for them here. return false; } - -static unsigned char BaseOpcodes[] = { -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) BASEOPCODE, -#include "X86InstrInfo.def" -}; - -// getBaseOpcodeFor - This function returns the "base" X86 opcode for the -// specified opcode number. -// -unsigned char X86InstrInfo::getBaseOpcodeFor(unsigned Opcode) const { - assert(Opcode < sizeof(BaseOpcodes)/sizeof(BaseOpcodes[0]) && - "Opcode out of range!"); - return BaseOpcodes[Opcode]; -} From lattner at cs.uiuc.edu Mon Aug 4 00:00:10 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:10 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/FloatingPoint.cpp Message-ID: <200308032156.QAA30207@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: FloatingPoint.cpp updated: 1.5 -> 1.6 --- Log message: Resort tables --- Diffs of the changes: Index: llvm/lib/Target/X86/FloatingPoint.cpp diff -u llvm/lib/Target/X86/FloatingPoint.cpp:1.5 llvm/lib/Target/X86/FloatingPoint.cpp:1.6 --- llvm/lib/Target/X86/FloatingPoint.cpp:1.5 Sun Aug 3 16:14:38 2003 +++ llvm/lib/Target/X86/FloatingPoint.cpp Sun Aug 3 16:56:36 2003 @@ -259,21 +259,25 @@ // element is an instruction, the second is the version which pops. // static const TableEntry PopTable[] = { + { X86::FADDrST0 , X86::FADDPrST0 }, + + { X86::FDIVRrST0, X86::FDIVRPrST0 }, + { X86::FDIVrST0 , X86::FDIVPrST0 }, + + { X86::FISTr16 , X86::FISTPr16 }, + { X86::FISTr32 , X86::FISTPr32 }, + + { X86::FMULrST0 , X86::FMULPrST0 }, + { X86::FSTr32 , X86::FSTPr32 }, { X86::FSTr64 , X86::FSTPr64 }, { X86::FSTrr , X86::FSTPrr }, - { X86::FISTr16 , X86::FISTPr16 }, - { X86::FISTr32 , X86::FISTPr32 }, - { X86::FADDrST0 , X86::FADDPrST0 }, - { X86::FSUBrST0 , X86::FSUBPrST0 }, { X86::FSUBRrST0, X86::FSUBRPrST0 }, - { X86::FMULrST0 , X86::FMULPrST0 }, - { X86::FDIVrST0 , X86::FDIVPrST0 }, - { X86::FDIVRrST0, X86::FDIVRPrST0 }, + { X86::FSUBrST0 , X86::FSUBPrST0 }, - { X86::FUCOMr , X86::FUCOMPr }, { X86::FUCOMPr , X86::FUCOMPPr }, + { X86::FUCOMr , X86::FUCOMPr }, }; /// popStackAfter - Pop the current value off of the top of the FP stack after @@ -363,36 +367,36 @@ // ForwardST0Table - Map: A = B op C into: ST(0) = ST(0) op ST(i) static const TableEntry ForwardST0Table[] = { { X86::FpADD, X86::FADDST0r }, - { X86::FpSUB, X86::FSUBST0r }, - { X86::FpMUL, X86::FMULST0r }, { X86::FpDIV, X86::FDIVST0r }, + { X86::FpMUL, X86::FMULST0r }, + { X86::FpSUB, X86::FSUBST0r }, { X86::FpUCOM, X86::FUCOMr }, }; // ReverseST0Table - Map: A = B op C into: ST(0) = ST(i) op ST(0) static const TableEntry ReverseST0Table[] = { { X86::FpADD, X86::FADDST0r }, // commutative - { X86::FpSUB, X86::FSUBRST0r }, - { X86::FpMUL, X86::FMULST0r }, // commutative { X86::FpDIV, X86::FDIVRST0r }, + { X86::FpMUL, X86::FMULST0r }, // commutative + { X86::FpSUB, X86::FSUBRST0r }, { X86::FpUCOM, ~0 }, }; // ForwardSTiTable - Map: A = B op C into: ST(i) = ST(0) op ST(i) static const TableEntry ForwardSTiTable[] = { { X86::FpADD, X86::FADDrST0 }, // commutative - { X86::FpSUB, X86::FSUBRrST0 }, - { X86::FpMUL, X86::FMULrST0 }, // commutative { X86::FpDIV, X86::FDIVRrST0 }, + { X86::FpMUL, X86::FMULrST0 }, // commutative + { X86::FpSUB, X86::FSUBRrST0 }, { X86::FpUCOM, X86::FUCOMr }, }; // ReverseSTiTable - Map: A = B op C into: ST(i) = ST(i) op ST(0) static const TableEntry ReverseSTiTable[] = { { X86::FpADD, X86::FADDrST0 }, - { X86::FpSUB, X86::FSUBrST0 }, - { X86::FpMUL, X86::FMULrST0 }, { X86::FpDIV, X86::FDIVrST0 }, + { X86::FpMUL, X86::FMULrST0 }, + { X86::FpSUB, X86::FSUBrST0 }, { X86::FpUCOM, ~0 }, }; From lattner at cs.uiuc.edu Mon Aug 4 00:00:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:11 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Makefile Message-ID: <200308032156.QAA30176@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Makefile updated: 1.2 -> 1.3 --- Log message: Start using tablegenerated instruction descriptions --- Diffs of the changes: Index: llvm/lib/Target/X86/Makefile diff -u llvm/lib/Target/X86/Makefile:1.2 llvm/lib/Target/X86/Makefile:1.3 --- llvm/lib/Target/X86/Makefile:1.2 Sun Aug 3 10:48:14 2003 +++ llvm/lib/Target/X86/Makefile Sun Aug 3 16:54:59 2003 @@ -2,19 +2,25 @@ LIBRARYNAME = x86 include $(LEVEL)/Makefile.common - - # Make sure that tblgen is run, first thing. -$(SourceDepend): X86GenRegisterInfo.h.inc X86GenRegisterNames.inc X86GenRegisterInfo.inc +$(SourceDepend): X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \ + X86GenRegisterInfo.inc X86GenInstrNames.inc \ + X86GenInstrInfo.inc -X86GenRegisterNames.inc: $(wildcard *.td) $(TBLGEN) +X86GenRegisterNames.inc: X86.td X86RegisterInfo.td $(TBLGEN) $(TBLGEN) X86.td -gen-register-enums -o $@ -X86GenRegisterInfo.h.inc: $(wildcard *.td) $(TBLGEN) +X86GenRegisterInfo.h.inc: X86.td X86RegisterInfo.td $(TBLGEN) $(TBLGEN) X86.td -gen-register-desc-header -o $@ -X86GenRegisterInfo.inc: $(wildcard *.td) $(TBLGEN) +X86GenRegisterInfo.inc: X86.td X86RegisterInfo.td $(TBLGEN) $(TBLGEN) X86.td -gen-register-desc -o $@ + +X86GenInstrNames.inc: X86.td X86InstrInfo.td $(TBLGEN) + $(TBLGEN) X86.td -gen-instr-enums -o $@ + +X86GenInstrInfo.inc: X86.td X86InstrInfo.td $(TBLGEN) + $(TBLGEN) X86.td -gen-instr-desc -o $@ clean:: $(VERB) rm -f *.inc From lattner at cs.uiuc.edu Mon Aug 4 00:00:14 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:14 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/GeneralList.td Message-ID: <200308031748.MAA28973@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: GeneralList.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/GeneralList.td diff -c /dev/null llvm/test/Regression/TableGen/GeneralList.td:1.1 *** /dev/null Sun Aug 3 12:48:02 2003 --- llvm/test/Regression/TableGen/GeneralList.td Sun Aug 3 12:47:52 2003 *************** *** 0 **** --- 1,8 ---- + // RUN: tblgen %s + // + // Test to make sure that lists work with any data-type + + class foo { + list Test = [1, 2, 3]; + list Test2 = ["abc", "xyz", "gtq"]; + } From lattner at cs.uiuc.edu Mon Aug 4 00:00:15 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:15 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrInfoEmitter.cpp InstrInfoEmitter.h Message-ID: <200308032158.QAA30255@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrInfoEmitter.cpp updated: 1.1 -> 1.2 InstrInfoEmitter.h updated: 1.1 -> 1.2 --- Log message: Finish the instruction info emitter --- Diffs of the changes: Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.1 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.2 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.1 Sun Aug 3 12:24:10 2003 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Sun Aug 3 16:57:51 2003 @@ -44,22 +44,136 @@ OS << "namespace " << Namespace << " {\n"; OS << " enum {\n"; - // We must emit the PHI and NOOP opcodes first... + // We must emit the PHI opcode first... Record *Target = getTarget(Records); Record *InstrInfo = Target->getValueAsDef("InstructionSet"); - Record *PHI = InstrInfo->getValueAsDef("PHIInst"); - Record *NOOP = InstrInfo->getValueAsDef("NOOPInst"); - OS << " " << PHI->getName() << ", \t// 0 (fixed for all targets)\n" - << " " << NOOP->getName() << ", \t// 1 (fixed for all targets)\n"; + OS << " " << PHI->getName() << ", \t// 0 (fixed for all targets)\n"; // Print out the rest of the instructions now... for (unsigned i = 0, e = Insts.size(); i != e; ++i) - if (Insts[i] != PHI && Insts[i] != NOOP) - OS << " " << Insts[i]->getName() << ", \t// " << i+2 << "\n"; + if (Insts[i] != PHI) + OS << " " << Insts[i]->getName() << ", \t// " << i+1 << "\n"; OS << " };\n"; if (!Namespace.empty()) OS << "}\n"; +} + +static void printDefList(ListInit *LI, const std::string &Name, + std::ostream &OS) { + OS << "static const unsigned " << Name << "[] = { "; + for (unsigned j = 0, e = LI->getSize(); j != e; ++j) + if (DefInit *DI = dynamic_cast(LI->getElement(j))) + OS << getQualifiedName(DI->getDef()) << ", "; + else + throw "Illegal value in '" + Name + "' list!"; + OS << "0 };\n"; +} + + +// run - Emit the main instruction description records for the target... +void InstrInfoEmitter::run(std::ostream &OS) { + EmitSourceHeader("Target Instruction Descriptors", OS); + Record *Target = getTarget(Records); + const std::string &TargetName = Target->getName(); + Record *InstrInfo = Target->getValueAsDef("InstructionSet"); + Record *PHI = InstrInfo->getValueAsDef("PHIInst"); + + std::vector Instructions = + Records.getAllDerivedDefinitions("Instruction"); + + // Emit all of the instruction's implicit uses and defs... + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { + Record *Inst = Instructions[i]; + ListInit *LI = Inst->getValueAsListInit("Uses"); + if (LI->getSize()) printDefList(LI, Inst->getName()+"ImpUses", OS); + LI = Inst->getValueAsListInit("Defs"); + if (LI->getSize()) printDefList(LI, Inst->getName()+"ImpDefs", OS); + } + + OS << "\nstatic const TargetInstrDescriptor " << TargetName + << "Insts[] = {\n"; + emitRecord(PHI, 0, InstrInfo, OS); + + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) + if (Instructions[i] != PHI) + emitRecord(Instructions[i], i+1, InstrInfo, OS); + OS << "};\n"; +} + +void InstrInfoEmitter::emitRecord(Record *R, unsigned Num, Record *InstrInfo, + std::ostream &OS) { + OS << " { \"" << R->getValueAsString("Name") + << "\",\t-1, -1, 0, false, 0, 0, 0, 0"; + + // Emit all of the target indepedent flags... + if (R->getValueAsBit("isReturn")) OS << "|M_RET_FLAG"; + if (R->getValueAsBit("isBranch")) OS << "|M_BRANCH_FLAG"; + if (R->getValueAsBit("isCall" )) OS << "|M_CALL_FLAG"; + if (R->getValueAsBit("isTwoAddress")) OS << "|M_2_ADDR_FLAG"; + if (R->getValueAsBit("isTerminator")) OS << "|M_TERMINATOR_FLAG"; + OS << ", 0"; + + // Emit all of the target-specific flags... + ListInit *LI = InstrInfo->getValueAsListInit("TSFlagsFields"); + ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); + if (LI->getSize() != Shift->getSize()) + throw "Lengths of " + InstrInfo->getName() + + ":(TargetInfoFields, TargetInfoPositions) must be equal!"; + + for (unsigned i = 0, e = LI->getSize(); i != e; ++i) + emitShiftedValue(R, dynamic_cast(LI->getElement(i)), + dynamic_cast(Shift->getElement(i)), OS); + + OS << ", "; + + // Emit the implicit uses and defs lists... + LI = R->getValueAsListInit("Uses"); + if (!LI->getSize()) + OS << "0, "; + else + OS << R->getName() << "ImpUses, "; + + LI = R->getValueAsListInit("Defs"); + if (!LI->getSize()) + OS << "0 "; + else + OS << R->getName() << "ImpDefs "; + + OS << " }, // Inst #" << Num << " = " << R->getName() << "\n"; +} + +void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, + IntInit *ShiftInt, std::ostream &OS) { + if (Val == 0 || ShiftInt == 0) + throw std::string("Illegal value or shift amount in TargetInfo*!"); + RecordVal *RV = R->getValue(Val->getValue()); + int Shift = ShiftInt->getValue(); + + if (RV == 0 || RV->getValue() == 0) + throw R->getName() + " doesn't have a field named '" + Val->getValue()+"'!"; + + Init *Value = RV->getValue(); + if (BitInit *BI = dynamic_cast(Value)) { + if (BI->getValue()) OS << "|(1<<" << Shift << ")"; + return; + } else if (BitsInit *BI = dynamic_cast(Value)) { + // Convert the Bits to an integer to print... + Init *I = BI->convertInitializerTo(new IntRecTy()); + if (I) + if (IntInit *II = dynamic_cast(I)) { + if (II->getValue()) + OS << "|(" << II->getValue() << "<<" << Shift << ")"; + return; + } + + } else if (IntInit *II = dynamic_cast(Value)) { + if (II->getValue()) OS << "|(" << II->getValue() << "<<" << Shift << ")"; + return; + } + + std::cerr << "Unhandled initializer: " << *Val << "\n"; + throw "In record '" + R->getName() + "' for TSFlag emission."; } Index: llvm/utils/TableGen/InstrInfoEmitter.h diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.1 llvm/utils/TableGen/InstrInfoEmitter.h:1.2 --- llvm/utils/TableGen/InstrInfoEmitter.h:1.1 Sun Aug 3 12:24:10 2003 +++ llvm/utils/TableGen/InstrInfoEmitter.h Sun Aug 3 16:57:51 2003 @@ -10,6 +10,9 @@ #include class RecordKeeper; +class Record; +class StringInit; +class IntInit; class InstrInfoEmitter { RecordKeeper &Records; @@ -17,10 +20,14 @@ InstrInfoEmitter(RecordKeeper &R) : Records(R) {} // run - Output the instruction set description, returning true on failure. - void run(std::ostream &o); + void run(std::ostream &OS); // runEnums - Print out enum values for all of the instructions. - void runEnums(std::ostream &o); + void runEnums(std::ostream &OS); +private: + void emitRecord(Record *R, unsigned Num, Record *InstrInfo, std::ostream &OS); + void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift, + std::ostream &OS); }; #endif From lattner at cs.uiuc.edu Mon Aug 4 00:00:17 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:17 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.h Message-ID: <200308032157.QAA30226@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.h updated: 1.16 -> 1.17 --- Log message: Start using tablegen'd instruction enum list --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.16 llvm/lib/Target/X86/X86.h:1.17 --- llvm/lib/Target/X86/X86.h:1.16 Sun Aug 3 10:48:55 2003 +++ llvm/lib/Target/X86/X86.h Sun Aug 3 16:57:05 2003 @@ -47,15 +47,8 @@ // #include "X86GenRegisterNames.inc" -/// X86 namespace - This namespace contains all of the register and opcode enums -/// used by the X86 backend. -/// -namespace X86 { - // This defines a large number of symbolic names for X86 instruction opcodes. - enum Opcode { -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) ENUM, -#include "X86InstrInfo.def" - }; -} +// Defines symbolic names for the X86 instructions. +// +#include "X86GenInstrNames.inc" #endif From lattner at cs.uiuc.edu Mon Aug 4 00:00:18 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:18 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h Message-ID: <200308032157.QAA30233@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.24 -> 1.25 --- Log message: Lump the base opcode in with the X86 TargetSpecific flags --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.24 llvm/lib/Target/X86/X86InstrInfo.h:1.25 --- llvm/lib/Target/X86/X86InstrInfo.h:1.24 Thu Jun 26 19:00:46 2003 +++ llvm/lib/Target/X86/X86InstrInfo.h Sun Aug 3 16:56:22 2003 @@ -134,9 +134,11 @@ FPTypeMask = 7 << 14, // PrintImplUses - Print out implicit uses in the assembly output. - PrintImplUses = 1 << 17 + PrintImplUses = 1 << 17, - // Bits 18 -> 31 are unused + OpcodeMask = 0xFF << 18, + OpcodeShift = 18, + // Bits 26 -> 31 are unused }; } @@ -166,8 +168,9 @@ // getBaseOpcodeFor - This function returns the "base" X86 opcode for the // specified opcode number. // - unsigned char getBaseOpcodeFor(unsigned Opcode) const; + unsigned char getBaseOpcodeFor(unsigned Opcode) const { + return get(Opcode).TSFlags >> X86II::OpcodeShift; + } }; - #endif From lattner at cs.uiuc.edu Mon Aug 4 00:00:21 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:21 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstr.cpp Message-ID: <200308032151.QAA29971@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.74 -> 1.75 --- Log message: Simplify code, eliminating the need for the X86 isVoid target instr flag --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.74 llvm/lib/CodeGen/MachineInstr.cpp:1.75 --- llvm/lib/CodeGen/MachineInstr.cpp:1.74 Sun Aug 3 15:24:29 2003 +++ llvm/lib/CodeGen/MachineInstr.cpp Sun Aug 3 16:51:45 2003 @@ -126,10 +126,11 @@ operands[i].value = NULL; operands[i].regNum = regNum; - if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) + if (isdef || TargetInstrDescriptors[opCode].resultPos == (int)i) { + assert(operands[i].flags == MachineOperand::DEFONLYFLAG && + "Shouldn't be changing a register type once set!"); operands[i].flags = MachineOperand::DEFONLYFLAG; - else - operands[i].flags = 0; + } insertUsedReg(regNum); } From lattner at cs.uiuc.edu Mon Aug 4 00:00:22 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:22 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp RegAllocSimple.cpp Message-ID: <200308032147.QAA29941@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.18 -> 1.19 RegAllocSimple.cpp updated: 1.40 -> 1.41 --- Log message: Set debug types --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.18 llvm/lib/CodeGen/RegAllocLocal.cpp:1.19 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.18 Sun Aug 3 08:49:03 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Sun Aug 3 16:47:31 2003 @@ -5,6 +5,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "regalloc" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.40 llvm/lib/CodeGen/RegAllocSimple.cpp:1.41 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.40 Fri Aug 1 17:21:34 2003 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Sun Aug 3 16:47:31 2003 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "regalloc" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" From lattner at cs.uiuc.edu Mon Aug 4 00:00:26 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:26 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86.td Message-ID: <200308032154.QAA30140@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td added (r1.1) X86.td updated: 1.2 -> 1.3 --- Log message: Add new TableGen instruction definitions --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.td diff -c /dev/null llvm/lib/Target/X86/X86InstrInfo.td:1.1 *** /dev/null Sun Aug 3 16:54:31 2003 --- llvm/lib/Target/X86/X86InstrInfo.td Sun Aug 3 16:54:21 2003 *************** *** 0 **** --- 1,442 ---- + //===- X86InstrInfo.td - Describe the X86 Instruction Set -------*- C++ -*-===// + // + // This file describes the X86 instruction set, defining the instructions, and + // properties of the instructions which are needed for code generation, machine + // code emission, and analysis. + // + //===----------------------------------------------------------------------===// + + + + // Format specifies the encoding used by the instruction. This is part of the + // ad-hoc solution used to emit machine instruction encodings by our machine + // code emitter. + class Format val> { + bits<5> Value = val; + } + + def Pseudo : Format<0>; def RawFrm : Format<1>; + def AddRegFrm : Format<2>; def MRMDestReg : Format<3>; + def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>; + def MRMSrcMem : Format<6>; + def MRMS0r : Format<16>; def MRMS1r : Format<17>; def MRMS2r : Format<18>; + def MRMS3r : Format<19>; def MRMS4r : Format<20>; def MRMS5r : Format<21>; + def MRMS6r : Format<22>; def MRMS7r : Format<23>; + def MRMS0m : Format<24>; def MRMS1m : Format<25>; def MRMS2m : Format<26>; + def MRMS3m : Format<27>; def MRMS4m : Format<28>; def MRMS5m : Format<29>; + def MRMS6m : Format<30>; def MRMS7m : Format<31>; + + // ArgType - This specifies the argument type used by an instruction. This is + // part of the ad-hoc solution used to emit machine instruction encodings by our + // machine code emitter. + class ArgType val> { + bits<3> Value = val; + } + def NoArg : ArgType<0>; + def Arg8 : ArgType<1>; + def Arg16 : ArgType<2>; + def Arg32 : ArgType<3>; + def Arg64 : ArgType<4>; // 64 bit int argument for FILD64 + def ArgF32 : ArgType<5>; + def ArgF64 : ArgType<6>; + def ArgF80 : ArgType<6>; + + // FPFormat - This specifies what form this FP instruction has. This is used by + // the Floating-Point stackifier pass. + class FPFormat val> { + bits<3> Value = val; + } + def NotFP : FPFormat<0>; + def ZeroArgFP : FPFormat<1>; + def OneArgFP : FPFormat<2>; + def OneArgFPRW : FPFormat<3>; + def TwoArgFP : FPFormat<4>; + def SpecialFP : FPFormat<5>; + + + class X86Inst opcod, Format f, ArgType a> : Instruction { + set Namespace = "X86"; + + set Name = nam; + bits<8> Opcode = opcod; + Format Form = f; + bits<5> FormBits = Form.Value; + ArgType Type = a; + bits<3> TypeBits = Type.Value; + + // Attributes specific to X86 instructions... + bit isVoid = 0; // Does this inst ignore the return value? + bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix? + bit printImplicitUses = 0; // Should we print implicit uses of this inst? + + bits<4> Prefix = 0; // Which prefix byte does this inst have? + FPFormat FPForm; // What flavor of FP instruction is this? + bits<3> FPFormBits = 0; + } + + class Imp uses, list defs> { + list Uses = uses; + list Defs = defs; + } + + + // Prefix byte classes which are used to indicate to the ad-hoc machine code + // emitter that various prefix bytes are required. + class OpSize { bit hasOpSizePrefix = 1; } + class TB { bits<4> Prefix = 1; } + class D8 { bits<4> Prefix = 2; } + class D9 { bits<4> Prefix = 3; } + class DA { bits<4> Prefix = 4; } + class DB { bits<4> Prefix = 5; } + class DC { bits<4> Prefix = 6; } + class DD { bits<4> Prefix = 7; } + class DE { bits<4> Prefix = 8; } + class DF { bits<4> Prefix = 9; } + + + + //===----------------------------------------------------------------------===// + // Instruction list... + // + + def PHI : X86Inst<"PHI", 0, Pseudo, NoArg>; // PHI node... + + set isVoid = 1 in + def NOOP : X86Inst<"nop", 0x90, RawFrm, NoArg>; // nop + + def ADJCALLSTACKDOWN : X86Inst<"ADJCALLSTACKDOWN", 0, Pseudo, NoArg>; + def ADJCALLSTACKUP : X86Inst<"ADJCALLSTACKUP", 0, Pseudo, NoArg>; + def IMPLICIT_USE : X86Inst<"IMPLICIT_USE", 0, Pseudo, NoArg>; + + //===----------------------------------------------------------------------===// + // Control Flow Instructions... + // + + // Return instruction... + set isTerminator = 1, isVoid = 1, isReturn = 1 in + def RET : X86Inst<"ret", 0xC3, RawFrm, NoArg>; + + // All branches are RawFrm, Void, Branch, and Terminators + set isVoid = 1, isBranch = 1, isTerminator = 1 in + class IBr opcode> : X86Inst; + + def JMP : IBr<"jmp", 0xE9>; + def JB : IBr<"jb" , 0x82>, TB; + def JAE : IBr<"jae", 0x83>, TB; + def JE : IBr<"je" , 0x84>, TB; + def JNE : IBr<"jne", 0x85>, TB; + def JBE : IBr<"jbe", 0x86>, TB; + def JA : IBr<"ja" , 0x87>, TB; + def JL : IBr<"jl" , 0x8C>, TB; + def JGE : IBr<"jge", 0x8D>, TB; + def JLE : IBr<"jle", 0x8E>, TB; + def JG : IBr<"jg" , 0x8F>, TB; + + + //===----------------------------------------------------------------------===// + // Call Instructions... + // + set isCall = 1, isVoid = 1 in + // All calls clobber the non-callee saved registers... + set Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6] in { + def CALLpcrel32 : X86Inst<"call", 0xE8, RawFrm, NoArg>; + def CALLr32 : X86Inst<"call", 0xFF, MRMS2r, Arg32>; + def CALLm32 : X86Inst<"call", 0xFF, MRMS2m, Arg32>; + } + + + //===----------------------------------------------------------------------===// + // Miscellaneous Instructions... + // + def LEAVE : X86Inst<"leave", 0xC9, RawFrm, NoArg>, Imp<[EBP], [EBP]>; + + set isTwoAddress = 1 in // R32 = bswap R32 + def BSWAPr32 : X86Inst<"bswap", 0xC8, AddRegFrm, Arg32>, TB; + + def XCHGrr8 : X86Inst<"xchg", 0x86, MRMDestReg, Arg8>; // xchg R8, R8 + def XCHGrr16 : X86Inst<"xchg", 0x87, MRMDestReg, Arg16>, OpSize;// xchg R16, R16 + def XCHGrr32 : X86Inst<"xchg", 0x87, MRMDestReg, Arg32>; // xchg R32, R32 + + def LEAr16 : X86Inst<"lea", 0x8D, MRMSrcMem, Arg16>, OpSize; // R16 = lea [mem] + def LEAr32 : X86Inst<"lea", 0x8D, MRMSrcMem, Arg32>; // R32 = lea [mem] + + //===----------------------------------------------------------------------===// + // Move Instructions... + // + def MOVrr8 : X86Inst<"mov", 0x88, MRMDestReg, Arg8>; // R8 = R8 + def MOVrr16 : X86Inst<"mov", 0x89, MRMDestReg, Arg16>, OpSize; // R16 = R16 + def MOVrr32 : X86Inst<"mov", 0x89, MRMDestReg, Arg32>; // R32 = R32 + def MOVir8 : X86Inst<"mov", 0xB0, AddRegFrm , Arg8>; // R8 = imm8 + def MOVir16 : X86Inst<"mov", 0xB8, AddRegFrm , Arg16>, OpSize; // R16 = imm16 + def MOVir32 : X86Inst<"mov", 0xB8, AddRegFrm , Arg32>; // R32 = imm32 + def MOVim8 : X86Inst<"mov", 0xC6, MRMS0m , Arg8>; // [mem] = imm8 + def MOVim16 : X86Inst<"mov", 0xC7, MRMS0m , Arg16>, OpSize; // [mem] = imm16 + def MOVim32 : X86Inst<"mov", 0xC7, MRMS0m , Arg32>; // [mem] = imm32 + + def MOVmr8 : X86Inst<"mov", 0x8A, MRMSrcMem , Arg8>; // R8 = [mem] + def MOVmr16 : X86Inst<"mov", 0x8B, MRMSrcMem , Arg16>, OpSize; // R16 = [mem] + def MOVmr32 : X86Inst<"mov", 0x8B, MRMSrcMem , Arg32>; // R32 = [mem] + + set isVoid = 1 in { + def MOVrm8 : X86Inst<"mov", 0x88, MRMDestMem, Arg8>; // R8 = [mem] + def MOVrm16 : X86Inst<"mov", 0x89, MRMDestMem, Arg16>, OpSize; // R16 = [mem] + def MOVrm32 : X86Inst<"mov", 0x89, MRMDestMem, Arg32>; // R32 = [mem] + } + + //===----------------------------------------------------------------------===// + // Fixed-Register Multiplication and Division Instructions... + // + set isVoid = 1 in { + // Extra precision multiplication + def MULr8 : X86Inst<"mul", 0xF6, MRMS4r, Arg8 >, Imp<[AL],[AX]>; // AL,AH = AL*R8 + def MULr16 : X86Inst<"mul", 0xF7, MRMS4r, Arg16>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16 + def MULr32 : X86Inst<"mul", 0xF7, MRMS4r, Arg32>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32 + + // unsigned division/remainder + def DIVr8 : X86Inst<"div", 0xF6, MRMS6r, Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH + def DIVr16 : X86Inst<"div", 0xF7, MRMS6r, Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX + def DIVr32 : X86Inst<"div", 0xF7, MRMS6r, Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX + + // signed division/remainder + def IDIVr8 : X86Inst<"idiv",0xF6, MRMS7r, Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH + def IDIVr16: X86Inst<"idiv",0xF7, MRMS7r, Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX + def IDIVr32: X86Inst<"idiv",0xF7, MRMS7r, Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX + + // Sign-extenders for division + def CBW : X86Inst<"cbw", 0x98, RawFrm, Arg8 >, Imp<[AL],[AH]>; // AX = signext(AL) + def CWD : X86Inst<"cwd", 0x99, RawFrm, Arg8 >, Imp<[AX],[DX]>; // DX:AX = signext(AX) + def CDQ : X86Inst<"cdq", 0x99, RawFrm, Arg8 >, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX) + } + + + //===----------------------------------------------------------------------===// + // Two address Instructions... + // + set isTwoAddress = 1 in { // Define some helper classes to make defs shorter. + class I2A8 o, Format F> : X86Inst; + class I2A16 o, Format F> : X86Inst; + class I2A32 o, Format F> : X86Inst; + } + + // Arithmetic... + def ADDrr8 : I2A8 <"add", 0x00, MRMDestReg>; // R8 += R8 (set r8 (plus r8 r8)) + def ADDrr16 : I2A16<"add", 0x01, MRMDestReg>, OpSize; // R16 += R16 (set r16 (plus r16 r16)) + def ADDrr32 : I2A32<"add", 0x01, MRMDestReg>; // R32 += R32 (set r32 (plus r32 r32)) + def ADDri8 : I2A8 <"add", 0x80, MRMS0r >; // R8 += imm8 (set r8 (plus r8 imm8)) + def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize; // R16 += imm16 (set r16 (plus r16 imm16)) + def ADDri32 : I2A32<"add", 0x81, MRMS0r >; // R32 += imm32 (set r32 (plus r32 imm32)) + + def ADCrr32 : I2A32<"adc", 0x11, MRMDestReg>; // R32 += imm32+Carry + + def SUBrr8 : I2A8 <"sub", 0x28, MRMDestReg>; // R8 -= R8 + def SUBrr16 : I2A16<"sub", 0x29, MRMDestReg>, OpSize; // R16 -= R16 + def SUBrr32 : I2A32<"sub", 0x29, MRMDestReg>; // R32 -= R32 + def SUBri8 : I2A8 <"sub", 0x80, MRMS5r >; // R8 -= imm8 + def SUBri16 : I2A16<"sub", 0x81, MRMS5r >, OpSize; // R16 -= imm16 + def SUBri32 : I2A32<"sub", 0x81, MRMS5r >; // R32 -= imm32 + + def SBBrr32 : I2A32<"sbb", 0x19, MRMDestReg>; // R32 -= R32+Carry + + def IMULr16 : I2A16<"imul", 0xAF, MRMSrcReg>, TB, OpSize; // R16 *= R16 + def IMULr32 : I2A32<"imul", 0xAF, MRMSrcReg>, TB; // R32 *= R32 + + // Logical operators... + def ANDrr8 : I2A8 <"and", 0x20, MRMDestReg>; // R8 &= R8 + def ANDrr16 : I2A16<"and", 0x21, MRMDestReg>, OpSize; // R16 &= R16 + def ANDrr32 : I2A32<"and", 0x21, MRMDestReg>; // R32 &= R32 + def ANDri8 : I2A8 <"and", 0x80, MRMS4r >; // R8 &= imm8 + def ANDri16 : I2A16<"and", 0x81, MRMS4r >, OpSize; // R16 &= imm16 + def ANDri32 : I2A32<"and", 0x81, MRMS4r >; // R32 &= imm32 + + def ORrr8 : I2A8 <"or" , 0x08, MRMDestReg>; // R8 |= R8 + def ORrr16 : I2A16<"or" , 0x09, MRMDestReg>, OpSize; // R16 |= R16 + def ORrr32 : I2A32<"or" , 0x09, MRMDestReg>; // R32 |= R32 + def ORri8 : I2A8 <"or" , 0x80, MRMS1r >; // R8 |= imm8 + def ORri16 : I2A16<"or" , 0x81, MRMS1r >, OpSize; // R16 |= imm16 + def ORri32 : I2A32<"or" , 0x81, MRMS1r >; // R32 |= imm32 + + def XORrr8 : I2A8 <"xor", 0x30, MRMDestReg>; // R8 ^= R8 + def XORrr16 : I2A16<"xor", 0x31, MRMDestReg>, OpSize; // R16 ^= R16 + def XORrr32 : I2A32<"xor", 0x31, MRMDestReg>; // R32 ^= R32 + def XORri8 : I2A8 <"xor", 0x80, MRMS6r >; // R8 ^= imm8 + def XORri16 : I2A16<"xor", 0x81, MRMS6r >, OpSize; // R16 ^= imm16 + def XORri32 : I2A32<"xor", 0x81, MRMS6r >; // R32 ^= imm32 + + // Test instructions are just like AND, except they don't generate a result. + def TESTrr8 : X86Inst<"test", 0x84, MRMDestReg, Arg8 >; // flags = R8 & R8 + def TESTrr16 : X86Inst<"test", 0x85, MRMDestReg, Arg16>, OpSize; // flags = R16 & R16 + def TESTrr32 : X86Inst<"test", 0x85, MRMDestReg, Arg32>; // flags = R32 & R32 + def TESTri8 : X86Inst<"test", 0xF6, MRMS0r , Arg8 >; // flags = R8 & imm8 + def TESTri16 : X86Inst<"test", 0xF7, MRMS0r , Arg16>, OpSize; // flags = R16 & imm16 + def TESTri32 : X86Inst<"test", 0xF7, MRMS0r , Arg32>; // flags = R32 & imm32 + + // Shift instructions + class UsesCL { list Uses = [CL]; bit printImplicitUses = 1; } + + def SHLrr8 : I2A8 <"shl", 0xD2, MRMS4r > , UsesCL; // R8 <<= cl + def SHLrr16 : I2A8 <"shl", 0xD3, MRMS4r >, OpSize, UsesCL; // R16 <<= cl + def SHLrr32 : I2A8 <"shl", 0xD3, MRMS4r > , UsesCL; // R32 <<= cl + def SHLir8 : I2A8 <"shl", 0xC0, MRMS4r >; // R8 <<= imm8 + def SHLir16 : I2A8 <"shl", 0xC1, MRMS4r >, OpSize; // R16 <<= imm16 + def SHLir32 : I2A8 <"shl", 0xC1, MRMS4r >; // R32 <<= imm32 + def SHRrr8 : I2A8 <"shr", 0xD2, MRMS5r > , UsesCL; // R8 >>= cl + def SHRrr16 : I2A8 <"shr", 0xD3, MRMS5r >, OpSize, UsesCL; // R16 >>= cl + def SHRrr32 : I2A8 <"shr", 0xD3, MRMS5r > , UsesCL; // R32 >>= cl + def SHRir8 : I2A8 <"shr", 0xC0, MRMS5r >; // R8 >>= imm8 + def SHRir16 : I2A8 <"shr", 0xC1, MRMS5r >, OpSize; // R16 >>= imm16 + def SHRir32 : I2A8 <"shr", 0xC1, MRMS5r >; // R32 >>= imm32 + def SARrr8 : I2A8 <"sar", 0xD2, MRMS7r > , UsesCL; // R8 >>>= cl + def SARrr16 : I2A8 <"sar", 0xD3, MRMS7r >, OpSize, UsesCL; // R16 >>>= cl + def SARrr32 : I2A8 <"sar", 0xD3, MRMS7r > , UsesCL; // R32 >>>= cl + def SARir8 : I2A8 <"sar", 0xC0, MRMS7r >; // R8 >>>= imm8 + def SARir16 : I2A8 <"sar", 0xC1, MRMS7r >, OpSize; // R16 >>>= imm16 + def SARir32 : I2A8 <"sar", 0xC1, MRMS7r >; // R32 >>>= imm32 + + def SHLDrr32 : I2A8 <"shld", 0xA5, MRMDestReg>, TB, UsesCL; // R32 <<= R32,R32 cl + def SHLDir32 : I2A8 <"shld", 0xA4, MRMDestReg>, TB; // R32 <<= R32,R32 imm8 + def SHRDrr32 : I2A8 <"shrd", 0xAD, MRMDestReg>, TB, UsesCL; // R32 >>= R32,R32 cl + def SHRDir32 : I2A8 <"shrd", 0xAC, MRMDestReg>, TB; // R32 >>= R32,R32 imm8 + + // Condition code ops, incl. set if equal/not equal/... + def SAHF : X86Inst<"sahf" , 0x9E, RawFrm, Arg8>, Imp<[AH],[]>; // flags = AH + def SETBr : X86Inst<"setb" , 0x92, MRMS0r, Arg8>, TB; // R8 = < unsign + def SETAEr : X86Inst<"setae", 0x93, MRMS0r, Arg8>, TB; // R8 = >= unsign + def SETEr : X86Inst<"sete" , 0x94, MRMS0r, Arg8>, TB; // R8 = == + def SETNEr : X86Inst<"setne", 0x95, MRMS0r, Arg8>, TB; // R8 = != + def SETBEr : X86Inst<"setbe", 0x96, MRMS0r, Arg8>, TB; // R8 = <= unsign + def SETAr : X86Inst<"seta" , 0x97, MRMS0r, Arg8>, TB; // R8 = > signed + def SETLr : X86Inst<"setl" , 0x9C, MRMS0r, Arg8>, TB; // R8 = < signed + def SETGEr : X86Inst<"setge", 0x9D, MRMS0r, Arg8>, TB; // R8 = >= signed + def SETLEr : X86Inst<"setle", 0x9E, MRMS0r, Arg8>, TB; // R8 = <= signed + def SETGr : X86Inst<"setg" , 0x9F, MRMS0r, Arg8>, TB; // R8 = < signed + + // Conditional moves. These are modelled as X = cmovXX Y, Z. Eventually + // register allocated to cmovXX XY, Z + def CMOVErr16 : I2A16<"cmove", 0x44, MRMSrcReg>, TB, OpSize; // if ==, R16 = R16 + def CMOVNErr32: I2A32<"cmovne",0x45, MRMSrcReg>, TB; // if !=, R32 = R32 + + // Integer comparisons + set isVoid = 1 in { + def CMPrr8 : X86Inst<"cmp", 0x38, MRMDestReg, Arg8 >; // compare R8, R8 + def CMPrr16 : X86Inst<"cmp", 0x39, MRMDestReg, Arg16>, OpSize; // compare R16, R16 + def CMPrr32 : X86Inst<"cmp", 0x39, MRMDestReg, Arg32>; // compare R32, R32 + def CMPri8 : X86Inst<"cmp", 0x80, MRMS7r , Arg8 >; // compare R8, imm8 + def CMPri16 : X86Inst<"cmp", 0x81, MRMS7r , Arg16>, OpSize; // compare R16, imm16 + def CMPri32 : X86Inst<"cmp", 0x81, MRMS7r , Arg32>; // compare R32, imm32 + } + + // Sign/Zero extenders + def MOVSXr16r8 : X86Inst<"movsx", 0xBE, MRMSrcReg, Arg8>, TB, OpSize; // R16 = signext(R8) + def MOVSXr32r8 : X86Inst<"movsx", 0xBE, MRMSrcReg, Arg8>, TB; // R32 = signext(R8) + def MOVSXr32r16: X86Inst<"movsx", 0xBF, MRMSrcReg, Arg8>, TB; // R32 = signext(R16) + def MOVZXr16r8 : X86Inst<"movzx", 0xB6, MRMSrcReg, Arg8>, TB, OpSize; // R16 = zeroext(R8) + def MOVZXr32r8 : X86Inst<"movzx", 0xB6, MRMSrcReg, Arg8>, TB; // R32 = zeroext(R8) + def MOVZXr32r16: X86Inst<"movzx", 0xB7, MRMSrcReg, Arg8>, TB; // R32 = zeroext(R16) + + + //===----------------------------------------------------------------------===// + // Floating point support + //===----------------------------------------------------------------------===// + + // FIXME: These need to indicate mod/ref sets for FP regs... & FP 'TOP' + + // Floating point pseudo instructions... + class FPInst o, Format F, ArgType t, FPFormat fp> + : X86Inst { set FPForm = fp; set FPFormBits = FPForm.Value; } + + def FpMOV : FPInst<"FMOV", 0, Pseudo, ArgF80, SpecialFP>; // f1 = fmov f2 + def FpADD : FPInst<"FADD", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fadd f2, f3 + def FpSUB : FPInst<"FSUB", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fsub f2, f3 + def FpMUL : FPInst<"FMUL", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fmul f2, f3 + def FpDIV : FPInst<"FDIV", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fdiv f2, f3 + + set isVoid = 1 in + def FpUCOM : FPInst<"FUCOM", 0, Pseudo, ArgF80, TwoArgFP>; // FPSW = fucom f1, f2 + + def FpGETRESULT : FPInst<"FGETRESULT",0, Pseudo, ArgF80, SpecialFP>; // FPR = ST(0) + + set isVoid = 1 in + def FpSETRESULT : FPInst<"FSETRESULT",0, Pseudo, ArgF80, SpecialFP>; // ST(0) = FPR + + // Floating point loads & stores... + def FLDrr : FPInst<"fld" , 0xC0, AddRegFrm, ArgF80, NotFP>, D9; // push(ST(i)) + def FLDr32 : FPInst<"fld" , 0xD9, MRMS0m , ArgF32, ZeroArgFP>; // load float + def FLDr64 : FPInst<"fld" , 0xDD, MRMS0m , ArgF64, ZeroArgFP>; // load double + def FLDr80 : FPInst<"fld" , 0xDB, MRMS5m , ArgF80, ZeroArgFP>; // load extended + def FILDr16 : FPInst<"fild" , 0xDF, MRMS0m , Arg16 , ZeroArgFP>; // load signed short + def FILDr32 : FPInst<"fild" , 0xDB, MRMS0m , Arg32 , ZeroArgFP>; // load signed int + def FILDr64 : FPInst<"fild" , 0xDF, MRMS5m , Arg64 , ZeroArgFP>; // load signed long + + set isVoid = 1 in { + def FSTr32 : FPInst<"fst" , 0xD9, MRMS2m , ArgF32, OneArgFP>; // store float + def FSTr64 : FPInst<"fst" , 0xDD, MRMS2m , ArgF64, OneArgFP>; // store double + def FSTPr32 : FPInst<"fstp", 0xD9, MRMS3m , ArgF32, OneArgFP>; // store float, pop + def FSTPr64 : FPInst<"fstp", 0xDD, MRMS3m , ArgF64, OneArgFP>; // store double, pop + def FSTPr80 : FPInst<"fstp", 0xDB, MRMS7m , ArgF80, OneArgFP>; // store extended, pop + def FSTrr : FPInst<"fst" , 0xD0, AddRegFrm, ArgF80, NotFP >, DD; // ST(i) = ST(0) + def FSTPrr : FPInst<"fstp", 0xD8, AddRegFrm, ArgF80, NotFP >, DD; // ST(i) = ST(0), pop + + def FISTr16 : FPInst<"fist", 0xDF, MRMS2m, Arg16 , OneArgFP>; // store signed short + def FISTr32 : FPInst<"fist", 0xDB, MRMS2m, Arg32 , OneArgFP>; // store signed int + def FISTPr16 : FPInst<"fistp", 0xDF, MRMS3m, Arg16 , NotFP >; // store signed short, pop + def FISTPr32 : FPInst<"fistp", 0xDB, MRMS3m, Arg32 , NotFP >; // store signed int, pop + def FISTPr64 : FPInst<"fistpll", 0xDF, MRMS7m, Arg64 , OneArgFP>; // store signed long, pop + + def FXCH : FPInst<"fxch", 0xC8, AddRegFrm, ArgF80, NotFP>, D9; // fxch ST(i), ST(0) + } + + // Floating point constant loads... + def FLD0 : FPInst<"fldz", 0xEE, RawFrm, ArgF80, ZeroArgFP>, D9; + def FLD1 : FPInst<"fld1", 0xE8, RawFrm, ArgF80, ZeroArgFP>, D9; + + // Binary arithmetic operations... + class FPST0rInst o> + : X86Inst, D8 { + list Uses = [ST0]; + list Defs = [ST0]; + } + class FPrST0Inst o> + : X86Inst, DC { + bit printImplicitUses = 1; + list Uses = [ST0]; + } + class FPrST0PInst o> + : X86Inst, DE { + list Uses = [ST0]; + } + + def FADDST0r : FPST0rInst <"fadd", 0xC0>; + def FADDrST0 : FPrST0Inst <"fadd", 0xC0>; + def FADDPrST0 : FPrST0PInst<"faddp", 0xC0>; + + def FSUBRST0r : FPST0rInst <"fsubr", 0xE8>; + def FSUBrST0 : FPrST0Inst <"fsub", 0xE8>; + def FSUBPrST0 : FPrST0PInst<"fsubp", 0xE8>; + + def FSUBST0r : FPST0rInst <"fsub", 0xE0>; + def FSUBRrST0 : FPrST0Inst <"fsubr", 0xE0>; + def FSUBRPrST0 : FPrST0PInst<"fsubrp", 0xE0>; + + def FMULST0r : FPST0rInst <"fmul", 0xC8>; + def FMULrST0 : FPrST0Inst <"fmul", 0xC8>; + def FMULPrST0 : FPrST0PInst<"fmulp", 0xC8>; + + def FDIVRST0r : FPST0rInst <"fdivr", 0xF8>; + def FDIVrST0 : FPrST0Inst <"fdiv", 0xF8>; + def FDIVPrST0 : FPrST0PInst<"fdivp", 0xF8>; + + def FDIVST0r : FPST0rInst <"fdiv", 0xF0>; // ST(0) = ST(0) / ST(i) + def FDIVRrST0 : FPrST0Inst <"fdivr", 0xF0>; // ST(i) = ST(0) / ST(i) + def FDIVRPrST0 : FPrST0PInst<"fdivrp", 0xF0>; // ST(i) = ST(0) / ST(i), pop + + // Floating point compares + set isVoid = 1 in { + def FUCOMr : X86Inst<"fucom" , 0xE0, AddRegFrm, ArgF80>, DD, Imp<[ST0],[]>; // FPSW = compare ST(0) with ST(i) + def FUCOMPr : X86Inst<"fucomp" , 0xE8, AddRegFrm, ArgF80>, DD, Imp<[ST0],[]>; // FPSW = compare ST(0) with ST(i), pop + def FUCOMPPr : X86Inst<"fucompp", 0xE9, RawFrm , ArgF80>, DA, Imp<[ST0],[]>; // compare ST(0) with ST(1), pop, pop + + // Floating point flag ops + def FNSTSWr8 : X86Inst<"fnstsw" , 0xE0, RawFrm , ArgF80>, DF, Imp<[],[AX]>; // AX = fp flags + def FNSTCWm16 : X86Inst<"fnstcw" , 0xD9, MRMS7m , Arg16 >; // [mem16] = X87 control world + def FLDCWm16 : X86Inst<"fldcw" , 0xD9, MRMS5m , Arg16 >; // X87 control world = [mem16] + } Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.2 llvm/lib/Target/X86/X86.td:1.3 --- llvm/lib/Target/X86/X86.td:1.2 Sun Aug 3 13:19:37 2003 +++ llvm/lib/Target/X86/X86.td Sun Aug 3 16:54:21 2003 @@ -19,7 +19,18 @@ // Instruction Descriptions //===----------------------------------------------------------------------===// +include "X86InstrInfo.td" + def X86InstrInfo : InstrInfo { + set PHIInst = PHI; + set NOOPInst = NOOP; + + // Define how we want to layout our TargetSpecific information field... This + // should be kept up-to-date with the fields in the X86InstrInfo.h file. + set TSFlagsFields = ["FormBits", "isVoid", "hasOpSizePrefix", "Prefix", + "TypeBits", "FPFormBits", "printImplicitUses", "Opcode"]; + set TSFlagsShifts = [ 0, 5, 6, 7, + 11, 14, 17, 18]; } def X86 : Target { From lattner at cs.uiuc.edu Mon Aug 4 00:00:28 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:28 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308032152.QAA30003@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.9 -> 1.10 --- Log message: Rearrange fields yet again: Don't instantiate these lists ONCE PER INSTRUCTION. --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.9 llvm/lib/Target/Target.td:1.10 --- llvm/lib/Target/Target.td:1.9 Sun Aug 3 13:18:31 2003 +++ llvm/lib/Target/Target.td Sun Aug 3 16:52:28 2003 @@ -95,12 +95,6 @@ bit isCall = 0; // Is this instruction a call instruction? bit isTwoAddress = 0; // Is this a two address instruction? bit isTerminator = 0; // Is this part of the terminator for a basic block? - - // If the target wants to associate some target-specific information with each - // instruction, it should provide these two lists to indicate how to assemble - // the target specific information into the 32 bits available. - list TargetInfoFields = []; - list TargetInfoPositions = []; } // InstrInfo - This class should only be instantiated once to provide parameters @@ -109,6 +103,13 @@ class InstrInfo { Instruction PHIInst; Instruction NOOPInst; + + // If the target wants to associate some target-specific information with each + // instruction, it should provide these two lists to indicate how to assemble + // the target specific information into the 32 bits available. + // + list TSFlagsFields = []; + list TSFlagsShifts = []; } From lattner at cs.uiuc.edu Mon Aug 4 00:00:30 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:30 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200308032154.QAA30122@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def (r1.63) removed --- Log message: Remove the old .def file, it is now obsolete --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Aug 4 00:00:32 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:32 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200308031852.NAA04495@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.49 -> 1.50 --- Log message: The NOOP instruction is no longer needed. Instead, use the TargetInstrInfo::isNOPinstr method --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.49 llvm/include/llvm/Target/TargetInstrInfo.h:1.50 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.49 Tue Jul 29 15:30:20 2003 +++ llvm/include/llvm/Target/TargetInstrInfo.h Sun Aug 3 13:52:15 2003 @@ -93,11 +93,8 @@ unsigned numRealOpCodes); virtual ~TargetInstrInfo(); - // Invariant: All instruction sets use opcode #0 as the PHI instruction and - // opcode #1 as the noop instruction. - enum { - PHI = 0, NOOP = 1 - }; + // Invariant: All instruction sets use opcode #0 as the PHI instruction + enum { PHI = 0 }; unsigned getNumRealOpCodes() const { return numRealOpCodes; } unsigned getNumTotalOpCodes() const { return descSize; } From lattner at cs.uiuc.edu Mon Aug 4 00:00:34 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:34 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstr.cpp Message-ID: <200308032024.PAA13884@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.73 -> 1.74 --- Log message: Remove using decl --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.73 llvm/lib/CodeGen/MachineInstr.cpp:1.74 --- llvm/lib/CodeGen/MachineInstr.cpp:1.73 Thu Jul 10 14:44:49 2003 +++ llvm/lib/CodeGen/MachineInstr.cpp Sun Aug 3 15:24:29 2003 @@ -8,8 +8,6 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/MRegisterInfo.h" -using std::cerr; - // Global variable holding an array of descriptors for machine instructions. // The actual object needs to be created separately for each target machine. @@ -198,7 +196,7 @@ void MachineInstr::dump() const { - cerr << " " << *this; + std::cerr << " " << *this; } static inline std::ostream& From lattner at cs.uiuc.edu Mon Aug 4 00:00:37 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:37 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l Message-ID: <200308031813.NAA01636@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.6 -> 1.7 --- Log message: expand contraction --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.6 llvm/utils/TableGen/FileLexer.l:1.7 --- llvm/utils/TableGen/FileLexer.l:1.6 Wed Jul 30 17:15:58 2003 +++ llvm/utils/TableGen/FileLexer.l Sun Aug 3 13:12:59 2003 @@ -50,7 +50,7 @@ return std::cerr << "At end of input: "; for (unsigned i = 0, e = IncludeStack.size()-1; i != e; ++i) - std::cerr << "IncFrom " << IncludeStack[i].Filename << ":" + std::cerr << "Included from " << IncludeStack[i].Filename << ":" << IncludeStack[i].LineNo << ":\n"; return std::cerr << "Parsing " << IncludeStack.back().Filename << ":" << Filelineno << ": "; From lattner at cs.uiuc.edu Mon Aug 4 00:00:39 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:39 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/FloatingPoint.cpp X86CodeEmitter.cpp Message-ID: <200308032114.QAA20769@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: FloatingPoint.cpp updated: 1.4 -> 1.5 X86CodeEmitter.cpp updated: 1.32 -> 1.33 --- Log message: Set debug types --- Diffs of the changes: Index: llvm/lib/Target/X86/FloatingPoint.cpp diff -u llvm/lib/Target/X86/FloatingPoint.cpp:1.4 llvm/lib/Target/X86/FloatingPoint.cpp:1.5 --- llvm/lib/Target/X86/FloatingPoint.cpp:1.4 Fri Aug 1 17:20:37 2003 +++ llvm/lib/Target/X86/FloatingPoint.cpp Sun Aug 3 16:14:38 2003 @@ -5,6 +5,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "fp" #include "X86.h" #include "X86InstrInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.32 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.33 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.32 Fri Aug 1 17:20:22 2003 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Sun Aug 3 16:14:38 2003 @@ -5,6 +5,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "jit" #include "X86TargetMachine.h" #include "X86.h" #include "llvm/PassManager.h" From lattner at cs.uiuc.edu Mon Aug 4 00:00:43 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:43 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/ListConversion.td Message-ID: <200308031826.NAA03518@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: ListConversion.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/ListConversion.td diff -c /dev/null llvm/test/Regression/TableGen/ListConversion.td:1.1 *** /dev/null Sun Aug 3 13:26:51 2003 --- llvm/test/Regression/TableGen/ListConversion.td Sun Aug 3 13:26:40 2003 *************** *** 0 **** --- 1,10 ---- + // RUN: tblgen %s + class A; + class B : A; + + def b : B; + + def { + list X = [b]; + list Y = X; + } From lattner at cs.uiuc.edu Mon Aug 4 00:00:45 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:45 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Record.h Message-ID: <200308031830.NAA04675@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.20 -> 1.21 Record.h updated: 1.25 -> 1.26 --- Log message: Fix bug: TableGen/IntBitInit.td --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.20 llvm/utils/TableGen/Record.cpp:1.21 --- llvm/utils/TableGen/Record.cpp:1.20 Sun Aug 3 13:24:34 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 3 13:29:51 2003 @@ -93,6 +93,10 @@ return 0; } +Init *IntRecTy::convertValue(BitInit *BI) { + return new IntInit(BI->getValue()); +} + Init *IntRecTy::convertValue(BitsInit *BI) { int Result = 0; for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) @@ -105,7 +109,7 @@ } Init *IntRecTy::convertValue(TypedInit *TI) { - if (dynamic_cast(TI->getType())) + if (TI->getType()->typeIsConvertibleTo(this)) return TI; // Accept variable if already of the right type! return 0; } Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.25 llvm/utils/TableGen/Record.h:1.26 --- llvm/utils/TableGen/Record.h:1.25 Sun Aug 3 13:16:55 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 3 13:29:51 2003 @@ -145,6 +145,7 @@ struct IntRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(IntInit *II) { return (Init*)II; } + Init *convertValue(BitInit *BI); Init *convertValue(BitsInit *BI); Init *convertValue(TypedInit *TI); From lattner at cs.uiuc.edu Mon Aug 4 00:00:47 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:47 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/IntBitInit.td Message-ID: <200308031828.NAA04338@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: IntBitInit.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/IntBitInit.td diff -c /dev/null llvm/test/Regression/TableGen/IntBitInit.td:1.1 *** /dev/null Sun Aug 3 13:28:19 2003 --- llvm/test/Regression/TableGen/IntBitInit.td Sun Aug 3 13:28:09 2003 *************** *** 0 **** --- 1,5 ---- + // RUN: tblgen %s + def { + bit A = 1; + int B = A; + } From lattner at cs.uiuc.edu Mon Aug 4 00:00:49 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:49 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Record.cpp Message-ID: <200308031817.NAA02250@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.24 -> 1.25 Record.cpp updated: 1.18 -> 1.19 --- Log message: Changes to allow lists of any type --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.24 llvm/utils/TableGen/Record.h:1.25 --- llvm/utils/TableGen/Record.h:1.24 Fri Aug 1 20:27:37 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 3 13:16:55 2003 @@ -14,6 +14,16 @@ #include #include +// RecTy subclasses... +class BitRecTy; +class BitsRecTy; +class IntRecTy; +class StringRecTy; +class ListRecTy; +class CodeRecTy; +class RecordRecTy; + +// Init subclasses... class Init; class UnsetInit; class BitInit; @@ -27,6 +37,8 @@ class VarInit; class FieldInit; class VarBitInit; + +// Other classes... class Record; //===----------------------------------------------------------------------===// @@ -36,6 +48,14 @@ struct RecTy { virtual ~RecTy() {} + virtual void print(std::ostream &OS) const = 0; + void dump() const; + + /// typeIsConvertibleTo - Return true if all values of 'this' type can be + /// converted to the specified type. + virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; + +public: // These methods should only be called from subclasses of Init virtual Init *convertValue( UnsetInit *UI) { return 0; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -53,8 +73,16 @@ return convertValue((TypedInit*)FI); } - virtual void print(std::ostream &OS) const = 0; - void dump() const; +public: // These methods should only be called by subclasses of RecTy. + // baseClassOf - These virtual methods should be overloaded to return true iff + // all values of type 'RHS' can be converted to the 'this' type. + virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } + virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } + virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) { @@ -74,6 +102,13 @@ Init *convertValue(VarBitInit *VB) { return (Init*)VB; } void print(std::ostream &OS) const { OS << "bit"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } + virtual bool baseClassOf(const BitsRecTy *RHS) const; + virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } }; @@ -93,6 +128,15 @@ Init *convertValue(TypedInit *VI); void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { + return RHS->Size == Size; + } }; @@ -105,6 +149,14 @@ Init *convertValue(TypedInit *TI); void print(std::ostream &OS) const { OS << "int"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } + virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } + virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; } }; /// StringRecTy - 'string' - Represent an string value @@ -114,25 +166,37 @@ Init *convertValue(StringInit *SI) { return (Init*)SI; } Init *convertValue(TypedInit *TI); void print(std::ostream &OS) const { OS << "string"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const StringRecTy *RHS) const { return true; } }; -/// ListRecTy - 'list' - Represent a list defs, all of which must be -/// derived from the specified class. +/// ListRecTy - 'list' - Represent a list of values, all of which must be of +/// the specified type. /// class ListRecTy : public RecTy { - Record *Class; + RecTy *Ty; public: - ListRecTy(Record *C) : Class(C) {} + ListRecTy(RecTy *T) : Ty(T) {} - /// getElementClass - Return the class that the list contains. - /// - Record *getElementClass() const { return Class; } + RecTy *getElementType() const { return Ty; } Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(ListInit *LI); Init *convertValue(TypedInit *TI); void print(std::ostream &OS) const; + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + + virtual bool baseClassOf(const ListRecTy *RHS) const { + return RHS->getElementType()->typeIsConvertibleTo(Ty); + } }; /// CodeRecTy - 'code' - Represent an code fragment, function or method. @@ -142,6 +206,11 @@ Init *convertValue( CodeInit *CI) { return (Init*)CI; } void print(std::ostream &OS) const { OS << "code"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; } }; @@ -160,6 +229,11 @@ Init *convertValue(TypedInit *VI); void print(std::ostream &OS) const; + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const RecordRecTy *RHS) const; }; @@ -347,16 +421,16 @@ /// ListInit - [AL, AH, CL] - Represent a list of defs /// class ListInit : public Init { - std::vector Records; + std::vector Values; public: - ListInit(std::vector &Rs) { - Records.swap(Rs); + ListInit(std::vector &Vs) { + Values.swap(Vs); } - unsigned getSize() const { return Records.size(); } - Record *getElement(unsigned i) const { - assert(i < Records.size() && "List element index out of range!"); - return Records[i]; + unsigned getSize() const { return Values.size(); } + Init *getElement(unsigned i) const { + assert(i < Values.size() && "List element index out of range!"); + return Values[i]; } virtual Init *convertInitializerTo(RecTy *Ty) { Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.18 llvm/utils/TableGen/Record.cpp:1.19 --- llvm/utils/TableGen/Record.cpp:1.18 Fri Aug 1 20:27:37 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 3 13:16:55 2003 @@ -16,6 +16,10 @@ return BI->getBit(0); } +bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const { + return RHS->getNumBits() == 1; +} + Init *BitRecTy::convertValue(IntInit *II) { int Val = II->getValue(); if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit! @@ -104,22 +108,27 @@ } void ListRecTy::print(std::ostream &OS) const { - OS << "list<" << Class->getName() << ">"; + OS << "list<" << *Ty << ">"; } Init *ListRecTy::convertValue(ListInit *LI) { + std::vector Elements; + // Verify that all of the elements of the list are subclasses of the - // appopriate class! + // appropriate class! for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - if (!LI->getElement(i)->isSubClassOf(Class)) + if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty)) + Elements.push_back(CI); + else return 0; - return LI; + + return new ListInit(Elements); } Init *ListRecTy::convertValue(TypedInit *TI) { // Ensure that TI is compatible with our class. if (ListRecTy *LRT = dynamic_cast(TI->getType())) - if (LRT->getElementClass() == getElementClass()) + if (LRT->getElementType()->typeIsConvertibleTo(getElementType())) return TI; return 0; } @@ -144,6 +153,11 @@ return 0; } +bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const { + return Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec); +} + + //===----------------------------------------------------------------------===// // Initializer implementations //===----------------------------------------------------------------------===// @@ -263,9 +277,9 @@ void ListInit::print(std::ostream &OS) const { OS << "["; - for (unsigned i = 0, e = Records.size(); i != e; ++i) { + for (unsigned i = 0, e = Values.size(); i != e; ++i) { if (i) OS << ", "; - OS << Records[i]->getName(); + OS << *Values[i]; } OS << "]"; } From lattner at cs.uiuc.edu Mon Aug 4 00:00:51 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:00:51 2003 Subject: [llvm-commits] CVS: llvm/.cvsignore Message-ID: <200308031833.NAA05314@apoc.cs.uiuc.edu> Changes in directory llvm: .cvsignore updated: 1.1 -> 1.2 --- Log message: Ok, try #2, this time I'll not be stupid --- Diffs of the changes: Index: llvm/.cvsignore diff -u llvm/.cvsignore:1.1 llvm/.cvsignore:1.2 --- llvm/.cvsignore:1.1 Sun Aug 3 13:32:10 2003 +++ llvm/.cvsignore Sun Aug 3 13:33:24 2003 @@ -1,7227 +1,5 @@ -#! /bin/sh - -# mklibT - Provide generalized library-building support services. -# Generated automatically by (GNU ) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED="/bin/sed" - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="/bin/sed -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -# The names of the tagged configurations supported by this script. -available_tags=" CXX F77" - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host apoc.cs.uiuc.edu: - -# Shell to use when invoking shell scripts. -SHELL="/bin/sh" - -# Whether or not to build shared libraries. -build_libtool_libs=yes - -# Whether or not to build static libraries. -build_old_libs=yes - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=no - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=no - -# Whether or not to optimize for fast installation. -fast_install=yes - -# The host system. -host_alias= -host=i686-pc-linux-gnu - -# An echo program that does not interpret backslashes. -echo="echo" - -# The archiver. -AR="ar" -AR_FLAGS="cru" - -# A C compiler. -LTCC="gcc" - -# A language-specific compiler. -CC="gcc" - -# Is the compiler the GNU C compiler? -with_gcc=yes - -# An ERE matcher. -EGREP="grep -E" - -# The linker used to build libraries. -LD="/usr/bin/ld" - -# Whether we need hard or soft links. -LN_S="ln -s" - -# A BSD-compatible nm program. -NM="/usr/bin/nm -B" - -# A symbol stripping program -STRIP=strip - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=file - -# Used on cygwin: DLL creation program. -DLLTOOL="dlltool" - -# Used on cygwin: object dumper. -OBJDUMP="objdump" - -# Used on cygwin: assembler. -AS="as" - -# The name of the directory that contains temporary libtool files. -objdir=.libs - -# How to create reloadable object files. -reload_flag=" -r" -reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" - -# How to pass a linker flag through the compiler. -wl="-Wl," - -# Object file suffix (normally "o"). -objext="o" - -# Old archive suffix (normally "a"). -libext="a" - -# Shared library suffix (normally ".so"). -shrext='.so' - -# Executable file suffix (normally ""). -exeext="" - -# Additional compiler flags for building library objects. -pic_flag=" -fPIC -DPIC" -pic_mode=default - -# What is the maximum length of a command? -max_cmd_len=32768 - -# Does compiler simultaneously support -c and -o options? -compiler_c_o="yes" - -# Must we lock files when doing compilation ? -need_locks="no" - -# Do we need the lib prefix for modules? -need_lib_prefix=no - -# Do we need a version for libraries? -need_version=no - -# Whether dlopen is supported. -dlopen_support=unknown - -# Whether dlopen of programs is supported. -dlopen_self=unknown - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=unknown - -# Compiler flag to prevent dynamic linking. -link_static_flag="-static" - -# Compiler flag to turn off builtin functions. -no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions" - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec="\${wl}--export-dynamic" - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec="" - -# Library versioning type. -version_type=linux - -# Format of library name prefix. -libname_spec="lib\$name" - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" - -# The coded name of the library, if different from the real name. -soname_spec="\${libname}\${release}\${shared_ext}\$major" - -# Commands used to build and install an old-style archive. -RANLIB="ranlib" -old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" -old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" -old_postuninstall_cmds="" - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds="" - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds="" - -# Commands used to build and install a shared archive. -archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" -archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" -postinstall_cmds="" -postuninstall_cmds="" - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds="" -module_expsym_cmds="" - -# Commands to strip libraries. -old_striplib="strip --strip-debug" -striplib="strip --strip-unneeded" - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects="" - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps="" - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path="" - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method="pass_all" - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd="\$MAGIC_CMD" - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag="" - -# Flag that forces no undefined symbols. -no_undefined_flag="" - -# Commands used to finish a libtool library installation in a directory. -finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval="" - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW][ABCDGISTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" - -# This is the shared library runtime path variable. -runpath_var=LD_RUN_PATH - -# This is the shared library path variable. -shlibpath_var=LD_LIBRARY_PATH - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=no - -# How to hardcode a shared library path into an executable. -hardcode_action=immediate - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=yes - -# Flag to hardcode $libdir into a binary during linking. -# This must work even if $libdir does not exist. -hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" - -# If ld is used when linking, flag to hardcode $libdir into -# a binary during linking. This must work even if $libdir does -# not exist. -hardcode_libdir_flag_spec_ld="" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="" - -# Set to yes if using DIR/libNAME during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=no - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=no - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=unsupported - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=no - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=unknown - -# Compile-time system search path for libraries -sys_lib_search_path_spec=" /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/lib/gcc/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linu! x-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /lib/i686-pc-linux-gnu/3.2/ /lib/ /usr/lib/i686-pc-linux-gnu/3.2/ /usr/lib/" - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib" - -# Fix the shell variable $srcfile for the compiler. -fix_srcfile_path="" - -# Set to yes if exported symbols are required. -always_export_symbols=no - -# The commands to list exported symbols. -export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds="" - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" - -# Symbols that must always be exported. -include_expsyms="" - -# ### END LIBTOOL CONFIG - -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -##################################### -# Shell function definitions: -# This seems to be the best place for them - -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -win32_libid () { - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ - grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then - win32_nmres=`eval $NM -f posix -A $1 | \ - sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` - if test "X$win32_nmres" = "Ximport" ; then - win32_libid_type="x86 archive import" - else - win32_libid_type="x86 archive static" - fi - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $echo $win32_libid_type -} - -# End of Shell function definitions -##################################### - -# Parse our command line options once, thoroughly. -while test "$#" -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - tag) - tagname="$arg" - - # Check whether tagname contains only valid characters - case $tagname in - *[!-_A-Za-z0-9,/]*) - $echo "$progname: invalid tag name: $tagname" 1>&2 - exit 1 - ;; - esac - - case $tagname in - CC) - # Don't test for the "default" C tag, as we know, it's there, but - # not specially marked. - ;; - *) - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then - taglist="$taglist $tagname" - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`" - else - $echo "$progname: ignoring unknown tag $tagname" 1>&2 - fi - ;; - esac - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - $echo - $echo "Copyright (C) 2003 Free Software Foundation, Inc." - $echo "This is free software; see the source for copying conditions. There is NO" - $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - exit 0 - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 - # Now print the configurations for the tags. - for tagname in $taglist; do - ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0" - done - exit 0 - ;; - - --debug) - $echo "$progname: enabling shell trace mode" - set -x - ;; - - --dry-run | -n) - run=: - ;; - - --features) - $echo "host: $host" - if test "$build_libtool_libs" = yes; then - $echo "enable shared libraries" - else - $echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - $echo "enable static libraries" - else - $echo "disable static libraries" - fi - exit 0 - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - ;; - - --tag) prevopt="--tag" prev=tag ;; - --tag=*) - set tag "$optarg" ${1+"$@"} - shift - prev=tag - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 -fi - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 - $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2 - case $nonopt in - *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_output= - arg_mode=normal - libobj= - - for arg - do - case "$arg_mode" in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - if test -n "$libobj" ; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit 1 - fi - arg_mode=target - continue - ;; - - -static) - build_old_libs=yes - continue - ;; - - -only-static) - build_libtool_libs=no - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - base_compile="$base_compile $lastarg" - continue - ;; - - * ) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - case $lastarg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - base_compile="$base_compile $lastarg" - done # for arg - - case $arg_mode in - arg) - $echo "$modename: you must specify an argument for -Xcompile" - exit 1 - ;; - target) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit 1 - ;; - *) - # Get the name of the library object. - [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSifmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.ii) xform=ii ;; - *.class) xform=class ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - *.java) xform=java ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit 1 - ;; - esac - - # Infer tagged configuration to use if any are available and - # if one wasn't chosen via the "--tag" command line option. - # Only attempt this if the compiler in the base compile - # command doesn't match the default compiler. - if test -n "$available_tags" && test -z "$tagname"; then - case $base_compile in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" - case "$base_compile " in - "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - $echo "$modename: unable to infer tagged configuration" - $echo "$modename: specify a tag with \`--tag'" 1>&2 - exit 1 -# else -# $echo "$modename: using $tagname tagged configuration" - fi - ;; - esac - fi - - objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir= - else - xdir=$xdir/ - fi - lobj=${xdir}$objdir/$objname - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit 1" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit 1" 1 2 15 - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$0" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - $echo $srcfile > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - - $run $rm "$libobj" "${libobj}T" - - # Create a libtool object file (analogous to a ".la" file), - # but don't create it if we're doing a dry run. - test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - $show "$mv $output_obj $lobj" - if $run $mv $output_obj $lobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the PIC object to the libtool object file. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the non-PIC object the libtool object file. - # Only append if the libtool object file exists. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - base_compile="$base_compile $arg" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit 1 - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat $save_arg` - do -# moreargs="$moreargs $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit 1 - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit 1 - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - done - else - $echo "$modename: link input file \`$save_arg' does not exist" - exit 1 - fi - arg=$save_arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - xcclinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit 1 - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit 1 - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - deplibs="$deplibs -framework System" - continue - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # gcc -m* arguments should be passed to the linker via $compiler_flags - # in order to pass architecture information to the linker - # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo - # but this is not reliable with gcc because gcc may use -mfoo to - # select a different linker, different libraries, etc, while - # -Wl,-mfoo simply passes -mfoo to the linker. - -m*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - if test "$with_gcc" = "yes" ; then - compiler_flags="$compiler_flags $arg" - fi - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.$objext) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit 1 - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit 1 - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Infer tagged configuration to use if any are available and - # if one wasn't chosen via the "--tag" command line option. - # Only attempt this if the compiler in the base link - # command doesn't match the default compiler. - if test -n "$available_tags" && test -z "$tagname"; then - case $base_compile in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" - case $base_compile in - "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) - # The compiler in $compile_command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - $echo "$modename: unable to infer tagged configuration" - $echo "$modename: specify a tag with \`--tag'" 1>&2 - exit 1 -# else -# $echo "$modename: using $tagname tagged configuration" - fi - ;; - esac - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d "$output_objdir"; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test "$status" -ne 0 && test ! -d "$output_objdir"; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - case $host in - *cygwin* | *mingw* | *pw32*) - # don't eliminate duplcations in $postdeps and $predeps - duplicate_compiler_generated_deps=yes - ;; - *) - duplicate_compiler_generated_deps=$duplicate_deps - ;; - esac - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; - esac - pre_post_deps="$pre_post_deps $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit 1 - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 - continue - fi - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - # Search the libtool library - lib="$searchdir/lib${name}.la" - if test -f "$lib"; then - found=yes - break - fi - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if (${SED} -e '2q' $lib | - grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - library_names= - old_library= - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - if test "$deplibs_check_method" != pass_all; then - $echo - $echo "*** Warning: Trying to link with static lib archive $deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because the file extensions .$libext of this argument makes me believe" - $echo "*** that it is just a static archive that I should not used here." - else - $echo - $echo "*** Warning: Linking the shared library $output against the" - $echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit 1 - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit 1 - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - dlprefiles="$dlprefiles $lib $dependency_libs" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var"; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $dir" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - # This is a shared library - - # Warn about portability, can't link against -module's on some systems (darwin) - if test "$shouldnotlink" = yes && test "$pass" = link ; then - $echo - if test "$linkmode" = prog; then - $echo "*** Warning: Linking the executable $output against the loadable module" - else - $echo "*** Warning: Linking the shared library $output against the loadable module" - fi - $echo "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`$echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - eval cmds=\"$extract_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - eval cmds=\"$old_archive_from_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5* ) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a module then we can not link against it, someone - # is ignoring the new warnings I added - if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; then - $echo "** Warning, lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - $echo - $echo "** And there doesn't seem to be a static archive available" - $echo "** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case "$libdir" in - [\\/]*) - add_dir="-L$inst_prefix_dir$libdir $add_dir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit 1 - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case "$libdir" in - [\\/]*) - add_dir="-L$inst_prefix_dir$libdir $add_dir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - $echo - $echo "*** Warning: This system can not link to static lib archive $lib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - $echo "*** But as you try to build a module library, libtool will still create " - $echo "*** a static module, that should work as long as the dlopening application" - $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - convenience="$convenience $dir/$old_library" - old_convenience="$old_convenience $dir/$old_library" - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="$absdir" - fi - depdepl= - case $host in - *-*-darwin*) - # we do not want to link against static libs, but need to link against shared - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$path/$depdepl" ; then - depdepl="$path/$depdepl" - fi - newlib_search_path="$newlib_search_path $path" - path="" - fi - ;; - *) - path="-L$path" - ;; - esac - - ;; - -l*) - case $host in - *-*-darwin*) - # Again, we only want to link against shared libraries - eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` - for tmp in $newlib_search_path ; do - if test -f "$tmp/lib$tmp_libs.dylib" ; then - eval depdepl="$tmp/lib$tmp_libs.dylib" - break - fi - done - path="" - ;; - *) continue ;; - esac - ;; - *) continue ;; - esac - case " $deplibs " in - *" $depdepl "*) ;; - *) deplibs="$deplibs $depdepl" ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$deplibs $path" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - tmp_libs="$tmp_libs $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval shared_ext=\"$shrext\" - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval shared_ext=\"$shrext\" - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit 1 - else - $echo - $echo "*** Warning: Linking the shared library $output against the non-libtool" - $echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test "$#" -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$2" - number_minor="$3" - number_revision="$4" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows) - current=`expr $number_major + $number_minor` - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - current=`expr $number_major + $number_minor - 1` - age="$number_minor" - revision="$number_minor" - ;; - esac - ;; - no) - current="$2" - revision="$3" - age="$4" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $revision in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $age in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - if test "$age" -gt "$current"; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - major=`expr $current - $age + 1` - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$echo "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - removelist="$removelist $p" - ;; - *) ;; - esac - done - if test -n "$removelist"; then - $show "${rm}r $removelist" - $run ${rm}r $removelist - fi - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` - deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` - dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for file magic test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name="`expr $a_deplib : '-l\(.*\)'`" - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval $echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` - done - fi - if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ - | grep . >/dev/null; then - $echo - if test "X$deplibs_check_method" = "Xnone"; then - $echo "*** Warning: inter-library dependencies are not supported in this platform." - else - $echo "*** Warning: inter-library dependencies are not known to be supported." - fi - $echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - $echo - $echo "*** Warning: libtool could not satisfy all declared inter-library" - $echo "*** dependencies of module $libname. Therefore, libtool will create" - $echo "*** a static module, that should work as long as the dlopening" - $echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - $echo "*** The inter-library dependencies that have been dropped here will be" - $echo "*** automatically added whenever a program is linked with this library" - $echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - $echo - $echo "*** Since this library must not contain undefined symbols," - $echo "*** because either the platform does not support them or" - $echo "*** it was explicitly requested with -no-undefined," - $echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - eval cmds=\"$export_symbols_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - if len=`expr "X$cmd" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - $show "$cmd" - $run eval "$cmd" || exit $? - skipped_export=false - else - # The command line is too long to execute in one step. - $show "using reloadable object file for export list..." - skipped_export=: - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - tmp_deplibs="$tmp_deplibs $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - status=$? - if test "$status" -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "$mkdir $xdir" - $run $mkdir "$xdir" - status=$? - if test "$status" -ne 0 && test ! -d "$xdir"; then - exit $status - fi - # We will extract separately just the conflicting names and we will no - # longer touch any unique names. It is faster to leave these extract - # automatically by $AR in one run. - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 - $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 - $AR t "$xabs" | sort | uniq -cd | while read -r count name - do - i=1 - while test "$i" -le "$count" - do - # Put our $i before any first dot (extension) - # Never overwrite any file - name_to="$name" - while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" - do - name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` - done - $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" - $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? - i=`expr $i + 1` - done - done - fi - - libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval cmds=\"$module_expsym_cmds\" - else - eval cmds=\"$module_cmds\" - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval cmds=\"$archive_expsym_cmds\" - else - eval cmds=\"$archive_cmds\" - fi - fi - - if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise. - $echo "creating reloadable object files..." - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - delfiles= - last_robj= - k=1 - output=$output_objdir/$save_output-${k}.$objext - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" - if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*"` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" - fi - last_robj=$output_objdir/$save_output-${k}.$objext - k=`expr $k + 1` - output=$output_objdir/$save_output-${k}.$objext - objlist=$obj - len=1 - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" - - if ${skipped_export-false}; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - libobjs=$output - # Append the command to create the export file. - eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" - fi - - # Set up a command to remove the reloadale object files - # after they are used. - i=0 - while test "$i" -lt "$k" - do - i=`expr $i + 1` - delfiles="$delfiles $output_objdir/$save_output-${i}.$objext" - done - - $echo "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval cmds=\"$archive_expsym_cmds\" - else - eval cmds=\"$archive_cmds\" - fi - - # Append the command to remove the reloadable object files - # to the just-reset $cmds. - eval cmds=\"\$cmds~$rm $delfiles\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - exit 0 - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit 1 - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - status=$? - if test "$status" -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "$mkdir $xdir" - $run $mkdir "$xdir" - status=$? - if test "$status" -ne 0 && test ! -d "$xdir"; then - exit $status - fi - # We will extract separately just the conflicting names and we will no - # longer touch any unique names. It is faster to leave these extract - # automatically by $AR in one run. - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 - $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 - $AR t "$xabs" | sort | uniq -cd | while read -r count name - do - i=1 - while test "$i" -le "$count" - do - # Put our $i before any first dot (extension) - # Never overwrite any file - name_to="$name" - while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" - do - name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` - done - $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" - $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? - i=`expr $i + 1` - done - done - fi - - reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - eval cmds=\"$reload_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $run eval "echo timestamp > $libobj" || exit $? - exit 0 - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - eval cmds=\"$reload_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - ;; - - prog) - case $host in - *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - if test "$tagname" = CXX ; then - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - fi - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$output.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' - $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval '$echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - $echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit 1 - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit 0 - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $0 --fallback-echo"; then - case $0 in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; - *) qecho="$SHELL `pwd`/$0 --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - cwrappersource=`$echo ${objdir}/lt-${output}.c` - cwrapper=`$echo ${output}.exe` - $rm $cwrappersource $cwrapper - trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15 - - cat > $cwrappersource <> $cwrappersource<<"EOF" -#include -#include -#include -#include -#include -#include - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -#define HAVE_DOS_BASED_FILE_SYSTEM -#ifndef DIR_SEPARATOR_2 -#define DIR_SEPARATOR_2 '\\' -#endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -const char *program_name = NULL; - -void * xmalloc (size_t num); -char * xstrdup (const char *string); -char * basename (const char *name); -char * fnqualify(const char *path); -char * strendzap(char *str, const char *pat); -void lt_fatal (const char *message, ...); - -int -main (int argc, char *argv[]) -{ - char **newargz; - int i; - - program_name = (char *) xstrdup ((char *) basename (argv[0])); - newargz = XMALLOC(char *, argc+2); -EOF - - cat >> $cwrappersource <> $cwrappersource <<"EOF" - newargz[1] = fnqualify(argv[0]); - /* we know the script has the same name, without the .exe */ - /* so make sure newargz[1] doesn't end in .exe */ - strendzap(newargz[1],".exe"); - for (i = 1; i < argc; i++) - newargz[i+1] = xstrdup(argv[i]); - newargz[argc+1] = NULL; -EOF - - cat >> $cwrappersource <> $cwrappersource <<"EOF" -} - -void * -xmalloc (size_t num) -{ - void * p = (void *) malloc (num); - if (!p) - lt_fatal ("Memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL -; -} - -char * -basename (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha (name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return (char *) base; -} - -char * -fnqualify(const char *path) -{ - size_t size; - char *p; - char tmp[LT_PATHMAX + 1]; - - assert(path != NULL); - - /* Is it qualified already? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha (path[0]) && path[1] == ':') - return xstrdup (path); -#endif - if (IS_DIR_SEPARATOR (path[0])) - return xstrdup (path); - - /* prepend the current directory */ - /* doesn't handle '~' */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ - p = XMALLOC(char, size); - sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); - return p; -} - -char * -strendzap(char *str, const char *pat) -{ - size_t len, patlen; - - assert(str != NULL); - assert(pat != NULL); - - len = strlen(str); - patlen = strlen(pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp(str, pat) == 0) - *str = '\0'; - } - return str; -} - -static void -lt_error_core (int exit_status, const char * mode, - const char * message, va_list ap) -{ - fprintf (stderr, "%s: %s: ", program_name, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, "FATAL", message, ap); - va_end (ap); -} -EOF - # we should really use a build-platform specific compiler - # here, but OTOH, the wrappers (shell script and this C one) - # are only useful if you want to execute the "real" binary. - # Since the "real" binary is built for $host, then this - # wrapper might as well be built for $host, too. - $run $LTCC -s -o $cwrapper $cwrappersource - ;; - esac - $rm $output - trap "$rm $output; exit 1" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='${SED} -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - $echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit 1 - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - $echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \$progdir\\\\\$program \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - exec \$progdir/\$program \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit 1 - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - $echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" - chmod +x $output - fi - exit 0 - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - status=$? - if test "$status" -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - # Add in members from convenience archives. - for xlib in $addlibs; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "$mkdir $xdir" - $run $mkdir "$xdir" - status=$? - if test "$status" -ne 0 && test ! -d "$xdir"; then - exit $status - fi - # We will extract separately just the conflicting names and we will no - # longer touch any unique names. It is faster to leave these extract - # automatically by $AR in one run. - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 - $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 - $AR t "$xabs" | sort | uniq -cd | while read -r count name - do - i=1 - while test "$i" -le "$count" - do - # Put our $i before any first dot (extension) - # Never overwrite any file - name_to="$name" - while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" - do - name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` - done - $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" - $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? - i=`expr $i + 1` - done - done - fi - - oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` - done - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - eval cmds=\"$old_archive_from_new_cmds\" - else - eval cmds=\"$old_archive_cmds\" - - if len=`expr "X$cmds" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # the command line is too long to link in one step, link in parts - $echo "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - # GNU ar 2.10+ was changed to match POSIX; thus no paths are - # encoded into archives. This makes 'ar r' malfunction in - # this piecewise linking case whenever conflicting object - # names appear in distinct ar calls; check, warn and compensate. - if (for obj in $save_oldobjs - do - $echo "X$obj" | $Xsed -e 's%^.*/%%' - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2 - $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2 - AR_FLAGS=cq - fi - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - for obj in $save_oldobjs - do - oldobjs="$objlist $obj" - objlist="$objlist $obj" - eval test_cmds=\"$old_archive_cmds\" - if len=`expr "X$test_cmds" : ".*"` && - test "$len" -le "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~$old_archive_cmds\" - fi - fi - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit 0 - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg="$nonopt" - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest="$arg" - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) prev="-f" ;; - -g) prev="-g" ;; - -m) prev="-m" ;; - -o) prev="-o" ;; - -s) - stripme=" -s" - continue - ;; - -*) ;; - - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest="$arg" - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit 1 - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test "$#" -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit 1 - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - exit 1 - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - eval cmds=\"$postinstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit 0 - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - file=`$echo $file|${SED} 's,.exe$,,'` - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # To insure that "foo" is sourced, and not "foo.exe", - # finese the cygwin/MSYS system by explicitly sourcing "foo." - # which disallows the automatic-append-.exe behavior. - case $build in - *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; - *) wrapperdot=${wrapper} ;; - esac - # If there is no directory component, then add one. - case $file in - */* | *\\*) . ${wrapperdot} ;; - *) . ./${wrapperdot} ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit 1 - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # To insure that "foo" is sourced, and not "foo.exe", - # finese the cygwin/MSYS system by explicitly sourcing "foo." - # which disallows the automatic-append-.exe behavior. - case $build in - *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; - *) wrapperdot=${wrapper} ;; - esac - # If there is no directory component, then add one. - case $file in - */* | *\\*) . ${wrapperdot} ;; - *) . ./${wrapperdot} ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir="$tmpdir/libtool-$$" - if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : - else - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyways - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - eval cmds=\"$old_postinstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $0 --finish$current_libdirs' - else - exit 0 - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - eval cmds=\"$finish_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = : && exit 0 - - $echo "----------------------------------------------------------------------" - $echo "Libraries have been installed in:" - for libdir in $libdirs; do - $echo " $libdir" - done - $echo - $echo "If you ever happen to want to link against installed libraries" - $echo "in a given directory, LIBDIR, you must either use libtool, and" - $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - $echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - $echo " during execution" - fi - if test -n "$runpath_var"; then - $echo " - add LIBDIR to the \`$runpath_var' environment variable" - $echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - $echo - $echo "See any operating system documentation about shared libraries for" - $echo "more information, such as the ld(1) and ld.so(8) manual pages." - $echo "----------------------------------------------------------------------" - exit 0 - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit 1 - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit 1 - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit 0 - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - rmdirs= - - origobjdir="$objdir" - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$origobjdir" - else - objdir="$dir/$origobjdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test "$mode" = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test "$mode" = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - eval cmds=\"$postuninstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - eval cmds=\"$old_postuninstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - - # Read the .lo file - . $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" \ - && test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" \ - && test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$mode" = clean ; then - noexename=$name - case $file in - *.exe) - file=`$echo $file|${SED} 's,.exe$,,'` - noexename=`$echo $name|${SED} 's,.exe$,,'` - # $file with .exe has already been added to rmfiles, - # add $file without .exe - rmfiles="$rmfiles $file" - ;; - esac - # Do a test to see if this is a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$noexename - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - objdir="$origobjdir" - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit 1 -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE. - -Report bugs to ." - exit 0 - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; -esac - -$echo -$echo "Try \`$modename --help' for more information about other modes." - -exit 0 - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# ### BEGIN LIBTOOL TAG CONFIG: CXX - -# Libtool was configured on host apoc.cs.uiuc.edu: - -# Shell to use when invoking shell scripts. -SHELL="/bin/sh" - -# Whether or not to build shared libraries. -build_libtool_libs=yes - -# Whether or not to build static libraries. -build_old_libs=yes - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=no - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=no - -# Whether or not to optimize for fast installation. -fast_install=yes - -# The host system. -host_alias= -host=i686-pc-linux-gnu - -# An echo program that does not interpret backslashes. -echo="echo" - -# The archiver. -AR="ar" -AR_FLAGS="cru" - -# A C compiler. -LTCC="gcc" - -# A language-specific compiler. -CC="g++" - -# Is the compiler the GNU C compiler? -with_gcc=yes - -# An ERE matcher. -EGREP="grep -E" - -# The linker used to build libraries. -LD="/usr/bin/ld" - -# Whether we need hard or soft links. -LN_S="ln -s" - -# A BSD-compatible nm program. -NM="/usr/bin/nm -B" - -# A symbol stripping program -STRIP=strip - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=file - -# Used on cygwin: DLL creation program. -DLLTOOL="dlltool" - -# Used on cygwin: object dumper. -OBJDUMP="objdump" - -# Used on cygwin: assembler. -AS="as" - -# The name of the directory that contains temporary libtool files. -objdir=.libs - -# How to create reloadable object files. -reload_flag=" -r" -reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" - -# How to pass a linker flag through the compiler. -wl="-Wl," - -# Object file suffix (normally "o"). -objext="o" - -# Old archive suffix (normally "a"). -libext="a" - -# Shared library suffix (normally ".so"). -shrext='.so' - -# Executable file suffix (normally ""). -exeext="" - -# Additional compiler flags for building library objects. -pic_flag=" -fPIC -DPIC" -pic_mode=default - -# What is the maximum length of a command? -max_cmd_len=32768 - -# Does compiler simultaneously support -c and -o options? -compiler_c_o="yes" - -# Must we lock files when doing compilation ? -need_locks="no" - -# Do we need the lib prefix for modules? -need_lib_prefix=no - -# Do we need a version for libraries? -need_version=no - -# Whether dlopen is supported. -dlopen_support=unknown - -# Whether dlopen of programs is supported. -dlopen_self=unknown - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=unknown - -# Compiler flag to prevent dynamic linking. -link_static_flag="-static" - -# Compiler flag to turn off builtin functions. -no_builtin_flag=" -fno-builtin" - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec="\${wl}--export-dynamic" - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec="" - -# Library versioning type. -version_type=linux - -# Format of library name prefix. -libname_spec="lib\$name" - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" - -# The coded name of the library, if different from the real name. -soname_spec="\${libname}\${release}\${shared_ext}\$major" - -# Commands used to build and install an old-style archive. -RANLIB="ranlib" -old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" -old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" -old_postuninstall_cmds="" - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds="" - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds="" - -# Commands used to build and install a shared archive. -archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" -archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" -postinstall_cmds="" -postuninstall_cmds="" - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds="" -module_expsym_cmds="" - -# Commands to strip libraries. -old_striplib="strip --strip-debug" -striplib="strip --strip-unneeded" - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects="/usr/lib/crti.o /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/crtbeginS.o" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects="/usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/crtendS.o /usr/lib/crtn.o" - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps="-lstdc++ -lm -lgcc -lc -lgcc" - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path="-L/usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2 -L/usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../.." - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method="pass_all" - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd="\$MAGIC_CMD" - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag="" - -# Flag that forces no undefined symbols. -no_undefined_flag="" - -# Commands used to finish a libtool library installation in a directory. -finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval="" - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW][ABCDGISTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" - -# This is the shared library runtime path variable. -runpath_var=LD_RUN_PATH - -# This is the shared library path variable. -shlibpath_var=LD_LIBRARY_PATH - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=no - -# How to hardcode a shared library path into an executable. -hardcode_action=immediate - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=yes - -# Flag to hardcode $libdir into a binary during linking. -# This must work even if $libdir does not exist. -hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" - -# If ld is used when linking, flag to hardcode $libdir into -# a binary during linking. This must work even if $libdir does -# not exist. -hardcode_libdir_flag_spec_ld="" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="" - -# Set to yes if using DIR/libNAME during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=no - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=no - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var= - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=no - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=unknown - -# Compile-time system search path for libraries -sys_lib_search_path_spec=" /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/lib/gcc/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linu! x-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /lib/i686-pc-linux-gnu/3.2/ /lib/ /usr/lib/i686-pc-linux-gnu/3.2/ /usr/lib/" - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib" - -# Fix the shell variable $srcfile for the compiler. -fix_srcfile_path="" - -# Set to yes if exported symbols are required. -always_export_symbols=no - -# The commands to list exported symbols. -export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds="" - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms="" - -# Symbols that must always be exported. -include_expsyms="" - -# ### END LIBTOOL TAG CONFIG: CXX - -# ### BEGIN LIBTOOL TAG CONFIG: F77 - -# Libtool was configured on host apoc.cs.uiuc.edu: - -# Shell to use when invoking shell scripts. -SHELL="/bin/sh" - -# Whether or not to build shared libraries. -build_libtool_libs=yes - -# Whether or not to build static libraries. -build_old_libs=yes - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=no - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=no - -# Whether or not to optimize for fast installation. -fast_install=yes - -# The host system. -host_alias= -host=i686-pc-linux-gnu - -# An echo program that does not interpret backslashes. -echo="echo" - -# The archiver. -AR="ar" -AR_FLAGS="cru" - -# A C compiler. -LTCC="gcc" - -# A language-specific compiler. -CC="g77" - -# Is the compiler the GNU C compiler? -with_gcc=yes - -# An ERE matcher. -EGREP="grep -E" - -# The linker used to build libraries. -LD="/usr/bin/ld" - -# Whether we need hard or soft links. -LN_S="ln -s" - -# A BSD-compatible nm program. -NM="/usr/bin/nm -B" - -# A symbol stripping program -STRIP=strip - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=file - -# Used on cygwin: DLL creation program. -DLLTOOL="dlltool" - -# Used on cygwin: object dumper. -OBJDUMP="objdump" - -# Used on cygwin: assembler. -AS="as" - -# The name of the directory that contains temporary libtool files. -objdir=.libs - -# How to create reloadable object files. -reload_flag=" -r" -reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" - -# How to pass a linker flag through the compiler. -wl="-Wl," - -# Object file suffix (normally "o"). -objext="o" - -# Old archive suffix (normally "a"). -libext="a" - -# Shared library suffix (normally ".so"). -shrext='.so' - -# Executable file suffix (normally ""). -exeext="" - -# Additional compiler flags for building library objects. -pic_flag=" -fPIC" -pic_mode=default - -# What is the maximum length of a command? -max_cmd_len=32768 - -# Does compiler simultaneously support -c and -o options? -compiler_c_o="yes" - -# Must we lock files when doing compilation ? -need_locks="no" - -# Do we need the lib prefix for modules? -need_lib_prefix=no - -# Do we need a version for libraries? -need_version=no - -# Whether dlopen is supported. -dlopen_support=unknown - -# Whether dlopen of programs is supported. -dlopen_self=unknown - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=unknown - -# Compiler flag to prevent dynamic linking. -link_static_flag="-static" - -# Compiler flag to turn off builtin functions. -no_builtin_flag="" - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec="\${wl}--export-dynamic" - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec="" - -# Library versioning type. -version_type=linux - -# Format of library name prefix. -libname_spec="lib\$name" - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" - -# The coded name of the library, if different from the real name. -soname_spec="\${libname}\${release}\${shared_ext}\$major" - -# Commands used to build and install an old-style archive. -RANLIB="ranlib" -old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" -old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" -old_postuninstall_cmds="" - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds="" - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds="" - -# Commands used to build and install a shared archive. -archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" -archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" -postinstall_cmds="" -postuninstall_cmds="" - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds="" -module_expsym_cmds="" - -# Commands to strip libraries. -old_striplib="strip --strip-debug" -striplib="strip --strip-unneeded" - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects="" - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps="" - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path="" - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method="pass_all" - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd="\$MAGIC_CMD" - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag="" - -# Flag that forces no undefined symbols. -no_undefined_flag="" - -# Commands used to finish a libtool library installation in a directory. -finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval="" - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW][ABCDGISTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" - -# This is the shared library runtime path variable. -runpath_var=LD_RUN_PATH - -# This is the shared library path variable. -shlibpath_var=LD_LIBRARY_PATH - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=no - -# How to hardcode a shared library path into an executable. -hardcode_action=immediate - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=yes - -# Flag to hardcode $libdir into a binary during linking. -# This must work even if $libdir does not exist. -hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" - -# If ld is used when linking, flag to hardcode $libdir into -# a binary during linking. This must work even if $libdir does -# not exist. -hardcode_libdir_flag_spec_ld="" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="" - -# Set to yes if using DIR/libNAME during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=no - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=no - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=unsupported - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=no - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=unknown - -# Compile-time system search path for libraries -sys_lib_search_path_spec=" /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/lib/gcc/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linu! x-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /lib/i686-pc-linux-gnu/3.2/ /lib/ /usr/lib/i686-pc-linux-gnu/3.2/ /usr/lib/" - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib" - -# Fix the shell variable $srcfile for the compiler. -fix_srcfile_path="" - -# Set to yes if exported symbols are required. -always_export_symbols=no - -# The commands to list exported symbols. -export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds="" - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" - -# Symbols that must always be exported. -include_expsyms="" - -# ### END LIBTOOL TAG CONFIG: F77 - +mklib +Makefile.config +config.log +config.status +cvs.out From lattner at cs.uiuc.edu Mon Aug 4 00:01:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:04 2003 Subject: [llvm-commits] CVS: llvm/include/Config/.cvsignore Message-ID: <200308031831.NAA05131@apoc.cs.uiuc.edu> Changes in directory llvm/include/Config: .cvsignore added (r1.1) --- Log message: CVS, please don't tell us that we have a new config.h file, everyone knows that. --- Diffs of the changes: Index: llvm/include/Config/.cvsignore diff -c /dev/null llvm/include/Config/.cvsignore:1.1 *** /dev/null Sun Aug 3 13:31:48 2003 --- llvm/include/Config/.cvsignore Sun Aug 3 13:31:38 2003 *************** *** 0 **** --- 1 ---- + config.h From lattner at cs.uiuc.edu Mon Aug 4 00:01:09 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:09 2003 Subject: [llvm-commits] CVS: llvm/.cvsignore Message-ID: <200308031832.NAA05158@apoc.cs.uiuc.edu> Changes in directory llvm: .cvsignore added (r1.1) --- Log message: We know we have a mklib file, ignore it please CVS! --- Diffs of the changes: Index: llvm/.cvsignore diff -c /dev/null llvm/.cvsignore:1.1 *** /dev/null Sun Aug 3 13:32:20 2003 --- llvm/.cvsignore Sun Aug 3 13:32:10 2003 *************** *** 0 **** --- 1,7227 ---- + #! /bin/sh + + # mklibT - Provide generalized library-building support services. + # Generated automatically by (GNU ) + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 + # Free Software Foundation, Inc. + # + # This file is part of GNU Libtool: + # Originally by Gordon Matzigkeit , 1996 + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + # General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + # + # As a special exception to the GNU General Public License, if you + # distribute this file as part of a program that contains a + # configuration script generated by Autoconf, you may include it under + # the same distribution terms that you use for the rest of that program. + + # A sed program that does not truncate output. + SED="/bin/sed" + + # Sed that helps us avoid accidentally triggering echo(1) options like -n. + Xsed="/bin/sed -e s/^X//" + + # The HP-UX ksh and POSIX shell print the target directory to stdout + # if CDPATH is set. + if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + + # The names of the tagged configurations supported by this script. + available_tags=" CXX F77" + + # ### BEGIN LIBTOOL CONFIG + + # Libtool was configured on host apoc.cs.uiuc.edu: + + # Shell to use when invoking shell scripts. + SHELL="/bin/sh" + + # Whether or not to build shared libraries. + build_libtool_libs=yes + + # Whether or not to build static libraries. + build_old_libs=yes + + # Whether or not to add -lc for building shared libraries. + build_libtool_need_lc=no + + # Whether or not to disallow shared libs when runtime libs are static + allow_libtool_libs_with_static_runtimes=no + + # Whether or not to optimize for fast installation. + fast_install=yes + + # The host system. + host_alias= + host=i686-pc-linux-gnu + + # An echo program that does not interpret backslashes. + echo="echo" + + # The archiver. + AR="ar" + AR_FLAGS="cru" + + # A C compiler. + LTCC="gcc" + + # A language-specific compiler. + CC="gcc" + + # Is the compiler the GNU C compiler? + with_gcc=yes + + # An ERE matcher. + EGREP="grep -E" + + # The linker used to build libraries. + LD="/usr/bin/ld" + + # Whether we need hard or soft links. + LN_S="ln -s" + + # A BSD-compatible nm program. + NM="/usr/bin/nm -B" + + # A symbol stripping program + STRIP=strip + + # Used to examine libraries when file_magic_cmd begins "file" + MAGIC_CMD=file + + # Used on cygwin: DLL creation program. + DLLTOOL="dlltool" + + # Used on cygwin: object dumper. + OBJDUMP="objdump" + + # Used on cygwin: assembler. + AS="as" + + # The name of the directory that contains temporary libtool files. + objdir=.libs + + # How to create reloadable object files. + reload_flag=" -r" + reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + + # How to pass a linker flag through the compiler. + wl="-Wl," + + # Object file suffix (normally "o"). + objext="o" + + # Old archive suffix (normally "a"). + libext="a" + + # Shared library suffix (normally ".so"). + shrext='.so' + + # Executable file suffix (normally ""). + exeext="" + + # Additional compiler flags for building library objects. + pic_flag=" -fPIC -DPIC" + pic_mode=default + + # What is the maximum length of a command? + max_cmd_len=32768 + + # Does compiler simultaneously support -c and -o options? + compiler_c_o="yes" + + # Must we lock files when doing compilation ? + need_locks="no" + + # Do we need the lib prefix for modules? + need_lib_prefix=no + + # Do we need a version for libraries? + need_version=no + + # Whether dlopen is supported. + dlopen_support=unknown + + # Whether dlopen of programs is supported. + dlopen_self=unknown + + # Whether dlopen of statically linked programs is supported. + dlopen_self_static=unknown + + # Compiler flag to prevent dynamic linking. + link_static_flag="-static" + + # Compiler flag to turn off builtin functions. + no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions" + + # Compiler flag to allow reflexive dlopens. + export_dynamic_flag_spec="\${wl}--export-dynamic" + + # Compiler flag to generate shared objects directly from archives. + whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + + # Compiler flag to generate thread-safe objects. + thread_safe_flag_spec="" + + # Library versioning type. + version_type=linux + + # Format of library name prefix. + libname_spec="lib\$name" + + # List of archive names. First name is the real one, the rest are links. + # The last name is the one that the linker finds with -lNAME. + library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + + # The coded name of the library, if different from the real name. + soname_spec="\${libname}\${release}\${shared_ext}\$major" + + # Commands used to build and install an old-style archive. + RANLIB="ranlib" + old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" + old_postuninstall_cmds="" + + # Create an old-style archive from a shared archive. + old_archive_from_new_cmds="" + + # Create a temporary old-style archive to link instead of a shared archive. + old_archive_from_expsyms_cmds="" + + # Commands used to build and install a shared archive. + archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" + archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" + postinstall_cmds="" + postuninstall_cmds="" + + # Commands used to build a loadable module (assumed same as above if empty) + module_cmds="" + module_expsym_cmds="" + + # Commands to strip libraries. + old_striplib="strip --strip-debug" + striplib="strip --strip-unneeded" + + # Dependencies to place before the objects being linked to create a + # shared library. + predep_objects="" + + # Dependencies to place after the objects being linked to create a + # shared library. + postdep_objects="" + + # Dependencies to place before the objects being linked to create a + # shared library. + predeps="" + + # Dependencies to place after the objects being linked to create a + # shared library. + postdeps="" + + # The library search path used internally by the compiler when linking + # a shared library. + compiler_lib_search_path="" + + # Method to check whether dependent libraries are shared objects. + deplibs_check_method="pass_all" + + # Command to use when deplibs_check_method == file_magic. + file_magic_cmd="\$MAGIC_CMD" + + # Flag that allows shared libraries with undefined symbols to be built. + allow_undefined_flag="" + + # Flag that forces no undefined symbols. + no_undefined_flag="" + + # Commands used to finish a libtool library installation in a directory. + finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + + # Same as above, but a single script fragment to be evaled but not shown. + finish_eval="" + + # Take the output of nm and produce a listing of raw symbols and C names. + global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW][ABCDGISTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" + + # Transform the output of nm in a proper C declaration + global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + + # Transform the output of nm in a C name address pair + global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + + # This is the shared library runtime path variable. + runpath_var=LD_RUN_PATH + + # This is the shared library path variable. + shlibpath_var=LD_LIBRARY_PATH + + # Is shlibpath searched before the hard-coded library search path? + shlibpath_overrides_runpath=no + + # How to hardcode a shared library path into an executable. + hardcode_action=immediate + + # Whether we should hardcode library paths into libraries. + hardcode_into_libs=yes + + # Flag to hardcode $libdir into a binary during linking. + # This must work even if $libdir does not exist. + hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + + # If ld is used when linking, flag to hardcode $libdir into + # a binary during linking. This must work even if $libdir does + # not exist. + hardcode_libdir_flag_spec_ld="" + + # Whether we need a single -rpath flag with a separated argument. + hardcode_libdir_separator="" + + # Set to yes if using DIR/libNAME during linking hardcodes DIR into the + # resulting binary. + hardcode_direct=no + + # Set to yes if using the -LDIR flag during linking hardcodes DIR into the + # resulting binary. + hardcode_minus_L=no + + # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into + # the resulting binary. + hardcode_shlibpath_var=unsupported + + # Set to yes if building a shared library automatically hardcodes DIR into the library + # and all subsequent libraries and executables linked against it. + hardcode_automatic=no + + # Variables whose values should be saved in libtool wrapper scripts and + # restored at relink time. + variables_saved_for_relink="PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + + # Whether libtool must link a program against all its dependency libraries. + link_all_deplibs=unknown + + # Compile-time system search path for libraries + sys_lib_search_path_spec=" /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/lib/gcc/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-lin! ux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /lib/i686-pc-linux-gnu/3.2/ /lib/ /usr/lib/i686-pc-linux-gnu/3.2/ /usr/lib/" + + # Run-time system search path for libraries + sys_lib_dlsearch_path_spec="/lib /usr/lib" + + # Fix the shell variable $srcfile for the compiler. + fix_srcfile_path="" + + # Set to yes if exported symbols are required. + always_export_symbols=no + + # The commands to list exported symbols. + export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + + # The commands to extract the exported symbol list from a shared archive. + extract_expsyms_cmds="" + + # Symbols that should not be listed in the preloaded symbols. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + + # Symbols that must always be exported. + include_expsyms="" + + # ### END LIBTOOL CONFIG + + # ltmain.sh - Provide generalized library-building support services. + # NOTE: Changing this file will not affect anything until you rerun configure. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 + # Free Software Foundation, Inc. + # Originally by Gordon Matzigkeit , 1996 + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + # General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + # + # As a special exception to the GNU General Public License, if you + # distribute this file as part of a program that contains a + # configuration script generated by Autoconf, you may include it under + # the same distribution terms that you use for the rest of that program. + + # Check that we have a working $echo. + if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : + elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : + else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} + fi + + if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + fi + + # Global variables. + mode=$default_mode + nonopt= + prev= + prevopt= + run= + show="$echo" + show_help= + execute_dlfiles= + lo2o="s/\\.lo\$/.${objext}/" + o2lo="s/\\.${objext}\$/.lo/" + + ##################################### + # Shell function definitions: + # This seems to be the best place for them + + # Need a lot of goo to handle *both* DLLs and import libs + # Has to be a shell function in order to 'eat' the argument + # that is supplied when $file_magic_command is called. + win32_libid () { + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` + if test "X$win32_nmres" = "Ximport" ; then + win32_libid_type="x86 archive import" + else + win32_libid_type="x86 archive static" + fi + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type + } + + # End of Shell function definitions + ##################################### + + # Parse our command line options once, thoroughly. + while test "$#" -gt 0 + do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit 1 + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2003 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit 0 + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0" + done + exit 0 + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + ;; + + --tag) prevopt="--tag" prev=tag ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac + done + + if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # If this variable is set in any of the actions, the command in it + # will be execed at the end. This prevents here-documents from being + # left over by shells. + exec_cmd= + + if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_output= + arg_mode=normal + libobj= + + for arg + do + case "$arg_mode" in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + arg_mode=target + continue + ;; + + -static) + build_old_libs=yes + continue + ;; + + -only-static) + build_libtool_libs=no + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit 1 + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + # Infer tagged configuration to use if any are available and + # if one wasn't chosen via the "--tag" command line option. + # Only attempt this if the compiler in the base compile + # command doesn't match the default compiler. + if test -n "$available_tags" && test -z "$tagname"; then + case $base_compile in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" + case "$base_compile " in + "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit 1 + # else + # $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi + + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ + *** ERROR, $lockfile exists and contains: + `cat $lockfile 2>/dev/null` + + This indicates that another process is trying to use the same + temporary object file, and libtool could not work around it because + your compiler does not support \`-c' and \`-o' together. If you + repeat this compilation, it may succeed, by chance, but you had better + avoid parallel builds (make -j) in this platform, or get a better + compiler." + + $run $rm $removelist + exit 1 + fi + $echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ + *** ERROR, $lockfile contains: + `cat $lockfile 2>/dev/null` + + but it should contain: + $srcfile + + This indicates that another process is trying to use the same + temporary object file, and libtool could not work around it because + your compiler does not support \`-c' and \`-o' together. If you + repeat this compilation, it may succeed, by chance, but you had better + avoid parallel builds (make -j) in this platform, or get a better + compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ + *** ERROR, $lockfile contains: + `cat $lockfile 2>/dev/null` + + but it should contain: + $srcfile + + This indicates that another process is trying to use the same + temporary object file, and libtool could not work around it because + your compiler does not support \`-c' and \`-o' together. If you + repeat this compilation, it may succeed, by chance, but you had better + avoid parallel builds (make -j) in this platform, or get a better + compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + base_compile="$base_compile $arg" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do + # moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit 1 + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit 1 + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit 1 + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # gcc -m* arguments should be passed to the linker via $compiler_flags + # in order to pass architecture information to the linker + # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo + # but this is not reliable with gcc because gcc may use -mfoo to + # select a different linker, different libraries, etc, while + # -Wl,-mfoo simply passes -mfoo to the linker. + -m*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + if test "$with_gcc" = "yes" ; then + compiler_flags="$compiler_flags $arg" + fi + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit 1 + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit 1 + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Infer tagged configuration to use if any are available and + # if one wasn't chosen via the "--tag" command line option. + # Only attempt this if the compiler in the base link + # command doesn't match the default compiler. + if test -n "$available_tags" && test -z "$tagname"; then + case $base_compile in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`" + case $base_compile in + "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) + # The compiler in $compile_command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit 1 + # else + # $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test "$status" -ne 0 && test ! -d "$output_objdir"; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplcations in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5* ) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against it, someone + # is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + newlib_search_path="$newlib_search_path $path" + path="" + fi + ;; + *) + path="-L$path" + ;; + esac + + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$deplibs $depdepl" ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$xdir"; then + exit $status + fi + # We will extract separately just the conflicting names and we will no + # longer touch any unique names. It is faster to leave these extract + # automatically by $AR in one run. + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + + libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval cmds=\"$module_expsym_cmds\" + else + eval cmds=\"$module_cmds\" + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + fi + + if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$save_output-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$save_output-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$save_output-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadale object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$save_output-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$xdir"; then + exit $status + fi + # We will extract separately just the conflicting names and we will no + # longer touch any unique names. It is faster to leave these extract + # automatically by $AR in one run. + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + + reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ + /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ + /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + + #ifdef __cplusplus + extern \"C\" { + #endif + + /* Prevent the only kind of declaration conflicts we can make. */ + #define lt_preloaded_symbols some_other_symbol + + /* External symbol declarations for the compiler. */\ + " + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + + #undef lt_preloaded_symbols + + #if defined (__STDC__) && __STDC__ + # define lt_ptr void * + #else + # define lt_ptr char * + # define const + #endif + + /* The mapping between symbol names and symbols. */ + const struct { + const char *name; + lt_ptr address; + } + lt_preloaded_symbols[] = + {\ + " + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} + }; + + /* This works around a problem in FreeBSD linker */ + #ifdef FREEBSD_WORKAROUND + static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; + } + #endif + + #ifdef __cplusplus + } + #endif\ + " + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + cwrappersource=`$echo ${objdir}/lt-${output}.c` + cwrapper=`$echo ${output}.exe` + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" + #include + #include + #include + #include + #include + #include + + #if defined(PATH_MAX) + # define LT_PATHMAX PATH_MAX + #elif defined(MAXPATHLEN) + # define LT_PATHMAX MAXPATHLEN + #else + # define LT_PATHMAX 1024 + #endif + + #ifndef DIR_SEPARATOR + #define DIR_SEPARATOR '/' + #endif + + #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) + #define HAVE_DOS_BASED_FILE_SYSTEM + #ifndef DIR_SEPARATOR_2 + #define DIR_SEPARATOR_2 '\\' + #endif + #endif + + #ifndef DIR_SEPARATOR_2 + # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) + #else /* DIR_SEPARATOR_2 */ + # define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) + #endif /* DIR_SEPARATOR_2 */ + + #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) + #define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ + } while (0) + + const char *program_name = NULL; + + void * xmalloc (size_t num); + char * xstrdup (const char *string); + char * basename (const char *name); + char * fnqualify(const char *path); + char * strendzap(char *str, const char *pat); + void lt_fatal (const char *message, ...); + + int + main (int argc, char *argv[]) + { + char **newargz; + int i; + + program_name = (char *) xstrdup ((char *) basename (argv[0])); + newargz = XMALLOC(char *, argc+2); + EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = fnqualify(argv[0]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + } + + void * + xmalloc (size_t num) + { + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; + } + + char * + xstrdup (const char *string) + { + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL + ; + } + + char * + basename (const char *name) + { + const char *base; + + #if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha (name[0]) && name[1] == ':') + name += 2; + #endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return (char *) base; + } + + char * + fnqualify(const char *path) + { + size_t size; + char *p; + char tmp[LT_PATHMAX + 1]; + + assert(path != NULL); + + /* Is it qualified already? */ + #if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha (path[0]) && path[1] == ':') + return xstrdup (path); + #endif + if (IS_DIR_SEPARATOR (path[0])) + return xstrdup (path); + + /* prepend the current directory */ + /* doesn't handle '~' */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ + p = XMALLOC(char, size); + sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); + return p; + } + + char * + strendzap(char *str, const char *pat) + { + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; + } + + static void + lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) + { + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); + } + + void + lt_fatal (const char *message, ...) + { + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); + } + EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ + #! $SHELL + + # $output - temporary wrapper script for $objdir/$outputname + # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP + # + # The $output program cannot be directly executed until all the libtool + # libraries that it depends on are installed. + # + # This wrapper script should never be moved out of the build directory. + # If it is, it will not operate correctly. + + # Sed substitution that helps us do robust quoting. It backslashifies + # metacharacters that are still active within double-quoted strings. + Xsed='${SED} -e 1s/^X//' + sed_quote_subst='$sed_quote_subst' + + # The HP-UX ksh and POSIX shell print the target directory to stdout + # if CDPATH is set. + if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + + relink_command=\"$relink_command\" + + # This environment variable determines our operation mode. + if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' + else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ + " + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" + " + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" + " + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var + " + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH + " + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + " + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} + " + ;; + + *) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} + " + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi + fi\ + " + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "$mkdir $xdir" + $run $mkdir "$xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$xdir"; then + exit $status + fi + # We will extract separately just the conflicting names and we will no + # longer touch any unique names. It is faster to leave these extract + # automatically by $AR in one run. + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + # GNU ar 2.10+ was changed to match POSIX; thus no paths are + # encoded into archives. This makes 'ar r' malfunction in + # this piecewise linking case whenever conflicting object + # names appear in distinct ar calls; check, warn and compensate. + if (for obj in $save_oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2 + $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2 + AR_FLAGS=cq + fi + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ + # $outputname - a libtool library file + # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP + # + # Please DO NOT delete this file! + # It is necessary for linking the library. + + # The name that we can dlopen(3). + dlname='$tdlname' + + # Names of this library. + library_names='$library_names' + + # The name of the static archive. + old_library='$old_library' + + # Libraries that this one depends upon. + dependency_libs='$dependency_libs' + + # Version information for $libname. + current=$current + age=$age + revision=$revision + + # Is this an already installed library? + installed=$installed + + # Should we warn about portability when linking against -modules? + shouldnotlink=$module + + # Files to dlopen/dlpreopen + dlopen='$dlfiles' + dlpreopen='$dlprefiles' + + # Directory that this library needs to be installed in: + libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ + relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit 1 + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit 0 + + $echo "----------------------------------------------------------------------" + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test "$mode" = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi + fi # test -z "$show_help" + + if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 + fi + + # We need to display help for each of the modes. + case $mode in + "") $echo \ + "Usage: $modename [OPTION]... [MODE-ARG]... + + Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + + MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + + MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for + a more detailed description of MODE. + + Report bugs to ." + exit 0 + ;; + + clean) + $echo \ + "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + + Remove files from the build directory. + + RM is the name of the program to use to delete files associated with each FILE + (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed + to RM. + + If FILE is a libtool library, object or program, all the files associated + with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $echo \ + "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + + Compile a source file into a libtool library object. + + This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + + COMPILE-COMMAND is a command to be used in creating a \`standard' object file + from the given SOURCEFILE. + + The output file name is determined by removing the directory component from + SOURCEFILE, then substituting the C source code suffix \`.c' with the + library object suffix, \`.lo'." + ;; + + execute) + $echo \ + "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + + Automatically set library path, then run a program. + + This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + + This mode sets the library path environment variable according to \`-dlopen' + flags. + + If any of the ARGS are libtool executable wrappers, then they are translated + into their corresponding uninstalled binary, and any of their required library + directories are added to the library path. + + Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $echo \ + "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + + Complete the installation of libtool libraries. + + Each LIBDIR is a directory that contains libtool libraries. + + The commands that this mode executes may require superuser privileges. Use + the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $echo \ + "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + + Install executables or libraries. + + INSTALL-COMMAND is the installation command. The first component should be + either the \`install' or \`cp' program. + + The rest of the components are interpreted as arguments to that command (only + BSD-compatible install options are recognized)." + ;; + + link) + $echo \ + "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + + Link object files or libraries together to form another library, or to + create an executable program. + + LINK-COMMAND is a command using the C compiler that you would use to create + a program from several object files. + + The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + + All other options (arguments beginning with \`-') are ignored. + + Every other argument is treated as a filename. Files ending in \`.la' are + treated as uninstalled libtool libraries, other files are standard or library + object files. + + If the OUTPUT-FILE ends in \`.la', then a libtool library is created, + only library objects (\`.lo' files) may be specified, and \`-rpath' is + required, except when creating a convenience library. + + If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created + using \`ar' and \`ranlib', or on Windows using \`lib'. + + If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file + is created, otherwise an executable program is created." + ;; + + uninstall) + $echo \ + "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + + Remove libraries from an installation directory. + + RM is the name of the program to use to delete files associated with each FILE + (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed + to RM. + + If FILE is a libtool library, all the files associated with it are deleted. + Otherwise, only FILE itself is deleted using RM." + ;; + + *) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + $echo + $echo "Try \`$modename --help' for more information about other modes." + + exit 0 + + # The TAGs below are defined such that we never get into a situation + # in which we disable both kinds of libraries. Given conflicting + # choices, we go for a static library, that is the most portable, + # since we can't tell whether shared libraries were disabled because + # the user asked for that or because the platform doesn't support + # them. This is particularly important on AIX, because we don't + # support having both static and shared libraries enabled at the same + # time on that platform, so we default to a shared-only configuration. + # If a disable-shared tag is given, we'll fallback to a static-only + # configuration. But we'll never go from static-only to shared-only. + + # ### BEGIN LIBTOOL TAG CONFIG: disable-shared + build_libtool_libs=no + build_old_libs=yes + # ### END LIBTOOL TAG CONFIG: disable-shared + + # ### BEGIN LIBTOOL TAG CONFIG: disable-static + build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` + # ### END LIBTOOL TAG CONFIG: disable-static + + # Local Variables: + # mode:shell-script + # sh-indentation:2 + # End: + # ### BEGIN LIBTOOL TAG CONFIG: CXX + + # Libtool was configured on host apoc.cs.uiuc.edu: + + # Shell to use when invoking shell scripts. + SHELL="/bin/sh" + + # Whether or not to build shared libraries. + build_libtool_libs=yes + + # Whether or not to build static libraries. + build_old_libs=yes + + # Whether or not to add -lc for building shared libraries. + build_libtool_need_lc=no + + # Whether or not to disallow shared libs when runtime libs are static + allow_libtool_libs_with_static_runtimes=no + + # Whether or not to optimize for fast installation. + fast_install=yes + + # The host system. + host_alias= + host=i686-pc-linux-gnu + + # An echo program that does not interpret backslashes. + echo="echo" + + # The archiver. + AR="ar" + AR_FLAGS="cru" + + # A C compiler. + LTCC="gcc" + + # A language-specific compiler. + CC="g++" + + # Is the compiler the GNU C compiler? + with_gcc=yes + + # An ERE matcher. + EGREP="grep -E" + + # The linker used to build libraries. + LD="/usr/bin/ld" + + # Whether we need hard or soft links. + LN_S="ln -s" + + # A BSD-compatible nm program. + NM="/usr/bin/nm -B" + + # A symbol stripping program + STRIP=strip + + # Used to examine libraries when file_magic_cmd begins "file" + MAGIC_CMD=file + + # Used on cygwin: DLL creation program. + DLLTOOL="dlltool" + + # Used on cygwin: object dumper. + OBJDUMP="objdump" + + # Used on cygwin: assembler. + AS="as" + + # The name of the directory that contains temporary libtool files. + objdir=.libs + + # How to create reloadable object files. + reload_flag=" -r" + reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + + # How to pass a linker flag through the compiler. + wl="-Wl," + + # Object file suffix (normally "o"). + objext="o" + + # Old archive suffix (normally "a"). + libext="a" + + # Shared library suffix (normally ".so"). + shrext='.so' + + # Executable file suffix (normally ""). + exeext="" + + # Additional compiler flags for building library objects. + pic_flag=" -fPIC -DPIC" + pic_mode=default + + # What is the maximum length of a command? + max_cmd_len=32768 + + # Does compiler simultaneously support -c and -o options? + compiler_c_o="yes" + + # Must we lock files when doing compilation ? + need_locks="no" + + # Do we need the lib prefix for modules? + need_lib_prefix=no + + # Do we need a version for libraries? + need_version=no + + # Whether dlopen is supported. + dlopen_support=unknown + + # Whether dlopen of programs is supported. + dlopen_self=unknown + + # Whether dlopen of statically linked programs is supported. + dlopen_self_static=unknown + + # Compiler flag to prevent dynamic linking. + link_static_flag="-static" + + # Compiler flag to turn off builtin functions. + no_builtin_flag=" -fno-builtin" + + # Compiler flag to allow reflexive dlopens. + export_dynamic_flag_spec="\${wl}--export-dynamic" + + # Compiler flag to generate shared objects directly from archives. + whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + + # Compiler flag to generate thread-safe objects. + thread_safe_flag_spec="" + + # Library versioning type. + version_type=linux + + # Format of library name prefix. + libname_spec="lib\$name" + + # List of archive names. First name is the real one, the rest are links. + # The last name is the one that the linker finds with -lNAME. + library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + + # The coded name of the library, if different from the real name. + soname_spec="\${libname}\${release}\${shared_ext}\$major" + + # Commands used to build and install an old-style archive. + RANLIB="ranlib" + old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" + old_postuninstall_cmds="" + + # Create an old-style archive from a shared archive. + old_archive_from_new_cmds="" + + # Create a temporary old-style archive to link instead of a shared archive. + old_archive_from_expsyms_cmds="" + + # Commands used to build and install a shared archive. + archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" + archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" + postinstall_cmds="" + postuninstall_cmds="" + + # Commands used to build a loadable module (assumed same as above if empty) + module_cmds="" + module_expsym_cmds="" + + # Commands to strip libraries. + old_striplib="strip --strip-debug" + striplib="strip --strip-unneeded" + + # Dependencies to place before the objects being linked to create a + # shared library. + predep_objects="/usr/lib/crti.o /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/crtbeginS.o" + + # Dependencies to place after the objects being linked to create a + # shared library. + postdep_objects="/usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/crtendS.o /usr/lib/crtn.o" + + # Dependencies to place before the objects being linked to create a + # shared library. + predeps="" + + # Dependencies to place after the objects being linked to create a + # shared library. + postdeps="-lstdc++ -lm -lgcc -lc -lgcc" + + # The library search path used internally by the compiler when linking + # a shared library. + compiler_lib_search_path="-L/usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2 -L/usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../.." + + # Method to check whether dependent libraries are shared objects. + deplibs_check_method="pass_all" + + # Command to use when deplibs_check_method == file_magic. + file_magic_cmd="\$MAGIC_CMD" + + # Flag that allows shared libraries with undefined symbols to be built. + allow_undefined_flag="" + + # Flag that forces no undefined symbols. + no_undefined_flag="" + + # Commands used to finish a libtool library installation in a directory. + finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + + # Same as above, but a single script fragment to be evaled but not shown. + finish_eval="" + + # Take the output of nm and produce a listing of raw symbols and C names. + global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW][ABCDGISTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" + + # Transform the output of nm in a proper C declaration + global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + + # Transform the output of nm in a C name address pair + global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + + # This is the shared library runtime path variable. + runpath_var=LD_RUN_PATH + + # This is the shared library path variable. + shlibpath_var=LD_LIBRARY_PATH + + # Is shlibpath searched before the hard-coded library search path? + shlibpath_overrides_runpath=no + + # How to hardcode a shared library path into an executable. + hardcode_action=immediate + + # Whether we should hardcode library paths into libraries. + hardcode_into_libs=yes + + # Flag to hardcode $libdir into a binary during linking. + # This must work even if $libdir does not exist. + hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + + # If ld is used when linking, flag to hardcode $libdir into + # a binary during linking. This must work even if $libdir does + # not exist. + hardcode_libdir_flag_spec_ld="" + + # Whether we need a single -rpath flag with a separated argument. + hardcode_libdir_separator="" + + # Set to yes if using DIR/libNAME during linking hardcodes DIR into the + # resulting binary. + hardcode_direct=no + + # Set to yes if using the -LDIR flag during linking hardcodes DIR into the + # resulting binary. + hardcode_minus_L=no + + # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into + # the resulting binary. + hardcode_shlibpath_var= + + # Set to yes if building a shared library automatically hardcodes DIR into the library + # and all subsequent libraries and executables linked against it. + hardcode_automatic=no + + # Variables whose values should be saved in libtool wrapper scripts and + # restored at relink time. + variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + + # Whether libtool must link a program against all its dependency libraries. + link_all_deplibs=unknown + + # Compile-time system search path for libraries + sys_lib_search_path_spec=" /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/lib/gcc/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-lin! ux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /lib/i686-pc-linux-gnu/3.2/ /lib/ /usr/lib/i686-pc-linux-gnu/3.2/ /usr/lib/" + + # Run-time system search path for libraries + sys_lib_dlsearch_path_spec="/lib /usr/lib" + + # Fix the shell variable $srcfile for the compiler. + fix_srcfile_path="" + + # Set to yes if exported symbols are required. + always_export_symbols=no + + # The commands to list exported symbols. + export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + + # The commands to extract the exported symbol list from a shared archive. + extract_expsyms_cmds="" + + # Symbols that should not be listed in the preloaded symbols. + exclude_expsyms="" + + # Symbols that must always be exported. + include_expsyms="" + + # ### END LIBTOOL TAG CONFIG: CXX + + # ### BEGIN LIBTOOL TAG CONFIG: F77 + + # Libtool was configured on host apoc.cs.uiuc.edu: + + # Shell to use when invoking shell scripts. + SHELL="/bin/sh" + + # Whether or not to build shared libraries. + build_libtool_libs=yes + + # Whether or not to build static libraries. + build_old_libs=yes + + # Whether or not to add -lc for building shared libraries. + build_libtool_need_lc=no + + # Whether or not to disallow shared libs when runtime libs are static + allow_libtool_libs_with_static_runtimes=no + + # Whether or not to optimize for fast installation. + fast_install=yes + + # The host system. + host_alias= + host=i686-pc-linux-gnu + + # An echo program that does not interpret backslashes. + echo="echo" + + # The archiver. + AR="ar" + AR_FLAGS="cru" + + # A C compiler. + LTCC="gcc" + + # A language-specific compiler. + CC="g77" + + # Is the compiler the GNU C compiler? + with_gcc=yes + + # An ERE matcher. + EGREP="grep -E" + + # The linker used to build libraries. + LD="/usr/bin/ld" + + # Whether we need hard or soft links. + LN_S="ln -s" + + # A BSD-compatible nm program. + NM="/usr/bin/nm -B" + + # A symbol stripping program + STRIP=strip + + # Used to examine libraries when file_magic_cmd begins "file" + MAGIC_CMD=file + + # Used on cygwin: DLL creation program. + DLLTOOL="dlltool" + + # Used on cygwin: object dumper. + OBJDUMP="objdump" + + # Used on cygwin: assembler. + AS="as" + + # The name of the directory that contains temporary libtool files. + objdir=.libs + + # How to create reloadable object files. + reload_flag=" -r" + reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + + # How to pass a linker flag through the compiler. + wl="-Wl," + + # Object file suffix (normally "o"). + objext="o" + + # Old archive suffix (normally "a"). + libext="a" + + # Shared library suffix (normally ".so"). + shrext='.so' + + # Executable file suffix (normally ""). + exeext="" + + # Additional compiler flags for building library objects. + pic_flag=" -fPIC" + pic_mode=default + + # What is the maximum length of a command? + max_cmd_len=32768 + + # Does compiler simultaneously support -c and -o options? + compiler_c_o="yes" + + # Must we lock files when doing compilation ? + need_locks="no" + + # Do we need the lib prefix for modules? + need_lib_prefix=no + + # Do we need a version for libraries? + need_version=no + + # Whether dlopen is supported. + dlopen_support=unknown + + # Whether dlopen of programs is supported. + dlopen_self=unknown + + # Whether dlopen of statically linked programs is supported. + dlopen_self_static=unknown + + # Compiler flag to prevent dynamic linking. + link_static_flag="-static" + + # Compiler flag to turn off builtin functions. + no_builtin_flag="" + + # Compiler flag to allow reflexive dlopens. + export_dynamic_flag_spec="\${wl}--export-dynamic" + + # Compiler flag to generate shared objects directly from archives. + whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + + # Compiler flag to generate thread-safe objects. + thread_safe_flag_spec="" + + # Library versioning type. + version_type=linux + + # Format of library name prefix. + libname_spec="lib\$name" + + # List of archive names. First name is the real one, the rest are links. + # The last name is the one that the linker finds with -lNAME. + library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + + # The coded name of the library, if different from the real name. + soname_spec="\${libname}\${release}\${shared_ext}\$major" + + # Commands used to build and install an old-style archive. + RANLIB="ranlib" + old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" + old_postuninstall_cmds="" + + # Create an old-style archive from a shared archive. + old_archive_from_new_cmds="" + + # Create a temporary old-style archive to link instead of a shared archive. + old_archive_from_expsyms_cmds="" + + # Commands used to build and install a shared archive. + archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" + archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" + postinstall_cmds="" + postuninstall_cmds="" + + # Commands used to build a loadable module (assumed same as above if empty) + module_cmds="" + module_expsym_cmds="" + + # Commands to strip libraries. + old_striplib="strip --strip-debug" + striplib="strip --strip-unneeded" + + # Dependencies to place before the objects being linked to create a + # shared library. + predep_objects="" + + # Dependencies to place after the objects being linked to create a + # shared library. + postdep_objects="" + + # Dependencies to place before the objects being linked to create a + # shared library. + predeps="" + + # Dependencies to place after the objects being linked to create a + # shared library. + postdeps="" + + # The library search path used internally by the compiler when linking + # a shared library. + compiler_lib_search_path="" + + # Method to check whether dependent libraries are shared objects. + deplibs_check_method="pass_all" + + # Command to use when deplibs_check_method == file_magic. + file_magic_cmd="\$MAGIC_CMD" + + # Flag that allows shared libraries with undefined symbols to be built. + allow_undefined_flag="" + + # Flag that forces no undefined symbols. + no_undefined_flag="" + + # Commands used to finish a libtool library installation in a directory. + finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + + # Same as above, but a single script fragment to be evaled but not shown. + finish_eval="" + + # Take the output of nm and produce a listing of raw symbols and C names. + global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW][ABCDGISTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" + + # Transform the output of nm in a proper C declaration + global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + + # Transform the output of nm in a C name address pair + global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + + # This is the shared library runtime path variable. + runpath_var=LD_RUN_PATH + + # This is the shared library path variable. + shlibpath_var=LD_LIBRARY_PATH + + # Is shlibpath searched before the hard-coded library search path? + shlibpath_overrides_runpath=no + + # How to hardcode a shared library path into an executable. + hardcode_action=immediate + + # Whether we should hardcode library paths into libraries. + hardcode_into_libs=yes + + # Flag to hardcode $libdir into a binary during linking. + # This must work even if $libdir does not exist. + hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + + # If ld is used when linking, flag to hardcode $libdir into + # a binary during linking. This must work even if $libdir does + # not exist. + hardcode_libdir_flag_spec_ld="" + + # Whether we need a single -rpath flag with a separated argument. + hardcode_libdir_separator="" + + # Set to yes if using DIR/libNAME during linking hardcodes DIR into the + # resulting binary. + hardcode_direct=no + + # Set to yes if using the -LDIR flag during linking hardcodes DIR into the + # resulting binary. + hardcode_minus_L=no + + # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into + # the resulting binary. + hardcode_shlibpath_var=unsupported + + # Set to yes if building a shared library automatically hardcodes DIR into the library + # and all subsequent libraries and executables linked against it. + hardcode_automatic=no + + # Variables whose values should be saved in libtool wrapper scripts and + # restored at relink time. + variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + + # Whether libtool must link a program against all its dependency libraries. + link_all_deplibs=unknown + + # Compile-time system search path for libraries + sys_lib_search_path_spec=" /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/ /usr/lib/gcc/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../../i686-pc-linux-gnu/lib/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-lin! ux-gnu/3.2/../../../i686-pc-linux-gnu/3.2/ /usr/dcs/software/evaluation/encap/gcc-3.2/lib/gcc-lib/i686-pc-linux-gnu/3.2/../../../ /lib/i686-pc-linux-gnu/3.2/ /lib/ /usr/lib/i686-pc-linux-gnu/3.2/ /usr/lib/" + + # Run-time system search path for libraries + sys_lib_dlsearch_path_spec="/lib /usr/lib" + + # Fix the shell variable $srcfile for the compiler. + fix_srcfile_path="" + + # Set to yes if exported symbols are required. + always_export_symbols=no + + # The commands to list exported symbols. + export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + + # The commands to extract the exported symbol list from a shared archive. + extract_expsyms_cmds="" + + # Symbols that should not be listed in the preloaded symbols. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + + # Symbols that must always be exported. + include_expsyms="" + + # ### END LIBTOOL TAG CONFIG: F77 + From lattner at cs.uiuc.edu Mon Aug 4 00:01:23 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:23 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200308031818.NAA02293@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.5 -> 1.6 --- Log message: * Changes to allow lists of any type * Reorganize Target class a bit * Fix string out of range access bug --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.5 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.6 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.5 Sun Aug 3 10:40:38 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Sun Aug 3 13:17:54 2003 @@ -41,20 +41,24 @@ OS << "}\n"; } -static Record *getRegisterInfo(RecordKeeper &RC) { - std::vector RegisterInfos = - Records.getAllDerivedDefinitions("RegisterInfo"); - - if (RegisterInfos.size() != 1) - throw std::string("ERROR: Multiple subclasses of RegisterInfo defined!"); - return RegisterInfos[0]; +static Record *getTarget(RecordKeeper &RC) { + std::vector Targets = RC.getAllDerivedDefinitions("Target"); + + if (Targets.size() != 1) + throw std::string("ERROR: Multiple subclasses of Target defined!"); + return Targets[0]; +} + +static std::string getQualifiedName(Record *R) { + std::string Namespace = R->getValueAsString("Namespace"); + if (Namespace.empty()) return R->getName(); + return Namespace + "::" + R->getName(); } void RegisterInfoEmitter::runHeader(std::ostream &OS) { EmitSourceHeader("Register Information Header Fragment", OS); - std::string ClassName = - getRegisterInfo(Records)->getValueAsString("ClassName"); + std::string ClassName = getTarget(Records)->getName() + "GenRegisterInfo"; OS << "#include \"llvm/Target/MRegisterInfo.h\"\n\n"; @@ -65,12 +69,6 @@ << "};\n\n"; } -static std::string getQualifiedName(Record *R) { - std::string Namespace = R->getValueAsString("Namespace"); - if (Namespace.empty()) return R->getName(); - return Namespace + "::" + R->getName(); -} - // RegisterInfoEmitter::run - Main register file description emitter. // void RegisterInfoEmitter::run(std::ostream &OS) { @@ -95,7 +93,7 @@ for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { Record *RC = RegisterClasses[rc]; std::string Name = RC->getName(); - if (Name[9] == '.') { + if (Name.size() > 9 && Name[9] == '.') { static unsigned AnonCounter = 0; Name = "AnonRegClass_"+utostr(AnonCounter++); } @@ -107,7 +105,9 @@ << "[] = {\n "; ListInit *RegList = RC->getValueAsListInit("MemberList"); for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { - Record *Reg = RegList->getElement(i); + DefInit *RegDef = dynamic_cast(RegList->getElement(i)); + if (!RegDef) throw "Register class member is not a record!"; + Record *Reg = RegDef->getDef(); if (!Reg->isSubClassOf(RegisterClass)) throw "Register Class member '" + Reg->getName() + " does not derive from the Register class!"; @@ -152,17 +152,19 @@ // Add information that R aliases all of the elements in the list... and // that everything in the list aliases R. for (unsigned j = 0, e = LI->getSize(); j != e; ++j) { - if (RegisterAliases[R].count(LI->getElement(j))) + DefInit *Reg = dynamic_cast(LI->getElement(j)); + if (!Reg) throw "ERROR: Alias list element is not a def!"; + if (RegisterAliases[R].count(Reg->getDef())) std::cerr << "Warning: register alias between " << getQualifiedName(R) - << " and " << getQualifiedName(LI->getElement(j)) + << " and " << getQualifiedName(Reg->getDef()) << " specified multiple times!\n"; - RegisterAliases[R].insert(LI->getElement(j)); + RegisterAliases[R].insert(Reg->getDef()); - if (RegisterAliases[LI->getElement(j)].count(R)) + if (RegisterAliases[Reg->getDef()].count(R)) std::cerr << "Warning: register alias between " << getQualifiedName(R) - << " and " << getQualifiedName(LI->getElement(j)) + << " and " << getQualifiedName(Reg->getDef()) << " specified multiple times!\n"; - RegisterAliases[LI->getElement(j)].insert(R); + RegisterAliases[Reg->getDef()].insert(R); } } @@ -196,8 +198,8 @@ OS << " };\n"; // End of register descriptors... OS << "}\n\n"; // End of anonymous namespace... - Record *RegisterInfo = getRegisterInfo(Records); - std::string ClassName = RegisterInfo->getValueAsString("ClassName"); + Record *Target = getTarget(Records); + std::string ClassName = Target->getName() + "GenRegisterInfo"; // Emit the constructor of the class... OS << ClassName << "::" << ClassName @@ -210,8 +212,11 @@ OS << "const unsigned* " << ClassName << "::getCalleeSaveRegs() const {\n" << " static const unsigned CalleeSaveRegs[] = {\n "; - ListInit *LI = RegisterInfo->getValueAsListInit("CalleeSavedRegisters"); + ListInit *LI = Target->getValueAsListInit("CalleeSavedRegisters"); for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - OS << getQualifiedName(LI->getElement(i)) << ", "; + if (DefInit *DI = dynamic_cast(LI->getElement(i))) + OS << getQualifiedName(DI->getDef()) << ", "; + else + throw "Expected register definition in CalleeSavedRegisters list!"; OS << " 0\n };\n return CalleeSaveRegs;\n}\n\n"; } From lattner at cs.uiuc.edu Mon Aug 4 00:01:30 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:30 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.td Message-ID: <200308031818.NAA02343@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.td updated: 1.1 -> 1.2 --- Log message: The RegisterInfo class is obsolete --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.1 llvm/lib/Target/X86/X86RegisterInfo.td:1.2 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.1 Sun Aug 3 10:47:25 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.td Sun Aug 3 13:18:48 2003 @@ -98,19 +98,3 @@ def : RegisterClass; def : RegisterClass; - - -//===----------------------------------------------------------------------===// -// Finally, define the global RegisterInfo implementation. -// - -def : RegisterInfo { - // Specify the class name for the register info generator to make. - set ClassName = "X86GenRegisterInfo"; - - // Specify the calle saved registers. - set CalleeSavedRegisters = [ESI, EDI, EBX, EBP]; - - // Yes, pointers are 32-bits in size. - set PointerType = i32; -} From lattner at cs.uiuc.edu Mon Aug 4 00:01:35 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:35 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308031818.NAA02326@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.8 -> 1.9 --- Log message: Remove the RegisterInfo class in favor of a general Target class. Add instrinfo stuff --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.8 llvm/lib/Target/Target.td:1.9 --- llvm/lib/Target/Target.td:1.8 Fri Aug 1 17:21:49 2003 +++ llvm/lib/Target/Target.td Sun Aug 3 13:18:31 2003 @@ -75,30 +75,10 @@ code Methods = [{}]; } -// RegisterInfo - This class should only be instantiated once to provide -// parameters which are global to the the target machine, such as callee safed -// registers. -// -class RegisterInfo { - // ClassName - Specify the name of the class that should be generated by the - // register info emitter. This class may be further subclasses by custom - // target code to implement virtual methods as necessary. Targets must - // specify a value for this. - // - string ClassName; - - // CalleeSavedRegisters - As you might guess, this is a list of the callee - // saved registers for a target. - list CalleeSavedRegisters = []; - - // PointerType - Specify the value type to be used to represent pointers in - // this target. Typically this is an i32 or i64 type. - ValueType PointerType; -} - //===----------------------------------------------------------------------===// -// Instruction set description - +// Instruction set description - These classes correspond to the C++ classes in +// the Target/TargetInstrInfo.h file. // class Instruction { @@ -115,4 +95,35 @@ bit isCall = 0; // Is this instruction a call instruction? bit isTwoAddress = 0; // Is this a two address instruction? bit isTerminator = 0; // Is this part of the terminator for a basic block? + + // If the target wants to associate some target-specific information with each + // instruction, it should provide these two lists to indicate how to assemble + // the target specific information into the 32 bits available. + list TargetInfoFields = []; + list TargetInfoPositions = []; +} + +// InstrInfo - This class should only be instantiated once to provide parameters +// which are global to the the target machine. +// +class InstrInfo { + Instruction PHIInst; + Instruction NOOPInst; +} + + +//===----------------------------------------------------------------------===// +// Target - This class contains the "global" target information +// +class Target { + // CalleeSavedRegisters - As you might guess, this is a list of the callee + // saved registers for a target. + list CalleeSavedRegisters = []; + + // PointerType - Specify the value type to be used to represent pointers in + // this target. Typically this is an i32 or i64 type. + ValueType PointerType; + + // InstructionSet - Instruction set description for this target + InstrInfo InstructionSet; } From lattner at cs.uiuc.edu Mon Aug 4 00:01:42 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:42 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200308031818.NAA02283@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.16 -> 1.17 --- Log message: Changes to allow lists of any type --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.16 llvm/utils/TableGen/FileParser.y:1.17 --- llvm/utils/TableGen/FileParser.y:1.16 Sun Aug 3 08:58:01 2003 +++ llvm/utils/TableGen/FileParser.y Sun Aug 3 13:17:22 2003 @@ -162,7 +162,6 @@ RecTy *Ty; Init *Initializer; std::vector *FieldList; - std::vector *RecPtr; std::vector*BitList; Record *Rec; SubClassRefTy *SubClassRef; @@ -174,8 +173,7 @@ %token ID STRVAL CODEFRAGMENT %type Type -%type DefList DefListNE -%type ClassInst DefInst Object ObjectBody ClassID DefID +%type ClassInst DefInst Object ObjectBody ClassID %type SubClassRef %type ClassList ClassListNE @@ -197,15 +195,6 @@ delete $1; }; -DefID : ID { - $$ = Records.getDef(*$1); - if ($$ == 0) { - err() << "Couldn't find def '" << *$1 << "'!\n"; - abort(); - } - delete $1; - }; - // TableGen types... Type : STRING { // string type @@ -216,7 +205,7 @@ $$ = new BitsRecTy($3); } | INT { // int type $$ = new IntRecTy(); - } | LIST '<' ClassID '>' { // list type + } | LIST '<' Type '>' { // list type $$ = new ListRecTy($3); } | CODE { // code type $$ = new CodeRecTy(); @@ -252,11 +241,7 @@ $$ = Init; delete $2; } | ID { - if (CurRec == 0) { - err() << "Def/Class name '" << *$1 << "' not allowed here!\n"; - abort(); - } - if (const RecordVal *RV = CurRec->getValue(*$1)) { + if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) { $$ = new VarInit(*$1, RV->getType()); } else if (Record *D = Records.getDef(*$1)) { $$ = new DefInit(D); @@ -273,7 +258,7 @@ abort(); } delete $3; - } | '[' DefList ']' { + } | '[' ValueList ']' { $$ = new ListInit(*$2); delete $2; } | Value '.' ID { @@ -284,19 +269,6 @@ $$ = new FieldInit($1, *$3); delete $3; }; - -DefList : /*empty */ { - $$ = new std::vector(); - } | DefListNE { - $$ = $1; - }; -DefListNE : DefID { - $$ = new std::vector(); - $$->push_back($1); - } | DefListNE ',' DefID { - ($$=$1)->push_back($3); - }; - RBitList : INTVAL { $$ = new std::vector(); From lattner at cs.uiuc.edu Mon Aug 4 00:01:48 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:48 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Message-ID: <200308031824.NAA03361@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.19 -> 1.20 --- Log message: Fix bug: TableGen/BitsInitOverflow.td --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.19 llvm/utils/TableGen/Record.cpp:1.20 --- llvm/utils/TableGen/Record.cpp:1.19 Sun Aug 3 13:16:55 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 3 13:24:34 2003 @@ -53,10 +53,19 @@ // Init *BitsRecTy::convertValue(IntInit *II) { int Value = II->getValue(); + // Make sure this bitfield is large enough to hold the integer value... + if (Value >= 0) { + if (Value & ~((1 << Size)-1)) + return 0; + } else { + if ((Value >> Size) != -1 || ((Value & (1 << Size-1)) == 0)) + return 0; + } BitsInit *Ret = new BitsInit(Size); for (unsigned i = 0; i != Size; ++i) Ret->setBit(i, new BitInit(Value & (1 << i))); + return Ret; } From lattner at cs.uiuc.edu Mon Aug 4 00:01:53 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:53 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.td Message-ID: <200308031819.NAA02363@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.td updated: 1.1 -> 1.2 --- Log message: Add Target class for X86 target --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.1 llvm/lib/Target/X86/X86.td:1.2 --- llvm/lib/Target/X86/X86.td:1.1 Sun Aug 3 10:47:49 2003 +++ llvm/lib/Target/X86/X86.td Sun Aug 3 13:19:37 2003 @@ -15,3 +15,20 @@ include "X86RegisterInfo.td" +//===----------------------------------------------------------------------===// +// Instruction Descriptions +//===----------------------------------------------------------------------===// + +def X86InstrInfo : InstrInfo { +} + +def X86 : Target { + // Specify the callee saved registers. + set CalleeSavedRegisters = [ESI, EDI, EBX, EBP]; + + // Yes, pointers are 32-bits in size. + set PointerType = i32; + + // Information about the instructions... + set InstructionSet = X86InstrInfo; +} From lattner at cs.uiuc.edu Mon Aug 4 00:01:59 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:01:59 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/BitsInitOverflow.td Message-ID: <200308031823.NAA02999@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: BitsInitOverflow.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/BitsInitOverflow.td diff -c /dev/null llvm/test/Regression/TableGen/BitsInitOverflow.td:1.1 *** /dev/null Sun Aug 3 13:23:06 2003 --- llvm/test/Regression/TableGen/BitsInitOverflow.td Sun Aug 3 13:22:56 2003 *************** *** 0 **** --- 1,5 ---- + // RUN: not tblgen %s + + def { + bits<2> X = 5; // bitfield is too small, reject + } From lattner at cs.uiuc.edu Mon Aug 4 00:02:05 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:05 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l FileParser.y Message-ID: <200308040457.XAA24454@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.8 -> 1.9 FileParser.y updated: 1.18 -> 1.19 --- Log message: Start transitioning towards using 'let X = y in' statements, instead of 'set X = y in'. --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.8 llvm/utils/TableGen/FileLexer.l:1.9 --- llvm/utils/TableGen/FileLexer.l:1.8 Sun Aug 3 23:50:57 2003 +++ llvm/utils/TableGen/FileLexer.l Sun Aug 3 23:56:53 2003 @@ -159,7 +159,8 @@ class { return CLASS; } def { return DEF; } field { return FIELD; } -set { return SET; } +let { return LET; } +set { return LET; } in { return IN; } {Identifier} { Filelval.StrVal = new std::string(yytext, yytext+yyleng); Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.18 llvm/utils/TableGen/FileParser.y:1.19 --- llvm/utils/TableGen/FileParser.y:1.18 Sun Aug 3 23:50:57 2003 +++ llvm/utils/TableGen/FileParser.y Sun Aug 3 23:56:53 2003 @@ -18,18 +18,18 @@ typedef std::pair*> SubClassRefTy; -struct SetRecord { +struct LetRecord { std::string Name; std::vector Bits; Init *Value; bool HasBits; - SetRecord(const std::string &N, std::vector *B, Init *V) + LetRecord(const std::string &N, std::vector *B, Init *V) : Name(N), Value(V), HasBits(B != 0) { if (HasBits) Bits = *B; } }; -static std::vector > SetStack; +static std::vector > LetStack; extern std::ostream &err(); @@ -168,7 +168,7 @@ std::vector *SubClassList; }; -%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD SET IN +%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN %token INTVAL %token ID STRVAL CODEFRAGMENT @@ -340,7 +340,7 @@ BodyItem : Declaration ';' { delete $1; -} | SET ID OptBitList '=' Value ';' { +} | LET ID OptBitList '=' Value ';' { setValue(*$2, $3, $5); delete $2; delete $3; @@ -399,11 +399,11 @@ } // Process any variables on the set stack... - for (unsigned i = 0, e = SetStack.size(); i != e; ++i) - for (unsigned j = 0, e = SetStack[i].size(); j != e; ++j) - setValue(SetStack[i][j].Name, - SetStack[i][j].HasBits ? &SetStack[i][j].Bits : 0, - SetStack[i][j].Value); + for (unsigned i = 0, e = LetStack.size(); i != e; ++i) + for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) + setValue(LetStack[i][j].Name, + LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, + LetStack[i][j].Value); } Body { CurRec->resolveReferences(); @@ -446,22 +446,22 @@ Object : ClassInst | DefInst; -SETItem : ID OptBitList '=' Value { - SetStack.back().push_back(SetRecord(*$1, $2, $4)); +LETItem : ID OptBitList '=' Value { + LetStack.back().push_back(LetRecord(*$1, $2, $4)); delete $1; delete $2; }; -SETList : SETItem | SETList ',' SETItem; +LETList : LETItem | LETList ',' LETItem; -// SETCommand - A 'SET' statement start... -SETCommand : SET { SetStack.push_back(std::vector()); } SETList IN; +// LETCommand - A 'LET' statement start... +LETCommand : LET { LetStack.push_back(std::vector()); } LETList IN; // Support Set commands wrapping objects... both with and without braces. -Object : SETCommand '{' ObjectList '}' { - SetStack.pop_back(); +Object : LETCommand '{' ObjectList '}' { + LetStack.pop_back(); } - | SETCommand Object { - SetStack.pop_back(); + | LETCommand Object { + LetStack.pop_back(); }; ObjectList : Object {} | ObjectList Object {}; From lattner at cs.uiuc.edu Mon Aug 4 00:02:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:11 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308040458.XAA24618@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.11 -> 1.12 --- Log message: Transition to using let instead of set --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.11 llvm/lib/Target/Target.td:1.12 --- llvm/lib/Target/Target.td:1.11 Sun Aug 3 17:12:37 2003 +++ llvm/lib/Target/Target.td Sun Aug 3 23:58:12 2003 @@ -42,7 +42,7 @@ // "name" of the register, you can use this to specify a custom name instead. // class NamedReg : Register { - set Name = n; + let Name = n; } // RegisterAliases - You should define instances of this class to indicate which From lattner at cs.uiuc.edu Mon Aug 4 00:02:17 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:17 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.h Message-ID: <200308031630.LAA18233@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.h updated: 1.2 -> 1.3 --- Log message: Remove dead private: --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.h diff -u llvm/utils/TableGen/RegisterInfoEmitter.h:1.2 llvm/utils/TableGen/RegisterInfoEmitter.h:1.3 --- llvm/utils/TableGen/RegisterInfoEmitter.h:1.2 Fri Aug 1 00:59:20 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.h Sun Aug 3 11:30:24 2003 @@ -25,7 +25,6 @@ // runEnums - Print out enum values for all of the registers. void runEnums(std::ostream &o); -private: }; #endif From lattner at cs.uiuc.edu Mon Aug 4 00:02:28 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:28 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/.cvsignore Message-ID: <200308031550.KAA16114@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: .cvsignore added (r1.1) --- Log message: Tell CVS to ignore all .inc files --- Diffs of the changes: Index: llvm/lib/Target/X86/.cvsignore diff -c /dev/null llvm/lib/Target/X86/.cvsignore:1.1 *** /dev/null Sun Aug 3 10:50:27 2003 --- llvm/lib/Target/X86/.cvsignore Sun Aug 3 10:50:17 2003 *************** *** 0 **** --- 1 ---- + *.inc From lattner at cs.uiuc.edu Mon Aug 4 00:02:36 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:36 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.h Message-ID: <200308031549.KAA16087@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.h updated: 1.15 -> 1.16 --- Log message: Switch over to tablegen generated header files --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.15 llvm/lib/Target/X86/X86.h:1.16 --- llvm/lib/Target/X86/X86.h:1.15 Sat Jul 26 18:49:58 2003 +++ llvm/lib/Target/X86/X86.h Sun Aug 3 10:48:55 2003 @@ -13,7 +13,7 @@ class Pass; /// createX86SimpleInstructionSelector - This pass converts an LLVM function -/// into a machine code representation is a very simple peep-hole fashion. The +/// into a machine code representation in a very simple peep-hole fashion. The /// generated code sucks but the implementation is nice and simple. /// Pass *createX86SimpleInstructionSelector(TargetMachine &TM); @@ -42,18 +42,15 @@ /// Pass *createEmitX86CodeToMemory(); +// Defines symbolic names for X86 registers. This defines a mapping from +// register name to register number. +// +#include "X86GenRegisterNames.inc" + /// X86 namespace - This namespace contains all of the register and opcode enums /// used by the X86 backend. /// namespace X86 { - // Defines a large number of symbolic names for X86 registers. This defines a - // mapping from register name to register number. - // - enum Register { -#define R(ENUM, NAME, FLAGS, TSFLAGS, ALIAS_SET) ENUM, -#include "X86RegisterInfo.def" - }; - // This defines a large number of symbolic names for X86 instruction opcodes. enum Opcode { #define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) ENUM, From lattner at cs.uiuc.edu Mon Aug 4 00:02:45 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:45 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Makefile X86RegisterInfo.cpp X86RegisterInfo.h X86RegisterInfo.def Message-ID: <200308031548.KAA16067@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Makefile updated: 1.1 -> 1.2 X86RegisterInfo.cpp updated: 1.32 -> 1.33 X86RegisterInfo.h updated: 1.14 -> 1.15 X86RegisterInfo.def (r1.14) removed --- Log message: Switch over to TableGen generated register file description --- Diffs of the changes: Index: llvm/lib/Target/X86/Makefile diff -u llvm/lib/Target/X86/Makefile:1.1 llvm/lib/Target/X86/Makefile:1.2 --- llvm/lib/Target/X86/Makefile:1.1 Fri Oct 25 17:55:53 2002 +++ llvm/lib/Target/X86/Makefile Sun Aug 3 10:48:14 2003 @@ -2,3 +2,20 @@ LIBRARYNAME = x86 include $(LEVEL)/Makefile.common + + +# Make sure that tblgen is run, first thing. +$(SourceDepend): X86GenRegisterInfo.h.inc X86GenRegisterNames.inc X86GenRegisterInfo.inc + +X86GenRegisterNames.inc: $(wildcard *.td) $(TBLGEN) + $(TBLGEN) X86.td -gen-register-enums -o $@ + +X86GenRegisterInfo.h.inc: $(wildcard *.td) $(TBLGEN) + $(TBLGEN) X86.td -gen-register-desc-header -o $@ + +X86GenRegisterInfo.inc: $(wildcard *.td) $(TBLGEN) + $(TBLGEN) X86.td -gen-register-desc -o $@ + +clean:: + $(VERB) rm -f *.inc + Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.32 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.33 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.32 Tue Jul 29 00:14:16 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Sun Aug 3 10:48:14 2003 @@ -24,6 +24,9 @@ cl::desc("Disable frame pointer elimination optimization")); } +X86RegisterInfo::X86RegisterInfo() + : X86GenRegisterInfo(X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP) {} + static unsigned getIdx(const TargetRegisterClass *RC) { switch (RC->getSize()) { default: assert(0 && "Invalid data size!"); @@ -66,14 +69,6 @@ MBBI = MBB.insert(MBBI, MI)+1; } -const unsigned* X86RegisterInfo::getCalleeSaveRegs() const { - static const unsigned CalleeSaveRegs[] = { - X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0 - }; - return CalleeSaveRegs; -} - - //===----------------------------------------------------------------------===// // Stack Frame Processing methods //===----------------------------------------------------------------------===// @@ -249,103 +244,7 @@ } } - -//===----------------------------------------------------------------------===// -// Register Class Implementation Code -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// 8 Bit Integer Registers -// -namespace { - const unsigned ByteRegClassRegs[] = { - X86::AL, X86::CL, X86::DL, X86::BL, X86::AH, X86::CH, X86::DH, X86::BH, - }; - - TargetRegisterClass X86ByteRegisterClassInstance(1, 1, ByteRegClassRegs, - ByteRegClassRegs+sizeof(ByteRegClassRegs)/sizeof(ByteRegClassRegs[0])); - -//===----------------------------------------------------------------------===// -// 16 Bit Integer Registers -// - const unsigned ShortRegClassRegs[] = { - X86::AX, X86::CX, X86::DX, X86::BX, X86::SI, X86::DI, X86::BP, X86::SP - }; - - struct R16CL : public TargetRegisterClass { - R16CL():TargetRegisterClass(2, 2, ShortRegClassRegs, ShortRegClassRegs+8) {} - iterator allocation_order_end(MachineFunction &MF) const { - if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? - return end()-2; // Don't allocate SP or BP - else - return end()-1; // Don't allocate SP - } - } X86ShortRegisterClassInstance; - -//===----------------------------------------------------------------------===// -// 32 Bit Integer Registers -// - const unsigned IntRegClassRegs[] = { - X86::EAX, X86::ECX, X86::EDX, X86::EBX, - X86::ESI, X86::EDI, X86::EBP, X86::ESP - }; - - struct R32CL : public TargetRegisterClass { - R32CL() : TargetRegisterClass(4, 4, IntRegClassRegs, IntRegClassRegs+8) {} - iterator allocation_order_end(MachineFunction &MF) const { - if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? - return end()-2; // Don't allocate ESP or EBP - else - return end()-1; // Don't allocate ESP - } - } X86IntRegisterClassInstance; - -//===----------------------------------------------------------------------===// -// Pseudo Floating Point Registers -// - const unsigned PFPRegClassRegs[] = { -#define PFP(ENUM, NAME, FLAGS, TSFLAGS, ALIAS_SET) X86::ENUM, -#include "X86RegisterInfo.def" - }; - - TargetRegisterClass X86FPRegisterClassInstance(10, 4, PFPRegClassRegs, - PFPRegClassRegs+sizeof(PFPRegClassRegs)/sizeof(PFPRegClassRegs[0])); - -//===----------------------------------------------------------------------===// -// Register class array... -// - const TargetRegisterClass * const X86RegClasses[] = { - &X86ByteRegisterClassInstance, - &X86ShortRegisterClassInstance, - &X86IntRegisterClassInstance, - &X86FPRegisterClassInstance, - }; -} - - -// Create static lists to contain register alias sets... -#define ALIASLIST(NAME, ...) \ - static const unsigned NAME[] = { __VA_ARGS__ }; -#include "X86RegisterInfo.def" - - -// X86Regs - Turn the X86RegisterInfo.def file into a bunch of register -// descriptors -// -static const MRegisterDesc X86Regs[] = { -#define R(ENUM, NAME, FLAGS, TSFLAGS, ALIAS_SET) \ - { NAME, ALIAS_SET, FLAGS, TSFLAGS }, -#include "X86RegisterInfo.def" -}; - -X86RegisterInfo::X86RegisterInfo() - : MRegisterInfo(X86Regs, sizeof(X86Regs)/sizeof(X86Regs[0]), - X86RegClasses, - X86RegClasses+sizeof(X86RegClasses)/sizeof(X86RegClasses[0]), - X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP) { -} - - +#include "X86GenRegisterInfo.inc" const TargetRegisterClass* X86RegisterInfo::getRegClassForType(const Type* Ty) const { @@ -355,14 +254,14 @@ default: assert(0 && "Invalid type to getClass!"); case Type::BoolTyID: case Type::SByteTyID: - case Type::UByteTyID: return &X86ByteRegisterClassInstance; + case Type::UByteTyID: return &r8Instance; case Type::ShortTyID: - case Type::UShortTyID: return &X86ShortRegisterClassInstance; + case Type::UShortTyID: return &r16Instance; case Type::IntTyID: case Type::UIntTyID: - case Type::PointerTyID: return &X86IntRegisterClassInstance; + case Type::PointerTyID: return &r32Instance; case Type::FloatTyID: - case Type::DoubleTyID: return &X86FPRegisterClassInstance; + case Type::DoubleTyID: return &rFPInstance; } } Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.14 llvm/lib/Target/X86/X86RegisterInfo.h:1.15 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.14 Thu Jul 31 22:48:42 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.h Sun Aug 3 10:48:14 2003 @@ -11,11 +11,10 @@ class Type; -struct X86RegisterInfo : public MRegisterInfo { - X86RegisterInfo(); - - const unsigned* getCalleeSaveRegs() const; +#include "X86GenRegisterInfo.h.inc" +struct X86RegisterInfo : public X86GenRegisterInfo { + X86RegisterInfo(); const TargetRegisterClass* getRegClassForType(const Type* Ty) const; /// Code Generation virtual methods... From lattner at cs.uiuc.edu Mon Aug 4 00:02:52 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:02:52 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.td Message-ID: <200308031547.KAA16043@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.td added (r1.1) --- Log message: Initial checkin of X86.td file --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.td diff -c /dev/null llvm/lib/Target/X86/X86.td:1.1 *** /dev/null Sun Aug 3 10:47:59 2003 --- llvm/lib/Target/X86/X86.td Sun Aug 3 10:47:49 2003 *************** *** 0 **** --- 1,17 ---- + //===- X86.td - Target definition file for the Intel X86 arch ---*- C++ -*-===// + // + // This is a target description file for the Intel i386 architecture, refered to + // here as the "X86" architecture. + // + //===----------------------------------------------------------------------===// + + // Get the target independent interfaces which we are implementing... + // + include "../Target.td" + + //===----------------------------------------------------------------------===// + // Register File Description + //===----------------------------------------------------------------------===// + + include "X86RegisterInfo.td" + From lattner at cs.uiuc.edu Mon Aug 4 00:03:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.td Message-ID: <200308031547.KAA16026@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.td added (r1.1) --- Log message: Initial checkin of X86 Register File description --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -c /dev/null llvm/lib/Target/X86/X86RegisterInfo.td:1.1 *** /dev/null Sun Aug 3 10:47:35 2003 --- llvm/lib/Target/X86/X86RegisterInfo.td Sun Aug 3 10:47:25 2003 *************** *** 0 **** --- 1,116 ---- + //===- X86RegisterInfo.td - Describe the X86 Register File ------*- C++ -*-===// + // + // This file describes the X86 Register file, defining the registers themselves, + // aliases between the registers, and the register classes built out of the + // registers. + // + //===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// + // Register definitions... + // + set Namespace = "X86" in { + // 32-bit registers + def EAX : Register; def ECX : Register; + def EDX : Register; def EBX : Register; + def ESP : Register; def EBP : Register; + def ESI : Register; def EDI : Register; + + // 16-bit registers + def AX : Register; def CX : Register; + def DX : Register; def BX : Register; + def SP : Register; def BP : Register; + def SI : Register; def DI : Register; + + // 8-bit registers + def AL : Register; def CL : Register; + def DL : Register; def BL : Register; + def AH : Register; def CH : Register; + def DH : Register; def BH : Register; + + // Pseudo Floating Point registers + def FP0 : Register; def FP1 : Register; + def FP2 : Register; def FP3 : Register; + def FP4 : Register; def FP5 : Register; + def FP6 : Register; + + // Floating point stack registers + def ST0 : Register; def ST1 : Register; + def ST2 : Register; def ST3 : Register; + def ST4 : Register; def ST5 : Register; + def ST6 : Register; def ST7 : Register; + + // Flags, Segment registers, etc... + + // This is a slimy hack to make it possible to say that flags are clobbered... + // Ideally we'd model instructions based on which particular flag(s) they + // could clobber. + def EFLAGS : Register; + } + + //===----------------------------------------------------------------------===// + // Register alias definitions... define which registers alias which others. We + // only specify which registers the small registers alias, because the register + // file generator is smart enough to figure out that AL aliases AX if we tell it + // that AX aliases AL (for example). + // + def : RegisterAliases; def : RegisterAliases; + def : RegisterAliases; def : RegisterAliases; + def : RegisterAliases; def : RegisterAliases; + def : RegisterAliases; def : RegisterAliases; + + def : RegisterAliases; def : RegisterAliases; + def : RegisterAliases; def : RegisterAliases; + def : RegisterAliases; def : RegisterAliases; + def : RegisterAliases; def : RegisterAliases; + + //===----------------------------------------------------------------------===// + // Register Class Definitions... now that we have all of the pieces, define the + // top-level register classes. The order specified in the register list is + // implicitly defined to be the register allocation order. + // + def r8 : RegisterClass; + def r16 : RegisterClass { + set Methods = [{ + iterator allocation_order_end(MachineFunction &MF) const { + if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? + return end()-2; // If so, don't allocate SP or BP + else + return end()-1; // If not, just don't allocate SP + } + }]; + } + + def r32 : RegisterClass { + set Methods = [{ + iterator allocation_order_end(MachineFunction &MF) const { + if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? + return end()-2; // If so, don't allocate ESP or EBP + else + return end()-1; // If not, just don't allocate ESP + } + }]; + } + + def rFP : RegisterClass; + + // Registers which cannot be allocated... and are thus left unnamed. + def : RegisterClass; + def : RegisterClass; + + + + //===----------------------------------------------------------------------===// + // Finally, define the global RegisterInfo implementation. + // + + def : RegisterInfo { + // Specify the class name for the register info generator to make. + set ClassName = "X86GenRegisterInfo"; + + // Specify the calle saved registers. + set CalleeSavedRegisters = [ESI, EDI, EBX, EBP]; + + // Yes, pointers are 32-bits in size. + set PointerType = i32; + } From lattner at cs.uiuc.edu Mon Aug 4 00:03:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:08 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200308031540.KAA12307@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.4 -> 1.5 --- Log message: Make the register numbers line up more frequently --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.4 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.5 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.4 Sun Aug 3 08:52:02 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Sun Aug 3 10:40:38 2003 @@ -34,7 +34,7 @@ OS << " enum {\n NoRegister,\n"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) - OS << " " << Registers[i]->getName() << ",\t// " << i+1 << "\n"; + OS << " " << Registers[i]->getName() << ", \t// " << i+1 << "\n"; OS << " };\n"; if (!Namespace.empty()) From lattner at cs.uiuc.edu Mon Aug 4 00:03:16 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:16 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200308031349.IAA10070@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.17 -> 1.18 --- Log message: Wrap at 80 columns --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.17 llvm/lib/CodeGen/RegAllocLocal.cpp:1.18 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.17 Fri Aug 1 17:21:34 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Sun Aug 3 08:49:03 2003 @@ -490,7 +490,8 @@ // Loop over all of the operands of the instruction, spilling registers that // are defined, and marking explicit destinations in the PhysRegsUsed map. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) - if ((MI->getOperand(i).opIsDefOnly() || MI->getOperand(i).opIsDefAndUse()) && + if ((MI->getOperand(i).opIsDefOnly() || + MI->getOperand(i).opIsDefAndUse()) && MI->getOperand(i).isPhysicalRegister()) { unsigned Reg = MI->getOperand(i).getAllocatedRegNum(); spillPhysReg(MBB, I, Reg); // Spill any existing value in the reg From lattner at cs.uiuc.edu Mon Aug 4 00:03:23 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:23 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/MRegisterInfo.cpp Message-ID: <200308031349.IAA10086@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: MRegisterInfo.cpp updated: 1.2 -> 1.3 --- Log message: Make it easier to debug by exposing a temporary --- Diffs of the changes: Index: llvm/lib/Target/MRegisterInfo.cpp diff -u llvm/lib/Target/MRegisterInfo.cpp:1.2 llvm/lib/Target/MRegisterInfo.cpp:1.3 --- llvm/lib/Target/MRegisterInfo.cpp:1.2 Sat Dec 28 14:34:18 2002 +++ llvm/lib/Target/MRegisterInfo.cpp Sun Aug 3 08:49:25 2003 @@ -20,10 +20,10 @@ // Fill in the PhysRegClasses map for (MRegisterInfo::regclass_iterator I = regclass_begin(), E = regclass_end(); I != E; ++I) - for (unsigned i=0; i < (*I)->getNumRegs(); ++i) { - assert(PhysRegClasses[(*I)->getRegister(i)] == 0 && - "Register in more than one class?"); - PhysRegClasses[(*I)->getRegister(i)] = *I; + for (unsigned i = 0, e = (*I)->getNumRegs(); i != e; ++i) { + unsigned Reg = (*I)->getRegister(i); + assert(PhysRegClasses[Reg] == 0 && "Register in more than one class?"); + PhysRegClasses[Reg] = *I; } CallFrameSetupOpcode = CFSO; From lattner at cs.uiuc.edu Mon Aug 4 00:03:29 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:29 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200308031358.IAA10169@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.15 -> 1.16 --- Log message: Allow an external 'set' command to set multiple values in the same command. Allow redefinitions of variables as long as they are of the same type. --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.15 llvm/utils/TableGen/FileParser.y:1.16 --- llvm/utils/TableGen/FileParser.y:1.15 Wed Jul 30 17:15:58 2003 +++ llvm/utils/TableGen/FileParser.y Sun Aug 3 08:58:01 2003 @@ -18,18 +18,34 @@ typedef std::pair*> SubClassRefTy; -static std::vector*>, - Init*> > SetStack; +struct SetRecord { + std::string Name; + std::vector Bits; + Init *Value; + bool HasBits; + SetRecord(const std::string &N, std::vector *B, Init *V) + : Name(N), Value(V), HasBits(B != 0) { + if (HasBits) Bits = *B; + } +}; + +static std::vector > SetStack; + extern std::ostream &err(); static void addValue(const RecordVal &RV) { - if (CurRec->getValue(RV.getName())) { - err() << "Value '" << RV.getName() << "' multiply defined!\n"; - abort(); + if (RecordVal *ERV = CurRec->getValue(RV.getName())) { + // The value already exists in the class, treat this as a set... + if (ERV->setValue(RV.getValue())) { + err() << "New definition of '" << RV.getName() << "' of type '" + << *RV.getType() << "' is incompatible with previous " + << "definition of type '" << *ERV->getType() << "'!\n"; + abort(); + } + } else { + CurRec->addValue(RV); } - - CurRec->addValue(RV); } static void addSuperClass(Record *SC) { @@ -410,8 +426,10 @@ // Process any variables on the set stack... for (unsigned i = 0, e = SetStack.size(); i != e; ++i) - setValue(SetStack[i].first.first, SetStack[i].first.second, - SetStack[i].second); + for (unsigned j = 0, e = SetStack[i].size(); j != e; ++j) + setValue(SetStack[i][j].Name, + SetStack[i][j].HasBits ? &SetStack[i][j].Bits : 0, + SetStack[i][j].Value); } Body { CurRec->resolveReferences(); @@ -454,19 +472,21 @@ Object : ClassInst | DefInst; -// SETCommand - A 'SET' statement start... -SETCommand : SET ID OptBitList '=' Value IN { - SetStack.push_back(std::make_pair(std::make_pair(*$2, $3), $5)); - delete $2; +SETItem : ID OptBitList '=' Value { + SetStack.back().push_back(SetRecord(*$1, $2, $4)); + delete $1; delete $2; }; +SETList : SETItem | SETList ',' SETItem; + +// SETCommand - A 'SET' statement start... +SETCommand : SET { SetStack.push_back(std::vector()); } SETList IN; + // Support Set commands wrapping objects... both with and without braces. Object : SETCommand '{' ObjectList '}' { - delete SetStack.back().first.second; // Delete OptBitList SetStack.pop_back(); } | SETCommand Object { - delete SetStack.back().first.second; // Delete OptBitList SetStack.pop_back(); }; From lattner at cs.uiuc.edu Mon Aug 4 00:03:37 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:37 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Record.cpp Message-ID: <200308032158.QAA30292@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.26 -> 1.27 Record.cpp updated: 1.21 -> 1.22 --- Log message: Add new Record::getValueAsBit method --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.26 llvm/utils/TableGen/Record.h:1.27 --- llvm/utils/TableGen/Record.h:1.26 Sun Aug 3 13:29:51 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 3 16:58:13 2003 @@ -707,6 +707,12 @@ /// Record *getValueAsDef(const std::string &FieldName) const; + /// getValueAsBit - This method looks up the specified field and returns its + /// value as a bit, throwing an exception if the field does not exist or if + /// the value is not the right type. + /// + bool getValueAsBit(const std::string &FieldName) const; + /// getValueAsInt - This method looks up the specified field and returns its /// value as an int, throwing an exception if the field does not exist or if /// the value is not the right type. Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.21 llvm/utils/TableGen/Record.cpp:1.22 --- llvm/utils/TableGen/Record.cpp:1.21 Sun Aug 3 13:29:51 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 3 16:58:13 2003 @@ -579,6 +579,22 @@ "' does not have a list initializer!"; } +/// getValueAsBit - This method looks up the specified field and returns its +/// value as a bit, throwing an exception if the field does not exist or if +/// the value is not the right type. +/// +bool Record::getValueAsBit(const std::string &FieldName) const { + const RecordVal *R = getValue(FieldName); + if (R == 0 || R->getValue() == 0) + throw "Record '" + R->getName() + "' does not have a field named '" + + FieldName + "!\n"; + + if (BitInit *DI = dynamic_cast(R->getValue())) + return DI->getValue(); + throw "Record '" + R->getName() + "', field '" + FieldName + + "' does not have a list initializer!"; +} + void RecordKeeper::dump() const { std::cerr << *this; } From lattner at cs.uiuc.edu Mon Aug 4 00:03:44 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:44 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200308032158.QAA30285@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.16 -> 1.17 --- Log message: add new --gen-instr-desc option --- Diffs of the changes: Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.16 llvm/utils/TableGen/TableGen.cpp:1.17 --- llvm/utils/TableGen/TableGen.cpp:1.16 Sun Aug 3 12:24:20 2003 +++ llvm/utils/TableGen/TableGen.cpp Sun Aug 3 16:58:28 2003 @@ -22,7 +22,7 @@ PrintRecords, GenEmitter, GenRegisterEnums, GenRegister, GenRegisterHeader, - GenInstrEnums, + GenInstrEnums, GenInstrs, PrintEnums, Parse, }; @@ -42,6 +42,8 @@ "Generate a register info description header"), clEnumValN(GenInstrEnums, "gen-instr-enums", "Generate enum values for instructions"), + clEnumValN(GenInstrs, "gen-instr-desc", + "Generate instruction descriptions"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(Parse, "parse", @@ -434,6 +436,9 @@ case GenInstrEnums: InstrInfoEmitter(Records).runEnums(*Out); + break; + case GenInstrs: + InstrInfoEmitter(Records).run(*Out); break; case PrintEnums: From lattner at cs.uiuc.edu Mon Aug 4 00:03:53 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:03:53 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrInfoEmitter.cpp InstrInfoEmitter.h Message-ID: <200308031724.MAA23611@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrInfoEmitter.cpp added (r1.1) InstrInfoEmitter.h added (r1.1) --- Log message: Initial checkin of Instruction emitter, which just produces enum values so far --- Diffs of the changes: Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -c /dev/null llvm/utils/TableGen/InstrInfoEmitter.cpp:1.1 *** /dev/null Sun Aug 3 12:24:20 2003 --- llvm/utils/TableGen/InstrInfoEmitter.cpp Sun Aug 3 12:24:10 2003 *************** *** 0 **** --- 1,65 ---- + //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// + // + // This tablegen backend is responsible for emitting a description of the target + // instruction set for the code generator. + // + //===----------------------------------------------------------------------===// + + #include "InstrInfoEmitter.h" + #include "Record.h" + + static void EmitSourceHeader(const std::string &Desc, std::ostream &o) { + o << "//===- TableGen'erated file -------------------------------------*-" + " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" + "d file, do not edit!\n//\n//===------------------------------------" + "----------------------------------===//\n\n"; + } + + static std::string getQualifiedName(Record *R) { + std::string Namespace = R->getValueAsString("Namespace"); + if (Namespace.empty()) return R->getName(); + return Namespace + "::" + R->getName(); + } + + static Record *getTarget(RecordKeeper &RC) { + std::vector Targets = RC.getAllDerivedDefinitions("Target"); + + if (Targets.size() != 1) + throw std::string("ERROR: Multiple subclasses of Target defined!"); + return Targets[0]; + } + + // runEnums - Print out enum values for all of the instructions. + void InstrInfoEmitter::runEnums(std::ostream &OS) { + std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); + + if (Insts.size() == 0) + throw std::string("No 'Instruction' subclasses defined!"); + + std::string Namespace = Insts[0]->getValueAsString("Namespace"); + + EmitSourceHeader("Target Instruction Enum Values", OS); + + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << " enum {\n"; + + // We must emit the PHI and NOOP opcodes first... + Record *Target = getTarget(Records); + Record *InstrInfo = Target->getValueAsDef("InstructionSet"); + + Record *PHI = InstrInfo->getValueAsDef("PHIInst"); + Record *NOOP = InstrInfo->getValueAsDef("NOOPInst"); + + OS << " " << PHI->getName() << ", \t// 0 (fixed for all targets)\n" + << " " << NOOP->getName() << ", \t// 1 (fixed for all targets)\n"; + + // Print out the rest of the instructions now... + for (unsigned i = 0, e = Insts.size(); i != e; ++i) + if (Insts[i] != PHI && Insts[i] != NOOP) + OS << " " << Insts[i]->getName() << ", \t// " << i+2 << "\n"; + + OS << " };\n"; + if (!Namespace.empty()) + OS << "}\n"; + } Index: llvm/utils/TableGen/InstrInfoEmitter.h diff -c /dev/null llvm/utils/TableGen/InstrInfoEmitter.h:1.1 *** /dev/null Sun Aug 3 12:24:20 2003 --- llvm/utils/TableGen/InstrInfoEmitter.h Sun Aug 3 12:24:10 2003 *************** *** 0 **** --- 1,26 ---- + //===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===// + // + // This tablegen backend is responsible for emitting a description of the target + // instruction set for the code generator. + // + //===----------------------------------------------------------------------===// + + #ifndef INSTRINFO_EMITTER_H + #define INSTRINFO_EMITTER_H + + #include + class RecordKeeper; + + class InstrInfoEmitter { + RecordKeeper &Records; + public: + InstrInfoEmitter(RecordKeeper &R) : Records(R) {} + + // run - Output the instruction set description, returning true on failure. + void run(std::ostream &o); + + // runEnums - Print out enum values for all of the instructions. + void runEnums(std::ostream &o); + }; + + #endif From lattner at cs.uiuc.edu Mon Aug 4 00:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordFunction.ll Message-ID: <200308032243.RAA03057@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/LLVMSource: 2003-08-03-ReservedWordFunction.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordFunction.ll diff -c /dev/null llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordFunction.ll:1.1 *** /dev/null Sun Aug 3 17:43:52 2003 --- llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordFunction.ll Sun Aug 3 17:43:42 2003 *************** *** 0 **** --- 1,14 ---- + ; This testcase ensures the code emitter does something about the fact that + ; we can have collisions with keywords + + target endian = little + target pointersize = 32 + + void %byte() { + ret void + } + int %main() { + call void %byte() + ret int 0 + } + From lattner at cs.uiuc.edu Mon Aug 4 00:04:12 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:12 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CodeGeneratorBug.cpp Message-ID: <200308032229.RAA15196@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CodeGeneratorBug.cpp updated: 1.9 -> 1.10 --- Log message: Fix problem I introduced in bugpoint with the cleanup functions --- Diffs of the changes: Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.9 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.10 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.9 Fri Aug 1 17:13:58 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Sun Aug 3 17:29:43 2003 @@ -172,10 +172,6 @@ abort(); } - // Clean up the modules, removing extra cruft that we don't need anymore... - SafeModule = BD.performFinalCleanups(SafeModule); - TestModule = BD.performFinalCleanups(TestModule); - DEBUG(std::cerr << "Safe module:\n"; typedef Module::iterator MI; typedef Module::giterator MGI; @@ -200,10 +196,6 @@ exit(1); } - // Make a shared library - std::string SharedObject; - BD.compileSharedObject(SafeModuleBC, SharedObject); - // Remove all functions from the Test module EXCEPT for the ones specified in // Funcs. We know which ones these are because they are non-external in // ToOptimize, but external in ToNotOptimize. @@ -222,10 +214,19 @@ std::cerr << "Bytecode file corrupted!\n"; exit(1); } + + // Clean up the modules, removing extra cruft that we don't need anymore... + SafeModule = BD.performFinalCleanups(SafeModule); + TestModule = BD.performFinalCleanups(TestModule); + if (BD.writeProgramToFile(TestModuleBC, TestModule)) { std::cerr << "Error writing bytecode to `" << SafeModuleBC << "'\nExiting."; exit(1); } + + // Make a shared library + std::string SharedObject; + BD.compileSharedObject(SafeModuleBC, SharedObject); delete SafeModule; delete TestModule; From lattner at cs.uiuc.edu Mon Aug 4 00:04:25 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:25 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordGlobal.ll Message-ID: <200308040012.TAA03949@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/LLVMSource: 2003-08-03-ReservedWordGlobal.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordGlobal.ll diff -c /dev/null llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordGlobal.ll:1.1 *** /dev/null Sun Aug 3 19:12:05 2003 --- llvm/test/Programs/LLVMSource/2003-08-03-ReservedWordGlobal.ll Sun Aug 3 19:11:55 2003 *************** *** 0 **** --- 1,10 ---- + target endian = little + target pointersize = 32 + %Sp = linkonce global int 0 ; [#uses=1] + + implementation ; Functions: + + int %main() { + store int 123, int* %Sp + ret int 0 + } From lattner at cs.uiuc.edu Mon Aug 4 00:04:35 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:35 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200308032342.SAA22847@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.52 -> 1.53 --- Log message: Remove illegal, unsupported escapes. This fixes program: Ptrdist-bc --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.52 llvm/lib/Target/X86/Printer.cpp:1.53 --- llvm/lib/Target/X86/Printer.cpp:1.52 Sun Aug 3 18:37:09 2003 +++ llvm/lib/Target/X86/Printer.cpp Sun Aug 3 18:42:17 2003 @@ -296,13 +296,11 @@ Result += C; } else { switch(C) { - case '\a': Result += "\\a"; break; case '\b': Result += "\\b"; break; case '\f': Result += "\\f"; break; case '\n': Result += "\\n"; break; case '\r': Result += "\\r"; break; case '\t': Result += "\\t"; break; - case '\v': Result += "\\v"; break; default: Result += '\\'; Result += toOctal(C >> 6); From lattner at cs.uiuc.edu Mon Aug 4 00:04:41 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:41 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200308032337.SAA03295@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.51 -> 1.52 --- Log message: * Sort #includes, remove dupliates * Use .zero to emit padding between struct elements * Emit .comm symbols when we can, this dramatically reduces the amount of gunk we have to print * Print global variable identifiers next to initializer more nicely. --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.51 llvm/lib/Target/X86/Printer.cpp:1.52 --- llvm/lib/Target/X86/Printer.cpp:1.51 Thu Jul 31 12:38:52 2003 +++ llvm/lib/Target/X86/Printer.cpp Sun Aug 3 18:37:09 2003 @@ -9,19 +9,17 @@ #include "X86.h" #include "X86InstrInfo.h" -#include "llvm/Function.h" -#include "llvm/Constant.h" +#include "llvm/Module.h" +#include "llvm/Type.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Type.h" -#include "llvm/Constants.h" #include "llvm/Assembly/Writer.h" -#include "llvm/DerivedTypes.h" -#include "Support/StringExtras.h" -#include "llvm/Module.h" #include "llvm/Support/Mangler.h" +#include "Support/StringExtras.h" namespace { struct Printer : public MachineFunctionPass { @@ -329,7 +327,7 @@ if (CVA && isStringCompatible(CVA)) { // print the string alone and return - O << "\t" << ".string" << "\t" << getAsCString(CVA) << "\n"; + O << "\t.string\t" << getAsCString(CVA) << "\n"; } else if (CVA) { // Not a string. Print the values in successive locations @@ -363,18 +361,7 @@ else printSingleConstantValue(CV); - if (numPadBytesAfter) { - unsigned numBytes = numPadBytesAfter; - for ( ; numBytes >= 8; numBytes -= 8) - printSingleConstantValue(Constant::getNullValue(Type::ULongTy)); - if (numBytes >= 4) - { - printSingleConstantValue(Constant::getNullValue(Type::UIntTy)); - numBytes -= 4; - } - while (numBytes--) - printSingleConstantValue(Constant::getNullValue(Type::UByteTy)); - } + if (numPadBytesAfter) O << "\t.zero\t " << numPadBytesAfter << "\n"; } /// printConstantPool - Print to the current output stream assembly @@ -406,6 +393,7 @@ // BBs the same name. (If you have a better way, please let me know!) static unsigned BBNumber = 0; + O << "\n\n"; // What's my mangled name? CurrentFnName = Mang->getValueName(MF.getFunction()); @@ -938,24 +926,25 @@ std::string name(Mang->getValueName(I)); if (I->hasInitializer()) { Constant *C = I->getInitializer(); - O << "\t.data\n"; - O << "\t.globl " << name << "\n"; - O << "\t.type " << name << ", at object\n"; - O << "\t.size " << name << "," - << (unsigned)TD.getTypeSize(I->getType()) << "\n"; - O << "\t.align " << (unsigned)TD.getTypeAlignment(C->getType()) << "\n"; - O << name << ":\t\t\t\t\t#"; - // If this is a constant function pointer, we only print out the - // name of the function in the comment (because printing the - // function means calling AsmWriter to print the whole LLVM - // assembly, which would corrupt the X86 assembly output.) - // Otherwise we print out the whole llvm value as a comment. - if (const Function *F = isConstantFunctionPointerRef (C)) { - O << " %" << F->getName() << "()\n"; + if (C->isNullValue()) { + O << "\n\n\t.comm " << name << "," << TD.getTypeSize(C->getType()) + << "," << (unsigned)TD.getTypeAlignment(C->getType()); + O << "\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << "\n"; } else { - O << *C << "\n"; + O << "\n\n\t.data\n"; + O << "\t.globl " << name << "\n"; + O << "\t.type " << name << ", at object\n"; + O << "\t.size " << name << "," << TD.getTypeSize(C->getType()) << "\n"; + O << "\t.align " << (unsigned)TD.getTypeAlignment(C->getType()) << "\n"; + O << name << ":\t\t\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << " = "; + WriteAsOperand(O, C, false, false, &M); + O << "\n"; + printConstantValueOnly(C); } - printConstantValueOnly (C); } else { O << "\t.globl " << name << "\n"; O << "\t.comm " << name << ", " From lattner at cs.uiuc.edu Mon Aug 4 00:04:49 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:49 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200308040105.UAA09257@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.53 -> 1.54 --- Log message: Simplify some constant expressions --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.53 llvm/lib/Target/X86/Printer.cpp:1.54 --- llvm/lib/Target/X86/Printer.cpp:1.53 Sun Aug 3 18:42:17 2003 +++ llvm/lib/Target/X86/Printer.cpp Sun Aug 3 20:04:59 2003 @@ -119,16 +119,16 @@ /// and return this as a string. /// std::string Printer::ConstantExprToString(const ConstantExpr* CE) { - std::string S; const TargetData &TD = TM.getTargetData(); switch(CE->getOpcode()) { case Instruction::GetElementPtr: { // generate a symbolic expression for the byte address const Value* ptrVal = CE->getOperand(0); std::vector idxVec(CE->op_begin()+1, CE->op_end()); - S += "(" + valToExprString(ptrVal) + ") + (" - + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")"; - break; + if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) + return "(" + valToExprString(ptrVal) + ") + " + utostr(Offset); + else + return valToExprString(ptrVal); } case Instruction::Cast: @@ -143,23 +143,19 @@ || (isa(Ty) && (OpTy == Type::LongTy || OpTy == Type::ULongTy))) || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) - && (OpTy-> isLosslesslyConvertibleTo(Ty)))) + && (OpTy->isLosslesslyConvertibleTo(Ty)))) && "FIXME: Don't yet support this kind of constant cast expr"); - S += "(" + valToExprString(Op) + ")"; + return "(" + valToExprString(Op) + ")"; } - break; case Instruction::Add: - S += "(" + valToExprString(CE->getOperand(0)) + ") + (" - + valToExprString(CE->getOperand(1)) + ")"; - break; + return "(" + valToExprString(CE->getOperand(0)) + ") + (" + + valToExprString(CE->getOperand(1)) + ")"; default: assert(0 && "Unsupported operator in ConstantExprToString()"); - break; + return ""; } - - return S; } /// printSingleConstantValue - Print a single constant value. From lattner at cs.uiuc.edu Mon Aug 4 00:04:56 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:04:56 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExecutionDriver.cpp Message-ID: <200308040056.TAA30760@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExecutionDriver.cpp updated: 1.14 -> 1.15 --- Log message: Make sure to flush the output stream so that we get incremental updates --- Diffs of the changes: Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.14 llvm/tools/bugpoint/ExecutionDriver.cpp:1.15 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.14 Fri Aug 1 17:13:59 2003 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Sun Aug 3 19:56:43 2003 @@ -111,8 +111,8 @@ LLIArgs.push_back(InputArgv[i].c_str()); LLIArgs.push_back(0); - std::cout << ""; - DEBUG(std::cerr << "About to run:\n\t"; + std::cout << "" << std::flush; + DEBUG(std::cerr << "\nAbout to run:\n\t"; for (unsigned i=0, e = LLIArgs.size(); i != e; ++i) std::cerr << " " << LLIArgs[i]; std::cerr << "\n"; @@ -176,7 +176,7 @@ GCCArgs.push_back("-O2"); // Optimize the program a bit... GCCArgs.push_back(0); // NULL terminator - std::cout << ""; + std::cout << "" << std::flush; if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "/dev/null", "/dev/null", "/dev/null")) { ProcessFailure(&GCCArgs[0]); @@ -191,15 +191,14 @@ ProgramArgs.push_back(0); // NULL terminator // Now that we have a binary, run it! - std::cout << ""; - DEBUG(std::cerr << "About to run:\n\t"; + std::cout << "" << std::flush; + DEBUG(std::cerr << "\nAbout to run:\n\t"; for (unsigned i=0, e = ProgramArgs.size(); i != e; ++i) std::cerr << " " << ProgramArgs[i]; std::cerr << "\n"; ); int ProgramResult = RunProgramWithTimeout(OutputBinary, &ProgramArgs[0], InputFile, OutputFile, OutputFile); - std::cout << "\n"; removeFile(OutputBinary); return ProgramResult; } @@ -223,7 +222,7 @@ 0 }; - std::cout << ""; + std::cout << "" << std::flush; if(RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", "/dev/null", "/dev/null")) { ProcessFailure(GCCArgs); @@ -303,7 +302,7 @@ 0 }; - std::cout << ""; + std::cout << "" << std::flush; if (RunProgramWithTimeout(LLCPath, LLCArgs, "/dev/null", "/dev/null", "/dev/null")) { // If LLC failed on the bytecode, print error... @@ -374,8 +373,8 @@ JITArgs.push_back(InputArgv[i].c_str()); JITArgs.push_back(0); - std::cout << "\n"; - DEBUG(std::cerr << "About to run:\n\t"; + std::cout << "" << std::flush; + DEBUG(std::cerr << "\nAbout to run:\n\t"; for (unsigned i=0, e = JITArgs.size(); i != e; ++i) std::cerr << " " << JITArgs[i]; std::cerr << "\n"; @@ -436,7 +435,7 @@ 0 }; - std::cout << ""; + std::cout << "" << std::flush; if (RunProgramWithTimeout(DISPath, DisArgs, "/dev/null", "/dev/null", "/dev/null")) { // If dis failed on the bytecode, print error... From lattner at cs.uiuc.edu Mon Aug 4 00:05:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:05:04 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CodeGeneratorBug.cpp Message-ID: <200308040057.TAA30766@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CodeGeneratorBug.cpp updated: 1.10 -> 1.11 --- Log message: Print accurate run instructions for when testing LLC --- Diffs of the changes: Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.10 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.11 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.10 Sun Aug 3 17:29:43 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Sun Aug 3 19:56:27 2003 @@ -233,11 +233,25 @@ // Run the code generator on the `Test' code, loading the shared library. // The function returns whether or not the new output differs from reference. - int Result = BD.diffProgram(TestModuleBC, SharedObject, false); + int Result = BD.diffProgram(TestModuleBC, SharedObject, false); + + if (Result) + std::cerr << ": Still failing!\n"; + else + std::cerr << ": didn't fail.\n"; + + if (KeepFiles) { - std::cout << "You can reproduce the problem with the command line: \n" - << (BD.isExecutingJIT() ? "lli" : "llc") - << " -load " << SharedObject << " " << TestModuleBC; + std::cout << "You can reproduce the problem with the command line: \n"; + if (BD.isExecutingJIT()) { + std::cout << " lli -load " << SharedObject << " " << TestModuleBC; + } else { + //<< (BD.isExecutingJIT() ? "lli" : "llc") + std::cout << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; + std::cout << " gcc " << SharedObject << " " << TestModuleBC + << ".s -o " << TestModuleBC << ".exe\n"; + std::cout << " " << TestModuleBC << ".exe"; + } for (unsigned i=0, e = InputArgv.size(); i != e; ++i) std::cout << " " << InputArgv[i]; std::cout << "\n"; @@ -365,8 +379,8 @@ // Do the reduction... if (!ReduceMisCodegenFunctions(*this).reduceList(MisCodegenFunctions)) { - std::cerr << "*** Execution matches reference output! No problem " - << "detected...\nbugpoint can't help you with your problem!\n"; + std::cerr << "*** Execution matches reference output! " + << "bugpoint can't help you with your problem!\n"; return false; } From sabre at nondot.org Mon Aug 4 00:05:24 2003 From: sabre at nondot.org (Chris Lattner) Date: Mon Aug 4 00:05:24 2003 Subject: [llvm-commits] test Message-ID: This is only a test -Chris -- http://llvm.cs.uiuc.edu/ http://www.nondot.org/~sabre/Projects/ From lattner at cs.uiuc.edu Mon Aug 4 00:05:31 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:05:31 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200308040212.VAA12351@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.118 -> 1.119 --- Log message: Fix Bug: test/Regression/Jello/2003-08-03-CallArgLiveRanges.llx --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.118 llvm/lib/Target/X86/InstSelectSimple.cpp:1.119 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.118 Wed Jul 30 00:33:48 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun Aug 3 21:12:48 2003 @@ -122,9 +122,11 @@ void visitBranchInst(BranchInst &BI); struct ValueRecord { + Value *Val; unsigned Reg; const Type *Ty; - ValueRecord(unsigned R, const Type *T) : Reg(R), Ty(T) {} + ValueRecord(unsigned R, const Type *T) : Val(0), Reg(R), Ty(T) {} + ValueRecord(Value *V) : Val(V), Reg(0), Ty(V->getType()) {} }; void doCall(const ValueRecord &Ret, MachineInstr *CallMI, const std::vector &Args); @@ -679,24 +681,28 @@ /// operand, in the specified target register. void ISel::promote32(unsigned targetReg, const ValueRecord &VR) { bool isUnsigned = VR.Ty->isUnsigned(); + + // Make sure we have the register number for this value... + unsigned Reg = VR.Val ? getReg(VR.Val) : VR.Reg; + switch (getClassB(VR.Ty)) { case cByte: // Extend value into target register (8->32) if (isUnsigned) - BuildMI(BB, X86::MOVZXr32r8, 1, targetReg).addReg(VR.Reg); + BuildMI(BB, X86::MOVZXr32r8, 1, targetReg).addReg(Reg); else - BuildMI(BB, X86::MOVSXr32r8, 1, targetReg).addReg(VR.Reg); + BuildMI(BB, X86::MOVSXr32r8, 1, targetReg).addReg(Reg); break; case cShort: // Extend value into target register (16->32) if (isUnsigned) - BuildMI(BB, X86::MOVZXr32r16, 1, targetReg).addReg(VR.Reg); + BuildMI(BB, X86::MOVZXr32r16, 1, targetReg).addReg(Reg); else - BuildMI(BB, X86::MOVSXr32r16, 1, targetReg).addReg(VR.Reg); + BuildMI(BB, X86::MOVSXr32r16, 1, targetReg).addReg(Reg); break; case cInt: // Move value into target register (32->32) - BuildMI(BB, X86::MOVrr32, 1, targetReg).addReg(VR.Reg); + BuildMI(BB, X86::MOVrr32, 1, targetReg).addReg(Reg); break; default: assert(0 && "Unpromotable operand class in promote32"); @@ -848,7 +854,7 @@ // Arguments go on the stack in reverse order, as specified by the ABI. unsigned ArgOffset = 0; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - unsigned ArgReg = Args[i].Reg; + unsigned ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg; switch (getClassB(Args[i].Ty)) { case cByte: case cShort: { @@ -945,8 +951,7 @@ std::vector Args; for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i) - Args.push_back(ValueRecord(getReg(CI.getOperand(i)), - CI.getOperand(i)->getType())); + Args.push_back(ValueRecord(CI.getOperand(i))); unsigned DestReg = CI.getType() != Type::VoidTy ? getReg(CI) : 0; doCall(ValueRecord(DestReg, CI.getType()), TheCall, Args); @@ -1135,21 +1140,21 @@ /// instructions work differently for signed and unsigned operands. /// void ISel::visitDivRem(BinaryOperator &I) { - unsigned Class = getClass(I.getType()); - unsigned Op0Reg = getReg(I.getOperand(0)); - unsigned Op1Reg = getReg(I.getOperand(1)); - unsigned ResultReg = getReg(I); + unsigned Class = getClass(I.getType()); + unsigned Op0Reg, Op1Reg, ResultReg = getReg(I); switch (Class) { case cFP: // Floating point divide - if (I.getOpcode() == Instruction::Div) + if (I.getOpcode() == Instruction::Div) { + Op0Reg = getReg(I.getOperand(0)); + Op1Reg = getReg(I.getOperand(1)); BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg); - else { // Floating point remainder... + } else { // Floating point remainder... MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true); std::vector Args; - Args.push_back(ValueRecord(Op0Reg, Type::DoubleTy)); - Args.push_back(ValueRecord(Op1Reg, Type::DoubleTy)); + Args.push_back(ValueRecord(I.getOperand(0))); + Args.push_back(ValueRecord(I.getOperand(1))); doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args); } return; @@ -1163,8 +1168,8 @@ BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true); std::vector Args; - Args.push_back(ValueRecord(Op0Reg, Type::LongTy)); - Args.push_back(ValueRecord(Op1Reg, Type::LongTy)); + Args.push_back(ValueRecord(I.getOperand(0))); + Args.push_back(ValueRecord(I.getOperand(1))); doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args); return; } @@ -1189,6 +1194,7 @@ unsigned ExtReg = ExtRegs[Class]; // Put the first operand into one of the A registers... + Op0Reg = getReg(I.getOperand(0)); BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg); if (isSigned) { @@ -1202,6 +1208,7 @@ } // Emit the appropriate divide or remainder instruction... + Op1Reg = getReg(I.getOperand(1)); BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg); // Figure out which register we want to pick the result out of... @@ -2085,8 +2092,7 @@ /// void ISel::visitFreeInst(FreeInst &I) { std::vector Args; - Args.push_back(ValueRecord(getReg(I.getOperand(0)), - I.getOperand(0)->getType())); + Args.push_back(ValueRecord(I.getOperand(0))); MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("free", true); doCall(ValueRecord(0, Type::VoidTy), TheCall, Args); From lattner at cs.uiuc.edu Mon Aug 4 00:05:41 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:05:41 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/2003-08-03-CallArgLiveRanges.llx Message-ID: <200308040211.VAA10475@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: 2003-08-03-CallArgLiveRanges.llx added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/Jello/2003-08-03-CallArgLiveRanges.llx diff -c /dev/null llvm/test/Regression/Jello/2003-08-03-CallArgLiveRanges.llx:1.1 *** /dev/null Sun Aug 3 21:11:15 2003 --- llvm/test/Regression/Jello/2003-08-03-CallArgLiveRanges.llx Sun Aug 3 21:11:05 2003 *************** *** 0 **** --- 1,15 ---- + ; The old instruction selector used to load all arguments to a call up in + ; registers, then start pushing them all onto the stack. This is bad news as + ; it makes a ton of annoying overlapping live ranges. This code should not + ; cause spills! + ; + ; RUN: as < %s | lli -stats 2>&1 | not grep spilled + + target endian = little + target pointersize = 32 + + int %test(int, int, int, int, int, int, int, int, int, int) { ret int 0 } + int %main() { + %X = call int %test(int 1, int 2, int 3, int 4, int 5, int 6, int 7, int 8, int 9, int 10) + ret int %X + } From lattner at cs.uiuc.edu Mon Aug 4 00:05:51 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:05:51 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Record.h Message-ID: <200308040454.XAA23983@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.23 -> 1.24 Record.h updated: 1.28 -> 1.29 --- Log message: It appears that somehow we forgot to add support for code variables. Fix bug: TableGen/2003-08-03-PassCode.td --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.23 llvm/utils/TableGen/Record.cpp:1.24 --- llvm/utils/TableGen/Record.cpp:1.23 Sun Aug 3 23:50:57 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 3 23:53:50 2003 @@ -146,6 +146,12 @@ return 0; } +Init *CodeRecTy::convertValue(TypedInit *TI) { + if (TI->getType()->typeIsConvertibleTo(this)) + return TI; + return 0; +} + Init *DagRecTy::convertValue(TypedInit *TI) { if (TI->getType()->typeIsConvertibleTo(this)) return TI; Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.28 llvm/utils/TableGen/Record.h:1.29 --- llvm/utils/TableGen/Record.h:1.28 Sun Aug 3 23:50:57 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 3 23:53:50 2003 @@ -207,6 +207,7 @@ struct CodeRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue( CodeInit *CI) { return (Init*)CI; } + Init *convertValue(TypedInit *TI); void print(std::ostream &OS) const { OS << "code"; } From lattner at cs.uiuc.edu Mon Aug 4 00:28:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:28:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td X86RegisterInfo.td X86.td Message-ID: <200308040500.AAA24691@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.1 -> 1.2 X86RegisterInfo.td updated: 1.3 -> 1.4 X86.td updated: 1.3 -> 1.4 --- Log message: transition to using let instead of set --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.1 llvm/lib/Target/X86/X86InstrInfo.td:1.2 --- llvm/lib/Target/X86/X86InstrInfo.td:1.1 Sun Aug 3 16:54:21 2003 +++ llvm/lib/Target/X86/X86InstrInfo.td Sun Aug 3 23:59:56 2003 @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// - - // Format specifies the encoding used by the instruction. This is part of the // ad-hoc solution used to emit machine instruction encodings by our machine // code emitter. @@ -55,9 +53,9 @@ class X86Inst opcod, Format f, ArgType a> : Instruction { - set Namespace = "X86"; + let Namespace = "X86"; - set Name = nam; + let Name = nam; bits<8> Opcode = opcod; Format Form = f; bits<5> FormBits = Form.Value; @@ -65,7 +63,6 @@ bits<3> TypeBits = Type.Value; // Attributes specific to X86 instructions... - bit isVoid = 0; // Does this inst ignore the return value? bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix? bit printImplicitUses = 0; // Should we print implicit uses of this inst? @@ -101,8 +98,7 @@ def PHI : X86Inst<"PHI", 0, Pseudo, NoArg>; // PHI node... -set isVoid = 1 in - def NOOP : X86Inst<"nop", 0x90, RawFrm, NoArg>; // nop +def NOOP : X86Inst<"nop", 0x90, RawFrm, NoArg>; // nop def ADJCALLSTACKDOWN : X86Inst<"ADJCALLSTACKDOWN", 0, Pseudo, NoArg>; def ADJCALLSTACKUP : X86Inst<"ADJCALLSTACKUP", 0, Pseudo, NoArg>; @@ -113,11 +109,11 @@ // // Return instruction... -set isTerminator = 1, isVoid = 1, isReturn = 1 in +let isTerminator = 1, isReturn = 1 in def RET : X86Inst<"ret", 0xC3, RawFrm, NoArg>; // All branches are RawFrm, Void, Branch, and Terminators -set isVoid = 1, isBranch = 1, isTerminator = 1 in +let isBranch = 1, isTerminator = 1 in class IBr opcode> : X86Inst; def JMP : IBr<"jmp", 0xE9>; @@ -136,9 +132,9 @@ //===----------------------------------------------------------------------===// // Call Instructions... // -set isCall = 1, isVoid = 1 in +let isCall = 1 in // All calls clobber the non-callee saved registers... - set Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6] in { + let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6] in { def CALLpcrel32 : X86Inst<"call", 0xE8, RawFrm, NoArg>; def CALLr32 : X86Inst<"call", 0xFF, MRMS2r, Arg32>; def CALLm32 : X86Inst<"call", 0xFF, MRMS2m, Arg32>; @@ -150,7 +146,7 @@ // def LEAVE : X86Inst<"leave", 0xC9, RawFrm, NoArg>, Imp<[EBP], [EBP]>; -set isTwoAddress = 1 in // R32 = bswap R32 +let isTwoAddress = 1 in // R32 = bswap R32 def BSWAPr32 : X86Inst<"bswap", 0xC8, AddRegFrm, Arg32>, TB; def XCHGrr8 : X86Inst<"xchg", 0x86, MRMDestReg, Arg8>; // xchg R8, R8 @@ -177,42 +173,39 @@ def MOVmr16 : X86Inst<"mov", 0x8B, MRMSrcMem , Arg16>, OpSize; // R16 = [mem] def MOVmr32 : X86Inst<"mov", 0x8B, MRMSrcMem , Arg32>; // R32 = [mem] -set isVoid = 1 in { - def MOVrm8 : X86Inst<"mov", 0x88, MRMDestMem, Arg8>; // R8 = [mem] - def MOVrm16 : X86Inst<"mov", 0x89, MRMDestMem, Arg16>, OpSize; // R16 = [mem] - def MOVrm32 : X86Inst<"mov", 0x89, MRMDestMem, Arg32>; // R32 = [mem] -} +def MOVrm8 : X86Inst<"mov", 0x88, MRMDestMem, Arg8>; // [mem] = R8 +def MOVrm16 : X86Inst<"mov", 0x89, MRMDestMem, Arg16>, OpSize; // [mem] = R16 +def MOVrm32 : X86Inst<"mov", 0x89, MRMDestMem, Arg32>; // [mem] = R32 //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... // -set isVoid = 1 in { - // Extra precision multiplication - def MULr8 : X86Inst<"mul", 0xF6, MRMS4r, Arg8 >, Imp<[AL],[AX]>; // AL,AH = AL*R8 - def MULr16 : X86Inst<"mul", 0xF7, MRMS4r, Arg16>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16 - def MULr32 : X86Inst<"mul", 0xF7, MRMS4r, Arg32>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32 - - // unsigned division/remainder - def DIVr8 : X86Inst<"div", 0xF6, MRMS6r, Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH - def DIVr16 : X86Inst<"div", 0xF7, MRMS6r, Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX - def DIVr32 : X86Inst<"div", 0xF7, MRMS6r, Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX - - // signed division/remainder - def IDIVr8 : X86Inst<"idiv",0xF6, MRMS7r, Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH - def IDIVr16: X86Inst<"idiv",0xF7, MRMS7r, Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX - def IDIVr32: X86Inst<"idiv",0xF7, MRMS7r, Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX - - // Sign-extenders for division - def CBW : X86Inst<"cbw", 0x98, RawFrm, Arg8 >, Imp<[AL],[AH]>; // AX = signext(AL) - def CWD : X86Inst<"cwd", 0x99, RawFrm, Arg8 >, Imp<[AX],[DX]>; // DX:AX = signext(AX) - def CDQ : X86Inst<"cdq", 0x99, RawFrm, Arg8 >, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX) -} + +// Extra precision multiplication +def MULr8 : X86Inst<"mul", 0xF6, MRMS4r, Arg8 >, Imp<[AL],[AX]>; // AL,AH = AL*R8 +def MULr16 : X86Inst<"mul", 0xF7, MRMS4r, Arg16>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16 +def MULr32 : X86Inst<"mul", 0xF7, MRMS4r, Arg32>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32 + +// unsigned division/remainder +def DIVr8 : X86Inst<"div", 0xF6, MRMS6r, Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH +def DIVr16 : X86Inst<"div", 0xF7, MRMS6r, Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX +def DIVr32 : X86Inst<"div", 0xF7, MRMS6r, Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX + +// signed division/remainder +def IDIVr8 : X86Inst<"idiv",0xF6, MRMS7r, Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH +def IDIVr16: X86Inst<"idiv",0xF7, MRMS7r, Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX +def IDIVr32: X86Inst<"idiv",0xF7, MRMS7r, Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX + +// Sign-extenders for division +def CBW : X86Inst<"cbw", 0x98, RawFrm, Arg8 >, Imp<[AL],[AH]>; // AX = signext(AL) +def CWD : X86Inst<"cwd", 0x99, RawFrm, Arg8 >, Imp<[AX],[DX]>; // DX:AX = signext(AX) +def CDQ : X86Inst<"cdq", 0x99, RawFrm, Arg8 >, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX) //===----------------------------------------------------------------------===// // Two address Instructions... // -set isTwoAddress = 1 in { // Define some helper classes to make defs shorter. +let isTwoAddress = 1 in { // Define some helper classes to make defs shorter. class I2A8 o, Format F> : X86Inst; class I2A16 o, Format F> : X86Inst; class I2A32 o, Format F> : X86Inst; @@ -237,8 +230,8 @@ def SBBrr32 : I2A32<"sbb", 0x19, MRMDestReg>; // R32 -= R32+Carry -def IMULr16 : I2A16<"imul", 0xAF, MRMSrcReg>, TB, OpSize; // R16 *= R16 -def IMULr32 : I2A32<"imul", 0xAF, MRMSrcReg>, TB; // R32 *= R32 +def IMULr16 : I2A16<"imul", 0xAF, MRMSrcReg>, TB, OpSize; // R16 *= R16 +def IMULr32 : I2A32<"imul", 0xAF, MRMSrcReg>, TB; // R32 *= R32 // Logical operators... def ANDrr8 : I2A8 <"and", 0x20, MRMDestReg>; // R8 &= R8 @@ -316,14 +309,12 @@ def CMOVNErr32: I2A32<"cmovne",0x45, MRMSrcReg>, TB; // if !=, R32 = R32 // Integer comparisons -set isVoid = 1 in { - def CMPrr8 : X86Inst<"cmp", 0x38, MRMDestReg, Arg8 >; // compare R8, R8 - def CMPrr16 : X86Inst<"cmp", 0x39, MRMDestReg, Arg16>, OpSize; // compare R16, R16 - def CMPrr32 : X86Inst<"cmp", 0x39, MRMDestReg, Arg32>; // compare R32, R32 - def CMPri8 : X86Inst<"cmp", 0x80, MRMS7r , Arg8 >; // compare R8, imm8 - def CMPri16 : X86Inst<"cmp", 0x81, MRMS7r , Arg16>, OpSize; // compare R16, imm16 - def CMPri32 : X86Inst<"cmp", 0x81, MRMS7r , Arg32>; // compare R32, imm32 -} +def CMPrr8 : X86Inst<"cmp", 0x38, MRMDestReg, Arg8 >; // compare R8, R8 +def CMPrr16 : X86Inst<"cmp", 0x39, MRMDestReg, Arg16>, OpSize; // compare R16, R16 +def CMPrr32 : X86Inst<"cmp", 0x39, MRMDestReg, Arg32>; // compare R32, R32 +def CMPri8 : X86Inst<"cmp", 0x80, MRMS7r , Arg8 >; // compare R8, imm8 +def CMPri16 : X86Inst<"cmp", 0x81, MRMS7r , Arg16>, OpSize; // compare R16, imm16 +def CMPri32 : X86Inst<"cmp", 0x81, MRMS7r , Arg32>; // compare R32, imm32 // Sign/Zero extenders def MOVSXr16r8 : X86Inst<"movsx", 0xBE, MRMSrcReg, Arg8>, TB, OpSize; // R16 = signext(R8) @@ -342,7 +333,7 @@ // Floating point pseudo instructions... class FPInst o, Format F, ArgType t, FPFormat fp> - : X86Inst { set FPForm = fp; set FPFormBits = FPForm.Value; } + : X86Inst { let FPForm = fp; let FPFormBits = FPForm.Value; } def FpMOV : FPInst<"FMOV", 0, Pseudo, ArgF80, SpecialFP>; // f1 = fmov f2 def FpADD : FPInst<"FADD", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fadd f2, f3 @@ -350,40 +341,36 @@ def FpMUL : FPInst<"FMUL", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fmul f2, f3 def FpDIV : FPInst<"FDIV", 0, Pseudo, ArgF80, TwoArgFP>; // f1 = fdiv f2, f3 -set isVoid = 1 in - def FpUCOM : FPInst<"FUCOM", 0, Pseudo, ArgF80, TwoArgFP>; // FPSW = fucom f1, f2 +def FpUCOM : FPInst<"FUCOM", 0, Pseudo, ArgF80, TwoArgFP>; // FPSW = fucom f1, f2 def FpGETRESULT : FPInst<"FGETRESULT",0, Pseudo, ArgF80, SpecialFP>; // FPR = ST(0) -set isVoid = 1 in - def FpSETRESULT : FPInst<"FSETRESULT",0, Pseudo, ArgF80, SpecialFP>; // ST(0) = FPR +def FpSETRESULT : FPInst<"FSETRESULT",0, Pseudo, ArgF80, SpecialFP>; // ST(0) = FPR // Floating point loads & stores... def FLDrr : FPInst<"fld" , 0xC0, AddRegFrm, ArgF80, NotFP>, D9; // push(ST(i)) -def FLDr32 : FPInst<"fld" , 0xD9, MRMS0m , ArgF32, ZeroArgFP>; // load float -def FLDr64 : FPInst<"fld" , 0xDD, MRMS0m , ArgF64, ZeroArgFP>; // load double -def FLDr80 : FPInst<"fld" , 0xDB, MRMS5m , ArgF80, ZeroArgFP>; // load extended -def FILDr16 : FPInst<"fild" , 0xDF, MRMS0m , Arg16 , ZeroArgFP>; // load signed short -def FILDr32 : FPInst<"fild" , 0xDB, MRMS0m , Arg32 , ZeroArgFP>; // load signed int -def FILDr64 : FPInst<"fild" , 0xDF, MRMS5m , Arg64 , ZeroArgFP>; // load signed long - -set isVoid = 1 in { - def FSTr32 : FPInst<"fst" , 0xD9, MRMS2m , ArgF32, OneArgFP>; // store float - def FSTr64 : FPInst<"fst" , 0xDD, MRMS2m , ArgF64, OneArgFP>; // store double - def FSTPr32 : FPInst<"fstp", 0xD9, MRMS3m , ArgF32, OneArgFP>; // store float, pop - def FSTPr64 : FPInst<"fstp", 0xDD, MRMS3m , ArgF64, OneArgFP>; // store double, pop - def FSTPr80 : FPInst<"fstp", 0xDB, MRMS7m , ArgF80, OneArgFP>; // store extended, pop - def FSTrr : FPInst<"fst" , 0xD0, AddRegFrm, ArgF80, NotFP >, DD; // ST(i) = ST(0) - def FSTPrr : FPInst<"fstp", 0xD8, AddRegFrm, ArgF80, NotFP >, DD; // ST(i) = ST(0), pop - - def FISTr16 : FPInst<"fist", 0xDF, MRMS2m, Arg16 , OneArgFP>; // store signed short - def FISTr32 : FPInst<"fist", 0xDB, MRMS2m, Arg32 , OneArgFP>; // store signed int - def FISTPr16 : FPInst<"fistp", 0xDF, MRMS3m, Arg16 , NotFP >; // store signed short, pop - def FISTPr32 : FPInst<"fistp", 0xDB, MRMS3m, Arg32 , NotFP >; // store signed int, pop - def FISTPr64 : FPInst<"fistpll", 0xDF, MRMS7m, Arg64 , OneArgFP>; // store signed long, pop +def FLDr32 : FPInst<"fld" , 0xD9, MRMS0m , ArgF32, ZeroArgFP>; // load float +def FLDr64 : FPInst<"fld" , 0xDD, MRMS0m , ArgF64, ZeroArgFP>; // load double +def FLDr80 : FPInst<"fld" , 0xDB, MRMS5m , ArgF80, ZeroArgFP>; // load extended +def FILDr16 : FPInst<"fild" , 0xDF, MRMS0m , Arg16 , ZeroArgFP>; // load signed short +def FILDr32 : FPInst<"fild" , 0xDB, MRMS0m , Arg32 , ZeroArgFP>; // load signed int +def FILDr64 : FPInst<"fild" , 0xDF, MRMS5m , Arg64 , ZeroArgFP>; // load signed long + +def FSTr32 : FPInst<"fst" , 0xD9, MRMS2m , ArgF32, OneArgFP>; // store float +def FSTr64 : FPInst<"fst" , 0xDD, MRMS2m , ArgF64, OneArgFP>; // store double +def FSTPr32 : FPInst<"fstp", 0xD9, MRMS3m , ArgF32, OneArgFP>; // store float, pop +def FSTPr64 : FPInst<"fstp", 0xDD, MRMS3m , ArgF64, OneArgFP>; // store double, pop +def FSTPr80 : FPInst<"fstp", 0xDB, MRMS7m , ArgF80, OneArgFP>; // store extended, pop +def FSTrr : FPInst<"fst" , 0xD0, AddRegFrm, ArgF80, NotFP >, DD; // ST(i) = ST(0) +def FSTPrr : FPInst<"fstp", 0xD8, AddRegFrm, ArgF80, NotFP >, DD; // ST(i) = ST(0), pop + +def FISTr16 : FPInst<"fist", 0xDF, MRMS2m, Arg16 , OneArgFP>; // store signed short +def FISTr32 : FPInst<"fist", 0xDB, MRMS2m, Arg32 , OneArgFP>; // store signed int +def FISTPr16 : FPInst<"fistp", 0xDF, MRMS3m, Arg16 , NotFP >; // store signed short, pop +def FISTPr32 : FPInst<"fistp", 0xDB, MRMS3m, Arg32 , NotFP >; // store signed int, pop +def FISTPr64 : FPInst<"fistpll", 0xDF, MRMS7m, Arg64 , OneArgFP>; // store signed long, pop - def FXCH : FPInst<"fxch", 0xC8, AddRegFrm, ArgF80, NotFP>, D9; // fxch ST(i), ST(0) -} +def FXCH : FPInst<"fxch", 0xC8, AddRegFrm, ArgF80, NotFP>, D9; // fxch ST(i), ST(0) // Floating point constant loads... def FLD0 : FPInst<"fldz", 0xEE, RawFrm, ArgF80, ZeroArgFP>, D9; @@ -430,13 +417,11 @@ def FDIVRPrST0 : FPrST0PInst<"fdivrp", 0xF0>; // ST(i) = ST(0) / ST(i), pop // Floating point compares -set isVoid = 1 in { - def FUCOMr : X86Inst<"fucom" , 0xE0, AddRegFrm, ArgF80>, DD, Imp<[ST0],[]>; // FPSW = compare ST(0) with ST(i) - def FUCOMPr : X86Inst<"fucomp" , 0xE8, AddRegFrm, ArgF80>, DD, Imp<[ST0],[]>; // FPSW = compare ST(0) with ST(i), pop - def FUCOMPPr : X86Inst<"fucompp", 0xE9, RawFrm , ArgF80>, DA, Imp<[ST0],[]>; // compare ST(0) with ST(1), pop, pop - - // Floating point flag ops - def FNSTSWr8 : X86Inst<"fnstsw" , 0xE0, RawFrm , ArgF80>, DF, Imp<[],[AX]>; // AX = fp flags - def FNSTCWm16 : X86Inst<"fnstcw" , 0xD9, MRMS7m , Arg16 >; // [mem16] = X87 control world - def FLDCWm16 : X86Inst<"fldcw" , 0xD9, MRMS5m , Arg16 >; // X87 control world = [mem16] -} +def FUCOMr : X86Inst<"fucom" , 0xE0, AddRegFrm, ArgF80>, DD, Imp<[ST0],[]>; // FPSW = compare ST(0) with ST(i) +def FUCOMPr : X86Inst<"fucomp" , 0xE8, AddRegFrm, ArgF80>, DD, Imp<[ST0],[]>; // FPSW = compare ST(0) with ST(i), pop +def FUCOMPPr : X86Inst<"fucompp", 0xE9, RawFrm , ArgF80>, DA, Imp<[ST0],[]>; // compare ST(0) with ST(1), pop, pop + +// Floating point flag ops +def FNSTSWr8 : X86Inst<"fnstsw" , 0xE0, RawFrm , ArgF80>, DF, Imp<[],[AX]>; // AX = fp flags +def FNSTCWm16 : X86Inst<"fnstcw" , 0xD9, MRMS7m , Arg16 >; // [mem16] = X87 control world +def FLDCWm16 : X86Inst<"fldcw" , 0xD9, MRMS5m , Arg16 >; // X87 control world = [mem16] Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.3 llvm/lib/Target/X86/X86RegisterInfo.td:1.4 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.3 Sun Aug 3 17:12:47 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.td Sun Aug 3 23:59:56 2003 @@ -9,7 +9,7 @@ //===----------------------------------------------------------------------===// // Register definitions... // -set Namespace = "X86" in { +let Namespace = "X86" in { // 32-bit registers def EAX : Register; def ECX : Register; def EDX : Register; def EBX : Register; @@ -71,7 +71,7 @@ // def r8 : RegisterClass; def r16 : RegisterClass { - set Methods = [{ + let Methods = [{ iterator allocation_order_end(MachineFunction &MF) const { if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? return end()-2; // If so, don't allocate SP or BP @@ -82,7 +82,7 @@ } def r32 : RegisterClass { - set Methods = [{ + let Methods = [{ iterator allocation_order_end(MachineFunction &MF) const { if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? return end()-2; // If so, don't allocate ESP or EBP Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.3 llvm/lib/Target/X86/X86.td:1.4 --- llvm/lib/Target/X86/X86.td:1.3 Sun Aug 3 16:54:21 2003 +++ llvm/lib/Target/X86/X86.td Sun Aug 3 23:59:56 2003 @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -// Get the target independent interfaces which we are implementing... +// Get the target-independent interfaces which we are implementing... // include "../Target.td" @@ -22,24 +22,24 @@ include "X86InstrInfo.td" def X86InstrInfo : InstrInfo { - set PHIInst = PHI; - set NOOPInst = NOOP; + let PHIInst = PHI; + let NOOPInst = NOOP; // Define how we want to layout our TargetSpecific information field... This // should be kept up-to-date with the fields in the X86InstrInfo.h file. - set TSFlagsFields = ["FormBits", "isVoid", "hasOpSizePrefix", "Prefix", + let TSFlagsFields = ["FormBits", "hasOpSizePrefix", "Prefix", "TypeBits", "FPFormBits", "printImplicitUses", "Opcode"]; - set TSFlagsShifts = [ 0, 5, 6, 7, + let TSFlagsShifts = [ 0, 6, 7, 11, 14, 17, 18]; } def X86 : Target { // Specify the callee saved registers. - set CalleeSavedRegisters = [ESI, EDI, EBX, EBP]; + let CalleeSavedRegisters = [ESI, EDI, EBX, EBP]; // Yes, pointers are 32-bits in size. - set PointerType = i32; + let PointerType = i32; // Information about the instructions... - set InstructionSet = X86InstrInfo; + let InstructionSet = X86InstrInfo; } From lattner at cs.uiuc.edu Mon Aug 4 00:28:32 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:28:32 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308040511.AAA25340@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.12 -> 1.13 --- Log message: There is nothing special about noops now --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.12 llvm/lib/Target/Target.td:1.13 --- llvm/lib/Target/Target.td:1.12 Sun Aug 3 23:58:12 2003 +++ llvm/lib/Target/Target.td Mon Aug 4 00:11:19 2003 @@ -110,7 +110,6 @@ // class InstrInfo { Instruction PHIInst; - Instruction NOOPInst; // If the target wants to associate some target-specific information with each // instruction, it should provide these two lists to indicate how to assemble From lattner at cs.uiuc.edu Mon Aug 4 00:28:46 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:28:46 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9.td SparcV9_F2.td SparcV9_F3.td SparcV9_F4.td SparcV9_Reg.td Message-ID: <200308040503.AAA24756@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcV9.td updated: 1.26 -> 1.27 SparcV9_F2.td updated: 1.4 -> 1.5 SparcV9_F3.td updated: 1.14 -> 1.15 SparcV9_F4.td updated: 1.7 -> 1.8 SparcV9_Reg.td updated: 1.3 -> 1.4 --- Log message: Transition to using 'let X = y' instead of 'set X = y'. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcV9.td diff -u llvm/lib/Target/Sparc/SparcV9.td:1.26 llvm/lib/Target/Sparc/SparcV9.td:1.27 --- llvm/lib/Target/Sparc/SparcV9.td:1.26 Wed Jul 30 16:00:37 2003 +++ llvm/lib/Target/Sparc/SparcV9.td Mon Aug 4 00:03:18 2003 @@ -13,10 +13,10 @@ class InstV9 : Instruction { // Sparc instruction baseline field bits<32> Inst; - set Namespace = "V9"; + let Namespace = "V9"; bits<2> op; - set Inst{31-30} = op; // Top two bits are the 'op' field + let Inst{31-30} = op; // Top two bits are the 'op' field // Bit attributes specific to Sparc instructions bit isPasi = 0; // Does this instruction affect an alternate addr space? @@ -43,7 +43,7 @@ def ADDCcci : F3_2<2, 0b011000, "addCcc">; // addCcc rs1, imm, rd // Section A.3: Branch on Integer Register with Prediction - p138 -set op2 = 0b011 in { +let op2 = 0b011 in { def BRZ : F2_4<0b001, "brz">; // Branch on rs1 == 0 def BRLEZ : F2_4<0b010, "brlez">; // Branch on rs1 <= 0 def BRLZ : F2_4<0b011, "brlz">; // Branch on rs1 < 0 @@ -55,8 +55,8 @@ // Section A.4: Branch on Floating-Point Condition Codes (FBfcc) p140 // The following deprecated instructions don't seem to play nice on Sparc /* -set isDeprecated = 1 in { - set op2 = 0b110 in { +let isDeprecated = 1 in { + let op2 = 0b110 in { def FBA : F2_2<0b1000, "fba">; // Branch always def FBN : F2_2<0b0000, "fbn">; // Branch never def FBU : F2_2<0b0111, "fbu">; // Branch on unordered @@ -78,7 +78,7 @@ */ // We now make these same opcodes represent the FBPfcc instructions -set op2 = 0b101 in { +let op2 = 0b101 in { def FBA : F2_3<0b1000, "fba">; // Branch always def FBN : F2_3<0b0000, "fbn">; // Branch never def FBU : F2_3<0b0111, "fbu">; // Branch on unordered @@ -100,7 +100,7 @@ // Section A.5: Branch on FP condition codes with prediction - p143 // Not used in the Sparc backend (directly) /* -set op2 = 0b101 in { +let op2 = 0b101 in { def FBPA : F2_3<0b1000, "fba">; // Branch always def FBPN : F2_3<0b0000, "fbn">; // Branch never def FBPU : F2_3<0b0111, "fbu">; // Branch on unordered @@ -122,8 +122,8 @@ // Section A.6: Branch on Integer condition codes (Bicc) - p146 /* -set isDeprecated = 1 in { - set op2 = 0b010 in { +let isDeprecated = 1 in { + let op2 = 0b010 in { def BA : F2_2<0b1000, "ba">; // Branch always def BN : F2_2<0b0000, "bn">; // Branch never def BNE : F2_2<0b1001, "bne">; // Branch != @@ -145,8 +145,8 @@ */ // Using the format of A.7 instructions... -set op2 = 0b001 in { - set cc = 0 in { // BA and BN don't read condition codes +let op2 = 0b001 in { + let cc = 0 in { // BA and BN don't read condition codes def BA : F2_3<0b1000, "ba">; // Branch always def BN : F2_3<0b0000, "bn">; // Branch never } @@ -169,7 +169,7 @@ // Section A.7: Branch on integer condition codes with prediction - p148 // Not used in the Sparc backend /* -set op2 = 0b001 in { +let op2 = 0b001 in { def BPA : F2_3<0b1000, "bpa">; // Branch always def BPN : F2_3<0b0000, "bpn">; // Branch never def BPNE : F2_3<0b1001, "bpne">; // Branch != @@ -192,10 +192,10 @@ // Section A.8: CALL - p151, the only Format #1 instruction def CALL : InstV9 { bits<30> disp; - set op = 1; - set Inst{29-0} = disp; - set Name = "call"; - set isCall = 1; + let op = 1; + let Inst{29-0} = disp; + let Name = "call"; + let isCall = 1; } // Section A.9: Compare and Swap - p176 @@ -205,7 +205,7 @@ // Section A.10: Divide (64-bit / 32-bit) - p178 // Not used in the Sparc backend /* -set isDeprecated = 1 in { +let isDeprecated = 1 in { def UDIVr : F3_1<2, 0b001110, "udiv">; // udiv r, r, r def UDIVi : F3_2<2, 0b001110, "udiv">; // udiv r, r, i def SDIVr : F3_1<2, 0b001111, "sdiv">; // sdiv r, r, r @@ -220,7 +220,7 @@ // Section A.11: DONE and RETRY - p181 // Not used in the Sparc backend /* -set isPrivileged = 1 in { +let isPrivileged = 1 in { def DONE : F3_18<0, "done">; // done def RETRY : F3_18<1, "retry">; // retry } @@ -321,13 +321,13 @@ def LDDFi : F3_2<3, 0b100011, "ldd">; // ldd [rs1+imm], rd def LDQFr : F3_1<3, 0b100010, "ldq">; // ldq [rs1+rs2], rd def LDQFi : F3_2<3, 0b100010, "ldq">; // ldq [rs1+imm], rd -set isDeprecated = 1 in { - set rd = 0 in { +let isDeprecated = 1 in { + let rd = 0 in { def LDFSRr : F3_1<3, 0b100001, "ld">; // ld [rs1+rs2], rd def LDFSRi : F3_2<3, 0b100001, "ld">; // ld [rs1+imm], rd } } -set rd = 1 in { +let rd = 1 in { def LDXFSRr : F3_1<3, 0b100001, "ldx">; // ldx [rs1+rs2], rd def LDXFSRi : F3_2<3, 0b100001, "ldx">; // ldx [rs1+imm], rd } @@ -349,7 +349,7 @@ def LDXr : F3_1<3, 0b001011, "ldx">; // ldx [rs1+rs2], rd def LDXi : F3_2<3, 0b001011, "ldx">; // ldx [rs1+imm], rd /* -set isDeprecated = 1 in { +let isDeprecated = 1 in { def LDDr : F3_1<3, 0b000011, "ldd">; // ldd [rs1+rs2], rd def LDDi : F3_2<3, 0b000011, "ldd">; // ldd [rs1+imm], rd } @@ -615,13 +615,13 @@ // Section A.38: Multiply (32-bit) - p200 // Not used in the Sparc backend /* -set Inst{13} = 0 in { +let Inst{13} = 0 in { def UMULr : F3_1<2, 0b001010, "umul">; // umul r, r, r def SMULr : F3_1<2, 0b001011, "smul">; // smul r, r, r def UMULCCr : F3_1<2, 0b011010, "umulcc">; // mulcc r, r, r def SMULCCr : F3_1<2, 0b011011, "smulcc">; // smulcc r, r, r } -set Inst{13} = 1 in { +let Inst{13} = 1 in { def UMULi : F3_1<2, 0b001010, "umul">; // umul r, i, r def SMULi : F3_1<2, 0b001011, "smul">; // smul r, i, r def UMULCCi : F3_1<2, 0b011010, "umulcc">; // umulcc r, i, r @@ -634,9 +634,9 @@ // Section A.40: No operation - p204 // NOP is really a pseudo-instruction (special case of SETHI) -set op2 = 0b100 in { - set rd = 0 in { - set imm = 0 in { +let op2 = 0b100 in { + let rd = 0 in { + let imm = 0 in { def NOP : F2_1<"nop">; // nop } } @@ -653,12 +653,12 @@ // Section A.44: Read State Register // The only instr from this section currently used is RDCCR -set rs1 = 2 in { +let rs1 = 2 in { def RDCCR : F3_17<2, 0b101000, "rd">; // rd %ccr, r } // Section A.45: RETURN - p216 -set isReturn = 1 in { +let isReturn = 1 in { def RETURNr : F3_3<2, 0b111001, "return">; // return def RETURNi : F3_4<2, 0b111001, "return">; // return } @@ -673,7 +673,7 @@ // Not currently used in Sparc backend // Section A.48: SETHI - p220 -set op2 = 0b100 in { +let op2 = 0b100 in { def SETHI : F2_1<"sethi">; // sethi } @@ -681,7 +681,7 @@ // Not currently used in the Sparc backend /* uses 5 least significant bits of rs2 -set x = 0 in { +let x = 0 in { def SLLr5 : F3_11<2, 0b100101, "sll">; // sll r, r, r def SRLr5 : F3_11<2, 0b100110, "srl">; // srl r, r, r def SRAr5 : F3_11<2, 0b100111, "sra">; // sra r, r, r @@ -692,12 +692,12 @@ */ // uses 6 least significant bits of rs2 -set x = 0 in { +let x = 0 in { def SLLr5 : F3_11<2, 0b100101, "sll">; // sll r, r, r def SRLr5 : F3_11<2, 0b100110, "srl">; // srl r, r, r def SRAr5 : F3_11<2, 0b100111, "sra">; // sra r, r, r } -set x = 1 in { +let x = 1 in { def SLLXr6 : F3_11<2, 0b100101, "sllx">; // sllx r, r, r def SRLXr6 : F3_11<2, 0b100110, "srlx">; // srlx r, r, r def SRAXr6 : F3_11<2, 0b100111, "srax">; // srax r, r, r @@ -733,7 +733,7 @@ // while STXFSRx expect rd=1, but assembly syntax dictates %fsr as first arg. // These are being disabled because they aren't used in the Sparc backend. /* -set isDeprecated = 1 in { +let isDeprecated = 1 in { def STFSRr : F3_1<3, 0b100101, "st">; // st %fsr, [r+r] def STFSRi : F3_2<3, 0b100101, "st">; // st %fsr, [r+i] } @@ -771,7 +771,7 @@ // FIXME: More...? // Section A.63: Write State Register - p244 -set rd = 2 in { +let rd = 2 in { def WRCCRr : F3_1<2, 0b110000, "wr">; // wr r, r, %y/ccr/etc def WRCCRi : F3_2<2, 0b110000, "wr">; // wr r, i, %y/ccr/etc } Index: llvm/lib/Target/Sparc/SparcV9_F2.td diff -u llvm/lib/Target/Sparc/SparcV9_F2.td:1.4 llvm/lib/Target/Sparc/SparcV9_F2.td:1.5 --- llvm/lib/Target/Sparc/SparcV9_F2.td:1.4 Tue Jul 15 16:26:49 2003 +++ llvm/lib/Target/Sparc/SparcV9_F2.td Mon Aug 4 00:03:18 2003 @@ -7,8 +7,8 @@ // class F2 : InstV9 { // Format 2 instructions bits<3> op2; - set op = 0; // Op = 0 - set Inst{24-22} = op2; + let op = 0; // Op = 0 + let Inst{24-22} = op2; } // Format 2.1 instructions @@ -16,23 +16,23 @@ bits<22> imm; bits<5> rd; - set Name = name; - set Inst{29-25} = rd; - set Inst{21-0} = imm; + let Name = name; + let Inst{29-25} = rd; + let Inst{21-0} = imm; } class F2_br : F2 { // Format 2 Branch instruction - set isBranch = 1; // All instances are branch instructions + let isBranch = 1; // All instances are branch instructions } class F2_2 cond, string name> : F2_br { // Format 2.2 instructions bits<22> disp; bit annul; - set Name = name; - set Inst{29} = annul; - set Inst{28-25} = cond; - set Inst{21-0} = disp; + let Name = name; + let Inst{29} = annul; + let Inst{28-25} = cond; + let Inst{21-0} = disp; } class F2_3 cond, string name> : F2_br { // Format 2.3 instructions @@ -41,12 +41,12 @@ bit predict = 1; bit annul; - set Name = name; - set Inst{29} = annul; - set Inst{28-25} = cond; - set Inst{21-20} = cc; - set Inst{19} = 1; // predict; - set Inst{18-0} = disp; + let Name = name; + let Inst{29} = annul; + let Inst{28-25} = cond; + let Inst{21-20} = cc; + let Inst{19} = 1; // predict; + let Inst{18-0} = disp; } class F2_4 rcond, string name> : F2_br { // Format 2.4 instructions @@ -55,12 +55,12 @@ bit predict = 1; bit annul; - set Name = name; - set Inst{29} = annul; - set Inst{28} = 0; - set Inst{27-25} = rcond; - set Inst{21-20} = disp{15-14}; - set Inst{19} = 1; // predict; - set Inst{18-14} = rs1; - set Inst{13-0 } = disp{13-0}; + let Name = name; + let Inst{29} = annul; + let Inst{28} = 0; + let Inst{27-25} = rcond; + let Inst{21-20} = disp{15-14}; + let Inst{19} = 1; // predict; + let Inst{18-14} = rs1; + let Inst{13-0 } = disp{13-0}; } Index: llvm/lib/Target/Sparc/SparcV9_F3.td diff -u llvm/lib/Target/Sparc/SparcV9_F3.td:1.14 llvm/lib/Target/Sparc/SparcV9_F3.td:1.15 --- llvm/lib/Target/Sparc/SparcV9_F3.td:1.14 Tue Jul 15 16:27:14 2003 +++ llvm/lib/Target/Sparc/SparcV9_F3.td Mon Aug 4 00:03:18 2003 @@ -10,79 +10,79 @@ // field. class F3 : InstV9 { bits<6> op3; - set op{1} = 1; // Op = 2 or 3 - set Inst{24-19} = op3; + let op{1} = 1; // Op = 2 or 3 + let Inst{24-19} = op3; } // F3_rs1 - Common class of instructions that have an rs1 field class F3_rs1 : F3 { bits<5> rs1; - set Inst{18-14} = rs1; + let Inst{18-14} = rs1; } // F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields class F3_rs1rs2 : F3_rs1 { bits<5> rs2; - set Inst{4-0} = rs2; + let Inst{4-0} = rs2; } // F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields class F3_rs1rs2rd : F3_rs1rs2 { bits<5> rd; - set Inst{29-25} = rd; + let Inst{29-25} = rd; } // F3_rs1simm13 - Common class of instructions that only have rs1 and simm13 class F3_rs1simm13 : F3_rs1 { bits<13> simm13; - set Inst{12-0} = simm13; + let Inst{12-0} = simm13; } class F3_rs1simm13rd : F3_rs1simm13 { bits<5> rd; - set Inst{29-25} = rd; + let Inst{29-25} = rd; } // F3_rs1rd - Common class of instructions that have an rs1 and rd fields class F3_rs1rd : F3_rs1 { bits<5> rd; - set Inst{29-25} = rd; + let Inst{29-25} = rd; } // F3_rs2 - Common class of instructions that don't use an rs1 class F3_rs2 : F3 { bits<5> rs2; - set Inst{4-0} = rs2; + let Inst{4-0} = rs2; } // F3_rs2rd - Common class of instructions that use rs2 and rd, but not rs1 class F3_rs2rd : F3_rs2 { bits<5> rd; - set Inst{29-25} = rd; + let Inst{29-25} = rd; } // F3_rd - Common class of instructions that have an rd field class F3_rd : F3 { bits<5> rd; - set Inst{29-25} = rd; + let Inst{29-25} = rd; } // F3_rdrs1 - Common class of instructions that have rd and rs1 fields class F3_rdrs1 : F3_rd { bits<5> rs1; - set Inst{18-14} = rs1; + let Inst{18-14} = rs1; } // F3_rdrs1simm13 - Common class of instructions that have rd, rs1, and simm13 class F3_rdrs1simm13 : F3_rdrs1 { bits<13> simm13; - set Inst{12-0} = simm13; + let Inst{12-0} = simm13; } // F3_rdrs1rs2 - Common class of instructions that have rd, rs1, and rs2 fields class F3_rdrs1rs2 : F3_rdrs1 { bits<5> rs2; - set Inst{4-0} = rs2; + let Inst{4-0} = rs2; } @@ -90,63 +90,63 @@ // class F3_1 opVal, bits<6> op3val, string name> : F3_rs1rs2rd { - set op = opVal; - set op3 = op3val; - set Name = name; - set Inst{13} = 0; // i field = 0 - set Inst{12-5} = 0; // don't care + let op = opVal; + let op3 = op3val; + let Name = name; + let Inst{13} = 0; // i field = 0 + let Inst{12-5} = 0; // don't care } // The store instructions seem to like to see rd first, then rs1 and rs2 class F3_1rd opVal, bits<6> op3val, string name> : F3_rdrs1rs2 { - set op = opVal; - set op3 = op3val; - set Name = name; - set Inst{13} = 0; // i field = 0 - set Inst{12-5} = 0; // don't care + let op = opVal; + let op3 = op3val; + let Name = name; + let Inst{13} = 0; // i field = 0 + let Inst{12-5} = 0; // don't care } class F3_2 opVal, bits<6> op3val, string name> : F3_rs1simm13rd { - set op = opVal; - set op3 = op3val; - set Name = name; - set Inst{13} = 1; // i field = 1 + let op = opVal; + let op3 = op3val; + let Name = name; + let Inst{13} = 1; // i field = 1 } // The store instructions seem to like to see rd first, then rs1 and imm class F3_2rd opVal, bits<6> op3val, string name> : F3_rdrs1simm13 { - set op = opVal; - set op3 = op3val; - set Name = name; - set Inst{13} = 1; // i field = 1 + let op = opVal; + let op3 = op3val; + let Name = name; + let Inst{13} = 1; // i field = 1 } class F3_3 opVal, bits<6> op3val, string name> : F3_rs1rs2 { - set op = opVal; - set op3 = op3val; - set Name = name; - set Inst{29-25} = 0; // don't care - set Inst{13} = 0; // i field = 0 - set Inst{12-5} = 0; // don't care + let op = opVal; + let op3 = op3val; + let Name = name; + let Inst{29-25} = 0; // don't care + let Inst{13} = 0; // i field = 0 + let Inst{12-5} = 0; // don't care } class F3_4 opVal, bits<6> op3Val, string name> : F3_rs1simm13 { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{29-25} = 0; // don't care - set Inst{13} = 1; // i field = 1 - set Inst{12-0} = simm13; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{29-25} = 0; // don't care + let Inst{13} = 1; // i field = 1 + let Inst{12-0} = simm13; } class F3_5 opVal, bits<6> op3Val, bits<3> rcondVal, string name> : F3_rs1rs2rd { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13} = 0; // i field = 0 - set Inst{12-10} = rcondVal; // rcond field - set Inst{9-5} = 0; // don't care + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13} = 0; // i field = 0 + let Inst{12-10} = rcondVal; // rcond field + let Inst{9-5} = 0; // don't care } class F3_6 opVal, bits<6> op3Val, bits<3> rcondVal, @@ -154,62 +154,62 @@ bits<10> simm10; bits<5> rd; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{29-25} = rd; - set Inst{13} = 1; // i field = 1 - set Inst{12-10} = rcondVal; // rcond field - set Inst{9-0} = simm10; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{29-25} = rd; + let Inst{13} = 1; // i field = 1 + let Inst{12-10} = rcondVal; // rcond field + let Inst{9-0} = simm10; } //FIXME: classes 7-10 not defined!! class F3_11 opVal, bits<6> op3Val, string name> : F3_rs1rs2rd { bit x; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13} = 0; // i field = 0 - set Inst{12} = x; - set Inst{11-5} = 0; // don't care + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13} = 0; // i field = 0 + let Inst{12} = x; + let Inst{11-5} = 0; // don't care } class F3_12 opVal, bits<6> op3Val, string name> : F3_rs1 { bits<5> shcnt; bits<5> rd; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{29-25} = rd; - set Inst{13} = 1; // i field = 1 - set Inst{12} = 0; // x field = 0 - set Inst{11-5} = 0; // don't care - set Inst{4-0} = shcnt; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{29-25} = rd; + let Inst{13} = 1; // i field = 1 + let Inst{12} = 0; // x field = 0 + let Inst{11-5} = 0; // don't care + let Inst{4-0} = shcnt; } class F3_13 opVal, bits<6> op3Val, string name> : F3_rs1 { bits<6> shcnt; bits<5> rd; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{29-25} = rd; - set Inst{13} = 1; // i field = 1 - set Inst{12} = 1; // x field = 1 - set Inst{11-6} = 0; // don't care - set Inst{5-0} = shcnt; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{29-25} = rd; + let Inst{13} = 1; // i field = 1 + let Inst{12} = 1; // x field = 1 + let Inst{11-6} = 0; // don't care + let Inst{5-0} = shcnt; } class F3_14 opVal, bits<6> op3Val, bits<9> opfVal, string name> : F3_rs2rd { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{18-14} = 0; // don't care - set Inst{13-5} = opfVal; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{18-14} = 0; // don't care + let Inst{13-5} = opfVal; } class F3_15 opVal, bits<6> op3Val, @@ -218,44 +218,44 @@ bits<5> rs1; bits<5> rs2; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{29-27} = 0; // defined to be zero - set Inst{26-25} = cc; - set Inst{18-14} = rs1; - set Inst{13-5} = opfVal; - set Inst{4-0} = rs2; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{29-27} = 0; // defined to be zero + let Inst{26-25} = cc; + let Inst{18-14} = rs1; + let Inst{13-5} = opfVal; + let Inst{4-0} = rs2; } class F3_16 opVal, bits<6> op3Val, bits<9> opfval, string name> : F3_rs1rs2rd { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13-5} = opfval; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13-5} = opfval; } class F3_17 opVal, bits<6> op3Val, string name> : F3_rs1rd { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13-0} = 0; // don't care + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13-0} = 0; // don't care } class F3_18 fcn, string name> : F3 { - set op = 2; - set op3 = 0b111110; - set Name = name; - set Inst{29-25} = fcn; - set Inst{18-0 } = 0; // don't care; + let op = 2; + let op3 = 0b111110; + let Name = name; + let Inst{29-25} = fcn; + let Inst{18-0 } = 0; // don't care; } class F3_19 opVal, bits<6> op3Val, string name> : F3_rd { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{18-0} = 0; // don't care + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{18-0} = 0; // don't care } // FIXME: class F3_20 Index: llvm/lib/Target/Sparc/SparcV9_F4.td diff -u llvm/lib/Target/Sparc/SparcV9_F4.td:1.7 llvm/lib/Target/Sparc/SparcV9_F4.td:1.8 --- llvm/lib/Target/Sparc/SparcV9_F4.td:1.7 Wed Jul 16 15:27:44 2003 +++ llvm/lib/Target/Sparc/SparcV9_F4.td Mon Aug 4 00:03:18 2003 @@ -8,25 +8,25 @@ // field. class F4 : InstV9 { bits<6> op3; - set Inst{24-19} = op3; + let Inst{24-19} = op3; } // F4_rs1 - Common class of instructions that use an rs1 field class F4_rs1 : F4 { bits<5> rs1; - set Inst{18-14} = rs1; + let Inst{18-14} = rs1; } // F4_rs1rs2 - Common class of instructions that have rs1 and rs2 fields class F4_rs1rs2 : F4_rs1 { bits<5> rs2; - set Inst{4-0} = rs2; + let Inst{4-0} = rs2; } // F4_rs1rs2rd - Common class of instructions that have 3 register operands class F4_rs1rs2rd : F4_rs1rs2 { bits<5> rd; - set Inst{29-25} = rd; + let Inst{29-25} = rd; } // F4_rs1rs2rd - Common class of instructions that have 2 reg and 1 imm operand @@ -34,22 +34,22 @@ bits<11> simm11; bits<5> rd; - set Inst{10-0} = simm11; - set Inst{29-25} = rd; + let Inst{10-0} = simm11; + let Inst{29-25} = rd; } // F4_cc - Common class of instructions that have a cond field class F4_cond : F4 { bits<4> cond; - set Inst{17-14} = cond; + let Inst{17-14} = cond; } // F4_cc - Common class of instructions that have cc register as first operand class F4_condcc : F4_cond { bits<3> cc; - set Inst{18} = cc{2}; - set Inst{12} = cc{1}; - set Inst{11} = cc{0}; + let Inst{18} = cc{2}; + let Inst{12} = cc{1}; + let Inst{11} = cc{0}; } // Actual F4 instruction classes @@ -57,22 +57,22 @@ class F4_1 opVal, bits<6> op3Val, string name> : F4_rs1rs2rd { bits<2> cc; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13} = 0; // i bit - set Inst{12-11} = cc; - set Inst{10-5} = 0; // don't care + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13} = 0; // i bit + let Inst{12-11} = cc; + let Inst{10-5} = 0; // don't care } class F4_2 opVal, bits<6> op3Val, string name> : F4_rs1simm11rd { bits<2> cc; - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13} = 1; // i bit - set Inst{12-11} = cc; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13} = 1; // i bit + let Inst{12-11} = cc; } class F4_3 opVal, bits<6> op3Val, bits<4> condVal, @@ -80,14 +80,14 @@ bits<5> rs2; bits<5> rd; - set op = opVal; - set op3 = op3Val; - set cond = condVal; - set Name = name; - set Inst{29-25} = rd; - set Inst{13} = 0; // i bit - set Inst{10-5} = 0; // don't care - set Inst{4-0} = rs2; + let op = opVal; + let op3 = op3Val; + let cond = condVal; + let Name = name; + let Inst{29-25} = rd; + let Inst{13} = 0; // i bit + let Inst{10-5} = 0; // don't care + let Inst{4-0} = rs2; } class F4_4 opVal, bits<6> op3Val, bits<4> condVal, @@ -95,25 +95,25 @@ bits<11> simm11; bits<5> rd; - set op = opVal; - set op3 = op3Val; - set cond = condVal; - set Name = name; - set Inst{29-25} = rd; - set Inst{13} = 1; // i bit - set Inst{10-0} = simm11; + let op = opVal; + let op3 = op3Val; + let cond = condVal; + let Name = name; + let Inst{29-25} = rd; + let Inst{13} = 1; // i bit + let Inst{10-0} = simm11; } // FIXME: class F4_5 class F4_6 opVal, bits<6> op3Val, bits<3> rcondVal, bits<5> opf_lowVal, string name> : F4_rs1rs2rd { - set op = opVal; - set op3 = op3Val; - set Name = name; - set Inst{13} = 0; - set Inst{12-10} = rcondVal; - set Inst{9-5} = opf_lowVal; + let op = opVal; + let op3 = op3Val; + let Name = name; + let Inst{13} = 0; + let Inst{12-10} = rcondVal; + let Inst{9-5} = opf_lowVal; } class F4_7 opVal, bits<6> op3Val, bits<4> condVal, @@ -122,15 +122,15 @@ bits<5> rs2; bits<5> rd; - set op = opVal; - set op3 = op3Val; - set cond = condVal; - set Name = name; - set Inst{29-25} = rd; - set Inst{18} = 0; - set Inst{13-11} = cc; - set Inst{10-5} = opf_lowVal; - set Inst{4-0} = rs2; + let op = opVal; + let op3 = op3Val; + let cond = condVal; + let Name = name; + let Inst{29-25} = rd; + let Inst{18} = 0; + let Inst{13-11} = cc; + let Inst{10-5} = opf_lowVal; + let Inst{4-0} = rs2; } // FIXME: F4 classes 8-9 Index: llvm/lib/Target/Sparc/SparcV9_Reg.td diff -u llvm/lib/Target/Sparc/SparcV9_Reg.td:1.3 llvm/lib/Target/Sparc/SparcV9_Reg.td:1.4 --- llvm/lib/Target/Sparc/SparcV9_Reg.td:1.3 Wed Jul 30 00:51:34 2003 +++ llvm/lib/Target/Sparc/SparcV9_Reg.td Mon Aug 4 00:03:18 2003 @@ -11,7 +11,7 @@ field bits<5> Num = num; // Numbers are identified with a 5 bit ID } -set Namespace = "SparcV9" in { +let Namespace = "SparcV9" in { def G0 : Ri< 0>; def G1 : Ri< 1>; def G2 : Ri< 2>; def G3 : Ri< 3>; def G4 : Ri< 4>; def G5 : Ri< 5>; def G6 : Ri< 6>; def G7 : Ri< 7>; def O0 : Ri< 8>; def O1 : Ri< 9>; def O2 : Ri<10>; def O3 : Ri<11>; From lattner at cs.uiuc.edu Mon Aug 4 00:28:57 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:28:57 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.td Message-ID: <200308040511.AAA25356@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.td updated: 1.4 -> 1.5 --- Log message: There is nothing special about noops anymore --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.4 llvm/lib/Target/X86/X86.td:1.5 --- llvm/lib/Target/X86/X86.td:1.4 Sun Aug 3 23:59:56 2003 +++ llvm/lib/Target/X86/X86.td Mon Aug 4 00:11:37 2003 @@ -23,7 +23,6 @@ def X86InstrInfo : InstrInfo { let PHIInst = PHI; - let NOOPInst = NOOP; // Define how we want to layout our TargetSpecific information field... This // should be kept up-to-date with the fields in the X86InstrInfo.h file. From lattner at cs.uiuc.edu Mon Aug 4 00:29:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:29:07 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l Message-ID: <200308040505.AAA25263@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.9 -> 1.10 --- Log message: Transition complete, remove the obsolete 'set' keyword --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.9 llvm/utils/TableGen/FileLexer.l:1.10 --- llvm/utils/TableGen/FileLexer.l:1.9 Sun Aug 3 23:56:53 2003 +++ llvm/utils/TableGen/FileLexer.l Mon Aug 4 00:04:52 2003 @@ -160,7 +160,6 @@ def { return DEF; } field { return FIELD; } let { return LET; } -set { return LET; } in { return IN; } {Identifier} { Filelval.StrVal = new std::string(yytext, yytext+yyleng); From lattner at cs.uiuc.edu Mon Aug 4 00:29:18 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:29:18 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/2003-08-03-PassCode.td Message-ID: <200308040453.XAA23967@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: 2003-08-03-PassCode.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/2003-08-03-PassCode.td diff -c /dev/null llvm/test/Regression/TableGen/2003-08-03-PassCode.td:1.1 *** /dev/null Sun Aug 3 23:53:23 2003 --- llvm/test/Regression/TableGen/2003-08-03-PassCode.td Sun Aug 3 23:53:13 2003 *************** *** 0 **** --- 1,7 ---- + // RUN: tblgen %s + + class test { + code Code = C; + } + + def foo : test<[{ hello world! }]>; From lattner at cs.uiuc.edu Mon Aug 4 00:29:30 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 00:29:30 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l FileParser.y Record.cpp Record.h Message-ID: <200308040451.XAA23044@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.7 -> 1.8 FileParser.y updated: 1.17 -> 1.18 Record.cpp updated: 1.22 -> 1.23 Record.h updated: 1.27 -> 1.28 --- Log message: Add initial support for a new 'dag' type --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.7 llvm/utils/TableGen/FileLexer.l:1.8 --- llvm/utils/TableGen/FileLexer.l:1.7 Sun Aug 3 13:12:59 2003 +++ llvm/utils/TableGen/FileLexer.l Sun Aug 3 23:50:57 2003 @@ -154,6 +154,7 @@ string { return STRING; } list { return LIST; } code { return CODE; } +dag { return DAG; } class { return CLASS; } def { return DEF; } Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.17 llvm/utils/TableGen/FileParser.y:1.18 --- llvm/utils/TableGen/FileParser.y:1.17 Sun Aug 3 13:17:22 2003 +++ llvm/utils/TableGen/FileParser.y Sun Aug 3 23:50:57 2003 @@ -168,7 +168,7 @@ std::vector *SubClassList; }; -%token INT BIT STRING BITS LIST CODE CLASS DEF FIELD SET IN +%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD SET IN %token INTVAL %token ID STRVAL CODEFRAGMENT @@ -209,6 +209,8 @@ $$ = new ListRecTy($3); } | CODE { // code type $$ = new CodeRecTy(); + } | DAG { // dag type + $$ = new DagRecTy(); } | ClassID { // Record Type $$ = new RecordRecTy($1); }; Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.22 llvm/utils/TableGen/Record.cpp:1.23 --- llvm/utils/TableGen/Record.cpp:1.22 Sun Aug 3 16:58:13 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 3 23:50:57 2003 @@ -146,6 +146,13 @@ return 0; } +Init *DagRecTy::convertValue(TypedInit *TI) { + if (TI->getType()->typeIsConvertibleTo(this)) + return TI; + return 0; +} + + void RecordRecTy::print(std::ostream &OS) const { OS << Rec->getName(); } Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.27 llvm/utils/TableGen/Record.h:1.28 --- llvm/utils/TableGen/Record.h:1.27 Sun Aug 3 16:58:13 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 3 23:50:57 2003 @@ -21,6 +21,7 @@ class StringRecTy; class ListRecTy; class CodeRecTy; +class DagRecTy; class RecordRecTy; // Init subclasses... @@ -82,6 +83,7 @@ virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; } + virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; @@ -212,6 +214,21 @@ return RHS->baseClassOf(this); } virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; } +}; + +/// DagRecTy - 'dag' - Represent a dag fragment +/// +struct DagRecTy : public RecTy { + Init *convertValue(UnsetInit *UI) { return (Init*)UI; } + //Init *convertValue( DagInit *CI) { return (Init*)CI; } + Init *convertValue(TypedInit *TI); + + void print(std::ostream &OS) const { OS << "dag"; } + + bool typeIsConvertibleTo(const RecTy *RHS) const { + return RHS->baseClassOf(this); + } + virtual bool baseClassOf(const DagRecTy *RHS) const { return true; } }; From criswell at cs.uiuc.edu Mon Aug 4 13:25:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 4 13:25:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CrashDebugger.cpp Message-ID: <200308041824.NAA14293@psmith.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CrashDebugger.cpp updated: 1.11 -> 1.12 --- Log message: Added code that ensures that we don't try to reduce an empty vector of basic blocks. This fixes the bugpoint regressions. --- Diffs of the changes: Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.11 llvm/tools/bugpoint/CrashDebugger.cpp:1.12 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.11 Tue Jun 24 23:13:52 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Mon Aug 4 13:24:31 2003 @@ -142,7 +142,7 @@ virtual TestResult doTest(std::vector &Prefix, std::vector &Kept) { - if (TestBlocks(Kept)) + if (!Kept.empty() && TestBlocks(Kept)) return KeepSuffix; if (!Prefix.empty() && TestBlocks(Prefix)) return KeepPrefix; From brukman at cs.uiuc.edu Mon Aug 4 14:04:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Aug 4 14:04:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/Miscompilation.cpp Message-ID: <200308041903.OAA22263@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: Miscompilation.cpp updated: 1.11 -> 1.12 --- Log message: Do not attempt to reduce a test case if it is an empty set. --- Diffs of the changes: Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.11 llvm/tools/bugpoint/Miscompilation.cpp:1.12 --- llvm/tools/bugpoint/Miscompilation.cpp:1.11 Wed Jul 30 15:15:56 2003 +++ llvm/tools/bugpoint/Miscompilation.cpp Mon Aug 4 14:03:42 2003 @@ -114,7 +114,7 @@ virtual TestResult doTest(std::vector &Prefix, std::vector &Suffix) { - if (TestFuncs(Suffix, false)) + if (!Suffix.empty() && TestFuncs(Suffix, false)) return KeepSuffix; if (!Prefix.empty() && TestFuncs(Prefix, false)) return KeepPrefix; From lattner at cs.uiuc.edu Mon Aug 4 14:48:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 14:48:04 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308041947.OAA27787@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.103 -> 1.104 --- Log message: * Don't print out HOW we are running Flex unless in verbose mode. We already hide the bison command line. * If running flex or bison gives us the files we already have, don't overwrite the ones we have, which cause unnecessary compilation. I demand the ability to make meaningless changes without penalty! --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.103 llvm/Makefile.common:1.104 --- llvm/Makefile.common:1.103 Thu Jul 31 15:58:51 2003 +++ llvm/Makefile.common Mon Aug 4 14:47:06 2003 @@ -766,10 +766,15 @@ # FIXME. (f.e. char Buffer[10000]; ) # %.cpp: %.l - $(FLEX) -t $< | $(SED) '/^find_rule/d' | \ + @echo Flex\'ing $<... + $(VERB) $(FLEX) -t $< | $(SED) '/^find_rule/d' | \ $(SED) 's/void yyunput/inline void yyunput/' | \ $(SED) 's/void \*yy_flex_realloc/inline void *yy_flex_realloc/' | \ - $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' > $@ + $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' \ + > $@.tmp + $(VERB) diff -q $@ $@.tmp || ${MV} -f $@.tmp $@ + @# remove the output of flex if it didn't get moved over... + @rm -f $@.tmp # Rule for building the bison parsers... %.c: %.y # Cancel built-in rules for yacc @@ -777,8 +782,10 @@ %.cpp %.h : %.y @echo Bison\'ing $<... $(VERB) $(BISON) -v -d -p $(<:%Parser.y=%) $*.y - $(VERB) ${MV} -f $*.tab.c $*.cpp - $(VERB) ${MV} -f $*.tab.h $*.h + $(VERB) diff -q $*.tab.c $*.cpp || ${MV} -f $*.tab.c $*.cpp + $(VERB) diff -q $*.tab.h $*.h || ${MV} -f $*.tab.h $*.h + @# If the files were not updated, don't leave them lying around... + @rm -f $*.tab.c $*.tab.h # To create the directories... %/.dir: From lattner at cs.uiuc.edu Mon Aug 4 14:49:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 14:49:02 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308041948.OAA27805@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.104 -> 1.105 --- Log message: While I'm looking at it, line up the SED lines --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.104 llvm/Makefile.common:1.105 --- llvm/Makefile.common:1.104 Mon Aug 4 14:47:06 2003 +++ llvm/Makefile.common Mon Aug 4 14:48:10 2003 @@ -767,8 +767,9 @@ # %.cpp: %.l @echo Flex\'ing $<... - $(VERB) $(FLEX) -t $< | $(SED) '/^find_rule/d' | \ - $(SED) 's/void yyunput/inline void yyunput/' | \ + $(VERB) $(FLEX) -t $< | \ + $(SED) '/^find_rule/d' | \ + $(SED) 's/void yyunput/inline void yyunput/' | \ $(SED) 's/void \*yy_flex_realloc/inline void *yy_flex_realloc/' | \ $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' \ > $@.tmp From lattner at cs.uiuc.edu Mon Aug 4 15:08:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 15:08:08 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308042007.PAA28352@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.105 -> 1.106 --- Log message: Urg, do not print "foo has changed" messages --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.105 llvm/Makefile.common:1.106 --- llvm/Makefile.common:1.105 Mon Aug 4 14:48:10 2003 +++ llvm/Makefile.common Mon Aug 4 15:07:01 2003 @@ -773,7 +773,7 @@ $(SED) 's/void \*yy_flex_realloc/inline void *yy_flex_realloc/' | \ $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' \ > $@.tmp - $(VERB) diff -q $@ $@.tmp || ${MV} -f $@.tmp $@ + $(VERB) diff -q $@ $@.tmp > /dev/null || ${MV} -f $@.tmp $@ @# remove the output of flex if it didn't get moved over... @rm -f $@.tmp @@ -783,8 +783,8 @@ %.cpp %.h : %.y @echo Bison\'ing $<... $(VERB) $(BISON) -v -d -p $(<:%Parser.y=%) $*.y - $(VERB) diff -q $*.tab.c $*.cpp || ${MV} -f $*.tab.c $*.cpp - $(VERB) diff -q $*.tab.h $*.h || ${MV} -f $*.tab.h $*.h + $(VERB) diff -q $*.tab.c $*.cpp > /dev/null || ${MV} -f $*.tab.c $*.cpp + $(VERB) diff -q $*.tab.h $*.h > /dev/null || ${MV} -f $*.tab.h $*.h @# If the files were not updated, don't leave them lying around... @rm -f $*.tab.c $*.tab.h From lattner at cs.uiuc.edu Mon Aug 4 15:09:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 15:09:02 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l Message-ID: <200308042008.PAA28369@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.10 -> 1.11 --- Log message: Update file header comment --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.10 llvm/utils/TableGen/FileLexer.l:1.11 --- llvm/utils/TableGen/FileLexer.l:1.10 Mon Aug 4 00:04:52 2003 +++ llvm/utils/TableGen/FileLexer.l Mon Aug 4 15:08:28 2003 @@ -1,7 +1,9 @@ /*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===// // +// This file defines a simple flex scanner for TableGen files. This is pretty +// straight-forward, except for the magic to handle file inclusion. // -//===------------------------------------------------------------------------=*/ +//===----------------------------------------------------------------------===*/ %option prefix="File" %option yylineno From lattner at cs.uiuc.edu Mon Aug 4 15:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 15:44:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/Tree.td Message-ID: <200308042043.PAA31012@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: Tree.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/Tree.td diff -c /dev/null llvm/test/Regression/TableGen/Tree.td:1.1 *** /dev/null Mon Aug 4 15:43:58 2003 --- llvm/test/Regression/TableGen/Tree.td Mon Aug 4 15:43:48 2003 *************** *** 0 **** --- 1,18 ---- + // This tests to make sure we can parse tree patterns. + // RUN: tblgen %s + + class TreeNode; + class RegisterClass; + + def set : TreeNode; + def plus : TreeNode; + def imm : TreeNode; + def R32 : RegisterClass; + + class Inst { + dag Pattern = T; + } + + def ADDrr32 : Inst<(set R32, (plus R32, R32))>; // a = b + c + def ADDri32 : Inst<(set R32, (plus R32, imm))>; // a = b + imm + From lattner at cs.uiuc.edu Mon Aug 4 15:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 15:45:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200308042044.PAA31052@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.19 -> 1.20 --- Log message: Parse DAG patterns --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.19 llvm/utils/TableGen/FileParser.y:1.20 --- llvm/utils/TableGen/FileParser.y:1.19 Sun Aug 3 23:56:53 2003 +++ llvm/utils/TableGen/FileParser.y Mon Aug 4 15:44:43 2003 @@ -161,6 +161,7 @@ int IntVal; RecTy *Ty; Init *Initializer; + std::vector *DagValueList; std::vector *FieldList; std::vector*BitList; Record *Rec; @@ -179,6 +180,7 @@ %type ClassList ClassListNE %type OptPrefix %type Value OptValue +%type DagArgList DagArgListNE %type ValueList ValueListNE %type BitList OptBitList RBitList %type Declaration OptID @@ -270,7 +272,29 @@ } $$ = new FieldInit($1, *$3); delete $3; + } | '(' ID DagArgList ')' { + Record *D = Records.getDef(*$2); + if (D == 0) { + err() << "Invalid def '" << *$2 << "'!\n"; + abort(); + } + $$ = new DagInit(D, *$3); + delete $2; delete $3; + }; + +DagArgListNE : Value { + $$ = new std::vector(); + $$->push_back($1); + } + | DagArgListNE ',' Value { + $1->push_back($3); }; + +DagArgList : /*empty*/ { + $$ = new std::vector(); + } + | DagArgListNE { $$ = $1; }; + RBitList : INTVAL { $$ = new std::vector(); From lattner at cs.uiuc.edu Mon Aug 4 15:45:09 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 15:45:09 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Record.cpp Message-ID: <200308042044.PAA31031@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.29 -> 1.30 Record.cpp updated: 1.24 -> 1.25 --- Log message: add support for DagInit initializers, which represent DAG patterns --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.29 llvm/utils/TableGen/Record.h:1.30 --- llvm/utils/TableGen/Record.h:1.29 Sun Aug 3 23:53:50 2003 +++ llvm/utils/TableGen/Record.h Mon Aug 4 15:44:17 2003 @@ -34,6 +34,7 @@ class CodeInit; class ListInit; class DefInit; +class DagInit; class TypedInit; class VarInit; class FieldInit; @@ -66,6 +67,7 @@ virtual Init *convertValue( CodeInit *CI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( DagInit *DI) { return 0; } virtual Init *convertValue( TypedInit *TI) { return 0; } virtual Init *convertValue( VarInit *VI) { return convertValue((TypedInit*)VI); @@ -221,7 +223,7 @@ /// struct DagRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } - //Init *convertValue( DagInit *CI) { return (Init*)CI; } + Init *convertValue( DagInit *CI) { return (Init*)CI; } Init *convertValue(TypedInit *TI); void print(std::ostream &OS) const { OS << "dag"; } @@ -582,6 +584,26 @@ } }; +/// DagInit - (def a, b) - Represent a DAG tree value. DAG inits are required +/// to have Records for their first value, after that, any legal Init is +/// possible. +/// +class DagInit : public Init { + Record *NodeTypeDef; + std::vector Args; +public: + DagInit(Record *D, std::vector &a) : NodeTypeDef(D) { + Args.swap(a); // DESTRUCTIVELY take the arguments + } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + Record *getNodeType() const { return NodeTypeDef; } + + virtual void print(std::ostream &OS) const; +}; //===----------------------------------------------------------------------===// // High-Level Classes Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.24 llvm/utils/TableGen/Record.cpp:1.25 --- llvm/utils/TableGen/Record.cpp:1.24 Sun Aug 3 23:53:50 2003 +++ llvm/utils/TableGen/Record.cpp Mon Aug 4 15:44:17 2003 @@ -434,6 +434,17 @@ } +void DagInit::print(std::ostream &OS) const { + OS << "(" << NodeTypeDef->getName(); + if (Args.size()) { + OS << " " << *Args[0]; + for (unsigned i = 1, e = Args.size(); i != e; ++i) + OS << ", " << *Args[i]; + } + OS << ")"; +} + + //===----------------------------------------------------------------------===// // Other implementations //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Mon Aug 4 15:59:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 15:59:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.td Message-ID: <200308042058.PAA32059@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.33 -> 1.34 X86RegisterInfo.td updated: 1.4 -> 1.5 --- Log message: Rename register classes to be upper case to make it obvious that they are X86 specific in the tree patterns --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.33 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.34 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.33 Sun Aug 3 10:48:14 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Mon Aug 4 15:58:29 2003 @@ -254,14 +254,14 @@ default: assert(0 && "Invalid type to getClass!"); case Type::BoolTyID: case Type::SByteTyID: - case Type::UByteTyID: return &r8Instance; + case Type::UByteTyID: return &R8Instance; case Type::ShortTyID: - case Type::UShortTyID: return &r16Instance; + case Type::UShortTyID: return &R16Instance; case Type::IntTyID: case Type::UIntTyID: - case Type::PointerTyID: return &r32Instance; + case Type::PointerTyID: return &R32Instance; case Type::FloatTyID: - case Type::DoubleTyID: return &rFPInstance; + case Type::DoubleTyID: return &RFPInstance; } } Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.4 llvm/lib/Target/X86/X86RegisterInfo.td:1.5 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.4 Sun Aug 3 23:59:56 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.td Mon Aug 4 15:58:29 2003 @@ -69,8 +69,8 @@ // top-level register classes. The order specified in the register list is // implicitly defined to be the register allocation order. // -def r8 : RegisterClass; -def r16 : RegisterClass { +def R8 : RegisterClass; +def R16 : RegisterClass { let Methods = [{ iterator allocation_order_end(MachineFunction &MF) const { if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? @@ -81,7 +81,7 @@ }]; } -def r32 : RegisterClass { +def R32 : RegisterClass { let Methods = [{ iterator allocation_order_end(MachineFunction &MF) const { if (hasFP(MF)) // Does the function dedicate EBP to being a frame ptr? @@ -92,7 +92,7 @@ }]; } -def rFP : RegisterClass; +def RFP : RegisterClass; // Registers which cannot be allocated... and are thus left unnamed. def : RegisterClass; From lattner at cs.uiuc.edu Mon Aug 4 16:08:10 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 16:08:10 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308042107.QAA32136@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.13 -> 1.14 --- Log message: Allow instructions to have a DAG pattern associated with them. Define a few preliminary node types. --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.13 llvm/lib/Target/Target.td:1.14 --- llvm/lib/Target/Target.td:1.13 Mon Aug 4 00:11:19 2003 +++ llvm/lib/Target/Target.td Mon Aug 4 16:07:37 2003 @@ -103,6 +103,10 @@ bit isCall = 0; // Is this instruction a call instruction? bit isTwoAddress = 0; // Is this a two address instruction? bit isTerminator = 0; // Is this part of the terminator for a basic block? + + // Pattern - Set to the DAG pattern for this instruction, if we know of one, + // otherwise, uninitialized. + dag Pattern; } // InstrInfo - This class should only be instantiated once to provide parameters @@ -135,3 +139,19 @@ // InstructionSet - Instruction set description for this target InstrInfo InstructionSet; } + + +//===----------------------------------------------------------------------===// +// DAG node definitions used by the instruction selector... +// +def set; // FIXME: these are subject to substantial change +def plus; +def minus; +def mult; +def div; +def udiv; +def mod; +def umod; +def imm8; +def imm16; +def imm32; From lattner at cs.uiuc.edu Mon Aug 4 16:09:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 16:09:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200308042108.QAA32154@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.2 -> 1.3 --- Log message: Change comments into something that TableGen can read! --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.2 llvm/lib/Target/X86/X86InstrInfo.td:1.3 --- llvm/lib/Target/X86/X86InstrInfo.td:1.2 Sun Aug 3 23:59:56 2003 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Aug 4 16:08:29 2003 @@ -76,6 +76,10 @@ list Defs = defs; } +class Pattern { + dag Pattern = P; +} + // Prefix byte classes which are used to indicate to the ad-hoc machine code // emitter that various prefix bytes are required. @@ -212,12 +216,12 @@ } // Arithmetic... -def ADDrr8 : I2A8 <"add", 0x00, MRMDestReg>; // R8 += R8 (set r8 (plus r8 r8)) -def ADDrr16 : I2A16<"add", 0x01, MRMDestReg>, OpSize; // R16 += R16 (set r16 (plus r16 r16)) -def ADDrr32 : I2A32<"add", 0x01, MRMDestReg>; // R32 += R32 (set r32 (plus r32 r32)) -def ADDri8 : I2A8 <"add", 0x80, MRMS0r >; // R8 += imm8 (set r8 (plus r8 imm8)) -def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize; // R16 += imm16 (set r16 (plus r16 imm16)) -def ADDri32 : I2A32<"add", 0x81, MRMS0r >; // R32 += imm32 (set r32 (plus r32 imm32)) +def ADDrr8 : I2A8 <"add", 0x00, MRMDestReg>, Pattern<(set R8 , (plus R8 , R8))>; +def ADDrr16 : I2A16<"add", 0x01, MRMDestReg>, OpSize, Pattern<(set R16, (plus R16, R16))>; +def ADDrr32 : I2A32<"add", 0x01, MRMDestReg>, Pattern<(set R32, (plus R32, R32))>; +def ADDri8 : I2A8 <"add", 0x80, MRMS0r >, Pattern<(set R8 , (plus R8 , imm8))>; +def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize, Pattern<(set R16, (plus R16, imm16))>; +def ADDri32 : I2A32<"add", 0x81, MRMS0r >, Pattern<(set R32, (plus R32, imm32))>; def ADCrr32 : I2A32<"adc", 0x11, MRMDestReg>; // R32 += imm32+Carry From lattner at cs.uiuc.edu Mon Aug 4 16:19:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 16:19:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200308042118.QAA32204@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.3 -> 1.4 --- Log message: Add patterns for (mov R, R) (mov R, I) and subtracts. The moves are to enable testing, the subtracts are because I was in the neighborhood. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.3 llvm/lib/Target/X86/X86InstrInfo.td:1.4 --- llvm/lib/Target/X86/X86InstrInfo.td:1.3 Mon Aug 4 16:08:29 2003 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Aug 4 16:18:19 2003 @@ -163,12 +163,12 @@ //===----------------------------------------------------------------------===// // Move Instructions... // -def MOVrr8 : X86Inst<"mov", 0x88, MRMDestReg, Arg8>; // R8 = R8 -def MOVrr16 : X86Inst<"mov", 0x89, MRMDestReg, Arg16>, OpSize; // R16 = R16 -def MOVrr32 : X86Inst<"mov", 0x89, MRMDestReg, Arg32>; // R32 = R32 -def MOVir8 : X86Inst<"mov", 0xB0, AddRegFrm , Arg8>; // R8 = imm8 -def MOVir16 : X86Inst<"mov", 0xB8, AddRegFrm , Arg16>, OpSize; // R16 = imm16 -def MOVir32 : X86Inst<"mov", 0xB8, AddRegFrm , Arg32>; // R32 = imm32 +def MOVrr8 : X86Inst<"mov", 0x88, MRMDestReg, Arg8>, Pattern<(set R8 , R8 )>; +def MOVrr16 : X86Inst<"mov", 0x89, MRMDestReg, Arg16>, OpSize, Pattern<(set R16, R16)>; +def MOVrr32 : X86Inst<"mov", 0x89, MRMDestReg, Arg32>, Pattern<(set R32, R32)>; +def MOVir8 : X86Inst<"mov", 0xB0, AddRegFrm , Arg8>, Pattern<(set R8 , imm8 )>; +def MOVir16 : X86Inst<"mov", 0xB8, AddRegFrm , Arg16>, OpSize, Pattern<(set R16, imm16)>; +def MOVir32 : X86Inst<"mov", 0xB8, AddRegFrm , Arg32>, Pattern<(set R32, imm32)>; def MOVim8 : X86Inst<"mov", 0xC6, MRMS0m , Arg8>; // [mem] = imm8 def MOVim16 : X86Inst<"mov", 0xC7, MRMS0m , Arg16>, OpSize; // [mem] = imm16 def MOVim32 : X86Inst<"mov", 0xC7, MRMS0m , Arg32>; // [mem] = imm32 @@ -216,21 +216,21 @@ } // Arithmetic... -def ADDrr8 : I2A8 <"add", 0x00, MRMDestReg>, Pattern<(set R8 , (plus R8 , R8))>; +def ADDrr8 : I2A8 <"add", 0x00, MRMDestReg>, Pattern<(set R8 , (plus R8 , R8 ))>; def ADDrr16 : I2A16<"add", 0x01, MRMDestReg>, OpSize, Pattern<(set R16, (plus R16, R16))>; def ADDrr32 : I2A32<"add", 0x01, MRMDestReg>, Pattern<(set R32, (plus R32, R32))>; -def ADDri8 : I2A8 <"add", 0x80, MRMS0r >, Pattern<(set R8 , (plus R8 , imm8))>; +def ADDri8 : I2A8 <"add", 0x80, MRMS0r >, Pattern<(set R8 , (plus R8 , imm8 ))>; def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize, Pattern<(set R16, (plus R16, imm16))>; def ADDri32 : I2A32<"add", 0x81, MRMS0r >, Pattern<(set R32, (plus R32, imm32))>; def ADCrr32 : I2A32<"adc", 0x11, MRMDestReg>; // R32 += imm32+Carry -def SUBrr8 : I2A8 <"sub", 0x28, MRMDestReg>; // R8 -= R8 -def SUBrr16 : I2A16<"sub", 0x29, MRMDestReg>, OpSize; // R16 -= R16 -def SUBrr32 : I2A32<"sub", 0x29, MRMDestReg>; // R32 -= R32 -def SUBri8 : I2A8 <"sub", 0x80, MRMS5r >; // R8 -= imm8 -def SUBri16 : I2A16<"sub", 0x81, MRMS5r >, OpSize; // R16 -= imm16 -def SUBri32 : I2A32<"sub", 0x81, MRMS5r >; // R32 -= imm32 +def SUBrr8 : I2A8 <"sub", 0x28, MRMDestReg>, Pattern<(set R8 , (minus R8 , R8 ))>; +def SUBrr16 : I2A16<"sub", 0x29, MRMDestReg>, OpSize, Pattern<(set R16, (minus R16, R16))>; +def SUBrr32 : I2A32<"sub", 0x29, MRMDestReg>, Pattern<(set R32, (minus R32, R32))>; +def SUBri8 : I2A8 <"sub", 0x80, MRMS5r >, Pattern<(set R8 , (minus R8 , imm8 ))>; +def SUBri16 : I2A16<"sub", 0x81, MRMS5r >, OpSize, Pattern<(set R16, (minus R16, imm16))>; +def SUBri32 : I2A32<"sub", 0x81, MRMS5r >, Pattern<(set R32, (minus R32, imm32))>; def SBBrr32 : I2A32<"sbb", 0x19, MRMDestReg>; // R32 -= R32+Carry From lattner at cs.uiuc.edu Mon Aug 4 18:37:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 18:37:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/2003-08-04-PhysRegLiveFailure.llx Message-ID: <200308042328.SAA09810@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: 2003-08-04-PhysRegLiveFailure.llx added (r1.1) --- Log message: New testcase, identified by Vikram, reduced by Brian --- Diffs of the changes: Index: llvm/test/Regression/Jello/2003-08-04-PhysRegLiveFailure.llx diff -c /dev/null llvm/test/Regression/Jello/2003-08-04-PhysRegLiveFailure.llx:1.1 *** /dev/null Mon Aug 4 18:28:54 2003 --- llvm/test/Regression/Jello/2003-08-04-PhysRegLiveFailure.llx Mon Aug 4 18:28:44 2003 *************** *** 0 **** --- 1,15 ---- + ; RUN: as < %s | llc -march=x86 + + target endian = big ; We need the byteswaps for this test! + target pointersize = 64 + + implementation + + long %main(long %s.1, long %e.1, ushort* %foo) { + %tmp.28 = load ushort* %foo + %tmp.39 = cast uint 0 to ushort* + %tmp.42 = sub long %e.1, %s.1 + %tmp.441 = setge long %tmp.42, 0 + %tmp.54 = getelementptr ushort* %tmp.39, long 0 + ret long %s.1 + } From lattner at cs.uiuc.edu Mon Aug 4 18:37:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 18:37:08 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200308042336.SAA13421@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.19 -> 1.20 --- Log message: * Fix spelling of 'necessary' * Add a lot more DEBUG output, which is better structured than before * Fix bug: Jello/2003-08-04-PhysRegLiveFailure.llx --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.19 llvm/lib/CodeGen/RegAllocLocal.cpp:1.20 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.19 Sun Aug 3 16:47:31 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Mon Aug 4 18:36:39 2003 @@ -31,8 +31,8 @@ const MRegisterInfo *RegInfo; LiveVariables *LV; - // StackSlotForVirtReg - Maps SSA Regs => frame index where these values are - // spilled + // StackSlotForVirtReg - Maps virtual regs to the frame index where these + // values are spilled. std::map StackSlotForVirtReg; // Virt2PhysRegMap - This map contains entries for each virtual register @@ -127,9 +127,12 @@ } /// getStackSpaceFor - This returns the frame index of the specified virtual - /// register on the stack, allocating space if neccesary. + /// register on the stack, allocating space if necessary. int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC); + /// removePhysReg - This method marks the specified physical register as no + /// longer being in use. + /// void removePhysReg(unsigned PhysReg); /// spillVirtReg - This method spills the value specified by PhysReg into @@ -184,17 +187,18 @@ /// unsigned reloadVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, unsigned VirtReg); + + void reloadPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, + unsigned PhysReg); }; } -/// getStackSpaceFor - This allocates space for the specified virtual -/// register to be held on the stack. -int RA::getStackSpaceFor(unsigned VirtReg, - const TargetRegisterClass *RC) { - // Find the location VirtReg would belong... - std::map::iterator I = - StackSlotForVirtReg.lower_bound(VirtReg); +/// getStackSpaceFor - This allocates space for the specified virtual register +/// to be held on the stack. +int RA::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) { + // Find the location Reg would belong... + std::map::iterator I =StackSlotForVirtReg.lower_bound(VirtReg); if (I != StackSlotForVirtReg.end() && I->first == VirtReg) return I->second; // Already has space allocated? @@ -228,21 +232,32 @@ /// void RA::spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, unsigned VirtReg, unsigned PhysReg) { - // If this is just a marker register, we don't need to spill it. - if (VirtReg != 0) { - const TargetRegisterClass *RegClass = - MF->getSSARegMap()->getRegClass(VirtReg); - int FrameIndex = getStackSpaceFor(VirtReg, RegClass); - // If we need to spill this value, do so now... + DEBUG(std::cerr << " Spilling register " << RegInfo->getName(PhysReg)); + if (VirtReg == 0) { + DEBUG(std::cerr << " which corresponds to no vreg, " + << "must be spurious physreg: ignoring (WARNING)\n"); + } else { + // FIXME: move this into the conditional?? + const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); + int FrameIndex = getStackSpaceFor(VirtReg, RC); + + DEBUG(std::cerr << " containing %reg" << VirtReg; + if (!isVirtRegModified(VirtReg)) + std::cerr << " which has not been modified, so no store necessary!"); + + // Otherwise, there is a virtual register corresponding to this physical + // register. We only need to spill it into its stack slot if it has been + // modified. if (isVirtRegModified(VirtReg)) { - // Add move instruction(s) - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RegClass); + DEBUG(std::cerr << " to stack slot #" << FrameIndex); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); ++NumSpilled; // Update statistics } Virt2PhysRegMap.erase(VirtReg); // VirtReg no longer available } + DEBUG(std::cerr << "\n"); removePhysReg(PhysReg); } @@ -433,18 +448,30 @@ markVirtRegModified(VirtReg, false); // Note that this reg was just reloaded + DEBUG(std::cerr << " Reloading %reg" << VirtReg << " into " + << RegInfo->getName(PhysReg) << "\n"); + // Add move instruction(s) RegInfo->loadRegFromStackSlot(MBB, I, PhysReg, FrameIndex, RC); ++NumReloaded; // Update statistics return PhysReg; } + + void RA::AllocateBasicBlock(MachineBasicBlock &MBB) { // loop over each instruction MachineBasicBlock::iterator I = MBB.begin(); for (; I != MBB.end(); ++I) { MachineInstr *MI = *I; const TargetInstrDescriptor &TID = TM->getInstrInfo().get(MI->getOpcode()); + DEBUG(std::cerr << "\nStarting RegAlloc of: " << *MI; + std::cerr << " Regs have values: "; + for (std::map::const_iterator + I = PhysRegsUsed.begin(), E = PhysRegsUsed.end(); I != E; ++I) + std::cerr << "[" << RegInfo->getName(I->first) + << ",%reg" << I->second << "] "; + std::cerr << "\n"); // Loop over the implicit uses, making sure that they are at the head of the // use order list, so they don't get reallocated. @@ -453,11 +480,13 @@ MarkPhysRegRecentlyUsed(ImplicitUses[i]); // Get the used operands into registers. This has the potiential to spill - // incoming values if we are out of registers. + // incoming values if we are out of registers. Note that we completely + // ignore physical register uses here. We assume that if an explicit + // physical register is referenced by the instruction, that it is guaranteed + // to be live-in, or the input is badly hosed. // for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) - if (MI->getOperand(i).opIsUse() && - MI->getOperand(i).isVirtualRegister()) { + if (MI->getOperand(i).opIsUse() && MI->getOperand(i).isVirtualRegister()){ unsigned VirtSrcReg = MI->getOperand(i).getAllocatedRegNum(); unsigned PhysSrcReg = reloadVirtReg(MBB, I, VirtSrcReg); MI->SetMachineOperandReg(i, PhysSrcReg); // Assign the input register @@ -481,9 +510,14 @@ } if (PhysReg) { - DEBUG(std::cerr << "V: " << VirtReg << " P: " << PhysReg - << " Killed by: " << *MI); - removePhysReg(PhysReg); + DEBUG(std::cerr << " Last use of " << RegInfo->getName(PhysReg) + << "[%reg" << VirtReg <<"], removing it from live set\n"); + // If the physical register was used, but there was no definition of + // the physical register (we are reading garbage), Live Variables will + // tell us that this is the last use of the register even though we + // don't know of anything in the register. No need to remove it. + if (VirtReg != PhysReg || PhysRegsUsed.count(PhysReg)) + removePhysReg(PhysReg); } } } @@ -565,8 +599,9 @@ } if (PhysReg) { - DEBUG(std::cerr << "V: " << VirtReg << " P: " << PhysReg - << " dead after: " << *MI); + DEBUG(std::cerr << " Register " << RegInfo->getName(PhysReg) + << " [%reg" << VirtReg + << "] is never used, removing it frame live list\n"); removePhysReg(PhysReg); } } From lattner at cs.uiuc.edu Mon Aug 4 18:43:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 18:43:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200308042342.SAA17082@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.20 -> 1.21 --- Log message: Don't bother calculating info unless its needed. May reduce number of stack slots created. --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.20 llvm/lib/CodeGen/RegAllocLocal.cpp:1.21 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.20 Mon Aug 4 18:36:39 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Mon Aug 4 18:42:37 2003 @@ -238,10 +238,6 @@ DEBUG(std::cerr << " which corresponds to no vreg, " << "must be spurious physreg: ignoring (WARNING)\n"); } else { - // FIXME: move this into the conditional?? - const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); - int FrameIndex = getStackSpaceFor(VirtReg, RC); - DEBUG(std::cerr << " containing %reg" << VirtReg; if (!isVirtRegModified(VirtReg)) std::cerr << " which has not been modified, so no store necessary!"); @@ -250,6 +246,8 @@ // register. We only need to spill it into its stack slot if it has been // modified. if (isVirtRegModified(VirtReg)) { + const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); + int FrameIndex = getStackSpaceFor(VirtReg, RC); DEBUG(std::cerr << " to stack slot #" << FrameIndex); RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); ++NumSpilled; // Update statistics From brukman at cs.uiuc.edu Mon Aug 4 18:49:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Aug 4 18:49:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSchedInfo.cpp Message-ID: <200308042348.SAA00912@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSchedInfo.cpp updated: 1.9 -> 1.10 --- Log message: ElectricFence found this bug where we were reading past the vector boundary. --- Diffs of the changes: Index: llvm/lib/Target/TargetSchedInfo.cpp diff -u llvm/lib/Target/TargetSchedInfo.cpp:1.9 llvm/lib/Target/TargetSchedInfo.cpp:1.10 --- llvm/lib/Target/TargetSchedInfo.cpp:1.9 Sat Dec 28 21:13:00 2002 +++ llvm/lib/Target/TargetSchedInfo.cpp Mon Aug 4 18:48:40 2003 @@ -243,7 +243,7 @@ // for that resource in each cycle. std::vector& rvec = this->resourcesByCycle[c]; int r; - for (r = (int) rvec.size(); r >= 0; r--) + for (r = rvec.size() - 1; r >= 0; r--) if (rvec[r] == delta.resourceId) {// found last entry for the resource rvec.erase(rvec.begin() + r); From brukman at cs.uiuc.edu Mon Aug 4 19:03:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Aug 4 19:03:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSchedInfo.cpp Message-ID: <200308050002.TAA01772@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSchedInfo.cpp updated: 1.10 -> 1.11 --- Log message: Reformatted code to match the prevalent LLVM style; fit code into 80 columns. --- Diffs of the changes: Index: llvm/lib/Target/TargetSchedInfo.cpp diff -u llvm/lib/Target/TargetSchedInfo.cpp:1.10 llvm/lib/Target/TargetSchedInfo.cpp:1.11 --- llvm/lib/Target/TargetSchedInfo.cpp:1.10 Mon Aug 4 18:48:40 2003 +++ llvm/lib/Target/TargetSchedInfo.cpp Mon Aug 4 19:02:06 2003 @@ -23,15 +23,14 @@ unsigned fN = fromRVec.size(), tN = toRVec.size(); unsigned fi = 0, ti = 0; - while (fi < fN && ti < tN) - { - if (fromRVec[fi] < toRVec[ti]) - ++fi; - else if (toRVec[ti] < fromRVec[fi]) - ++ti; - else - return true; - } + while (fi < fN && ti < tN) { + if (fromRVec[fi] < toRVec[ti]) + ++fi; + else if (toRVec[ti] < fromRVec[fi]) + ++ti; + else + return true; + } return false; } @@ -45,24 +44,21 @@ if (fromRU.numBubbles > 0) minGap = fromRU.numBubbles; - if (minGap < fromRU.numCycles) - { - // only need to check from cycle `minGap' onwards - for (cycles_t gap=minGap; gap <= fromRU.numCycles-1; gap++) - { - // check if instr. #2 can start executing `gap' cycles after #1 - // by checking for resource conflicts in each overlapping cycle - cycles_t numOverlap =std::min(fromRU.numCycles - gap, toRU.numCycles); - for (cycles_t c = 0; c <= numOverlap-1; c++) - if (RUConflict(fromRU.resourcesByCycle[gap + c], - toRU.resourcesByCycle[c])) - { - // conflict found so minGap must be more than `gap' - minGap = gap+1; - break; - } - } + if (minGap < fromRU.numCycles) { + // only need to check from cycle `minGap' onwards + for (cycles_t gap=minGap; gap <= fromRU.numCycles-1; gap++) { + // check if instr. #2 can start executing `gap' cycles after #1 + // by checking for resource conflicts in each overlapping cycle + cycles_t numOverlap =std::min(fromRU.numCycles - gap, toRU.numCycles); + for (cycles_t c = 0; c <= numOverlap-1; c++) + if (RUConflict(fromRU.resourcesByCycle[gap + c], + toRU.resourcesByCycle[c])) { + // conflict found so minGap must be more than `gap' + minGap = gap+1; + break; + } } + } return minGap; } @@ -157,12 +153,11 @@ // int classPairGaps[numSchedClasses][numSchedClasses]; for (InstrSchedClass fromSC=0; fromSC < numSchedClasses; fromSC++) - for (InstrSchedClass toSC=0; toSC < numSchedClasses; toSC++) - { - int classPairGap = ComputeMinGap(instrRUForClasses[fromSC], - instrRUForClasses[toSC]); - classPairGaps[fromSC][toSC] = classPairGap; - } + for (InstrSchedClass toSC=0; toSC < numSchedClasses; toSC++) { + int classPairGap = ComputeMinGap(instrRUForClasses[fromSC], + instrRUForClasses[toSC]); + classPairGaps[fromSC][toSC] = classPairGap; + } // Now, for each pair of instructions, use the class pair gap if both // instructions have identical resource usage as their respective classes. @@ -171,20 +166,18 @@ longestIssueConflict = 0; for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++) - for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++) - { - int instrPairGap = - (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) - ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] - : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); - - if (instrPairGap > 0) - { - this->setGap(instrPairGap, fromOp, toOp); - conflictLists[fromOp].push_back(toOp); - longestIssueConflict=std::max(longestIssueConflict, instrPairGap); - } + for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++) { + int instrPairGap = + (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) + ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] + : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); + + if (instrPairGap > 0) { + this->setGap(instrPairGap, fromOp, toOp); + conflictLists[fromOp].push_back(toOp); + longestIssueConflict=std::max(longestIssueConflict, instrPairGap); } + } } @@ -194,12 +187,11 @@ breaksGroup = classRU.breaksGroup; numBubbles = classRU.numBubbles; - for (unsigned i=0; i < classRU.numSlots; i++) - { - unsigned slot = classRU.feasibleSlots[i]; - assert(slot < feasibleSlots.size() && "Invalid slot specified!"); - this->feasibleSlots[slot] = true; - } + for (unsigned i=0; i < classRU.numSlots; i++) { + unsigned slot = classRU.feasibleSlots[i]; + assert(slot < feasibleSlots.size() && "Invalid slot specified!"); + this->feasibleSlots[slot] = true; + } numCycles = classRU.totCycles; resourcesByCycle.resize(this->numCycles); @@ -209,10 +201,10 @@ c < NC; c++) this->resourcesByCycle[c].push_back(classRU.V[i].resourceId); - // Sort each resource usage vector by resourceId_t to speed up conflict checking + // Sort each resource usage vector by resourceId_t to speed up conflict + // checking for (unsigned i=0; i < this->resourcesByCycle.size(); i++) sort(resourcesByCycle[i].begin(), resourcesByCycle[i].end()); - } // Add the extra resource usage requirements specified in the delta. @@ -226,29 +218,27 @@ // resize the resources vector if more cycles are specified unsigned maxCycles = this->numCycles; maxCycles = std::max(maxCycles, delta.startCycle + abs(NC) - 1); - if (maxCycles > this->numCycles) - { - this->resourcesByCycle.resize(maxCycles); - this->numCycles = maxCycles; - } + if (maxCycles > this->numCycles) { + this->resourcesByCycle.resize(maxCycles); + this->numCycles = maxCycles; + } if (NC >= 0) for (unsigned c=delta.startCycle, last=c+NC-1; c <= last; c++) this->resourcesByCycle[c].push_back(delta.resourceId); else // Remove the resource from all NC cycles. - for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++) - { - // Look for the resource backwards so we remove the last entry - // for that resource in each cycle. - std::vector& rvec = this->resourcesByCycle[c]; - int r; - for (r = rvec.size() - 1; r >= 0; r--) - if (rvec[r] == delta.resourceId) - {// found last entry for the resource - rvec.erase(rvec.begin() + r); - break; - } - assert(r >= 0 && "Resource to remove was unused in cycle c!"); - } + for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++) { + // Look for the resource backwards so we remove the last entry + // for that resource in each cycle. + std::vector& rvec = this->resourcesByCycle[c]; + int r; + for (r = rvec.size() - 1; r >= 0; r--) + if (rvec[r] == delta.resourceId) { + // found last entry for the resource + rvec.erase(rvec.begin() + r); + break; + } + assert(r >= 0 && "Resource to remove was unused in cycle c!"); + } } From lattner at cs.uiuc.edu Mon Aug 4 19:49:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 19:49:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86CodeEmitter.cpp X86InstrInfo.td InstSelectSimple.cpp Message-ID: <200308050048.TAA22721@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86CodeEmitter.cpp updated: 1.33 -> 1.34 X86InstrInfo.td updated: 1.4 -> 1.5 InstSelectSimple.cpp updated: 1.119 -> 1.120 --- Log message: This is the real fix for the previous register allocator problem. Physical registers should not float around. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.33 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.34 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.33 Sun Aug 3 16:14:38 2003 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Mon Aug 4 19:48:46 2003 @@ -470,7 +470,7 @@ switch (Desc.TSFlags & X86II::FormMask) { default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!"); case X86II::Pseudo: - if (Opcode != X86::IMPLICIT_USE) + if (Opcode != X86::IMPLICIT_USE && Opcode != X86::IMPLICIT_DEF) std::cerr << "X86 Machine Code Emitter: No 'form', not emitting: " << MI; break; Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.4 llvm/lib/Target/X86/X86InstrInfo.td:1.5 --- llvm/lib/Target/X86/X86InstrInfo.td:1.4 Mon Aug 4 16:18:19 2003 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Aug 4 19:48:46 2003 @@ -107,6 +107,7 @@ def ADJCALLSTACKDOWN : X86Inst<"ADJCALLSTACKDOWN", 0, Pseudo, NoArg>; def ADJCALLSTACKUP : X86Inst<"ADJCALLSTACKUP", 0, Pseudo, NoArg>; def IMPLICIT_USE : X86Inst<"IMPLICIT_USE", 0, Pseudo, NoArg>; +def IMPLICIT_DEF : X86Inst<"IMPLICIT_DEF", 0, Pseudo, NoArg>; //===----------------------------------------------------------------------===// // Control Flow Instructions... Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.119 llvm/lib/Target/X86/InstSelectSimple.cpp:1.120 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.119 Sun Aug 3 21:12:48 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Mon Aug 4 19:48:47 2003 @@ -646,6 +646,8 @@ BuildMI(BB, SetCCOpcodeTab[0][OpNum], 0, X86::AL); BuildMI(BB, X86::CMPrr32, 2).addReg(Op0r+1).addReg(Op1r+1); BuildMI(BB, SetCCOpcodeTab[isSigned][OpNum], 0, X86::BL); + BuildMI(BB, X86::IMPLICIT_DEF, 0, X86::BH); + BuildMI(BB, X86::IMPLICIT_DEF, 0, X86::AH); BuildMI(BB, X86::CMOVErr16, 2, X86::BX).addReg(X86::BX).addReg(X86::AX); // NOTE: visitSetCondInst knows that the value is dumped into the BL // register at this point for long values... From lattner at cs.uiuc.edu Mon Aug 4 19:50:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 19:50:02 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200308050049.TAA22737@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.21 -> 1.22 --- Log message: Revert previous change, and be really anal about what physical registers can do. --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.21 llvm/lib/CodeGen/RegAllocLocal.cpp:1.22 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.21 Mon Aug 4 18:42:37 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Mon Aug 4 19:49:09 2003 @@ -232,28 +232,25 @@ /// void RA::spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, unsigned VirtReg, unsigned PhysReg) { - - DEBUG(std::cerr << " Spilling register " << RegInfo->getName(PhysReg)); - if (VirtReg == 0) { - DEBUG(std::cerr << " which corresponds to no vreg, " - << "must be spurious physreg: ignoring (WARNING)\n"); - } else { - DEBUG(std::cerr << " containing %reg" << VirtReg; - if (!isVirtRegModified(VirtReg)) - std::cerr << " which has not been modified, so no store necessary!"); - - // Otherwise, there is a virtual register corresponding to this physical - // register. We only need to spill it into its stack slot if it has been - // modified. - if (isVirtRegModified(VirtReg)) { - const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); - int FrameIndex = getStackSpaceFor(VirtReg, RC); - DEBUG(std::cerr << " to stack slot #" << FrameIndex); - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); - ++NumSpilled; // Update statistics - } - Virt2PhysRegMap.erase(VirtReg); // VirtReg no longer available + assert((VirtReg || DisableKill) && "Spilling a physical register is illegal!" + " Must not have appropriate kill for the register or use exists beyond" + " the intended one."); + DEBUG(std::cerr << " Spilling register " << RegInfo->getName(PhysReg); + std::cerr << " containing %reg" << VirtReg; + if (!isVirtRegModified(VirtReg)) + std::cerr << " which has not been modified, so no store necessary!"); + + // Otherwise, there is a virtual register corresponding to this physical + // register. We only need to spill it into its stack slot if it has been + // modified. + if (isVirtRegModified(VirtReg)) { + const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); + int FrameIndex = getStackSpaceFor(VirtReg, RC); + DEBUG(std::cerr << " to stack slot #" << FrameIndex); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); + ++NumSpilled; // Update statistics } + Virt2PhysRegMap.erase(VirtReg); // VirtReg no longer available DEBUG(std::cerr << "\n"); removePhysReg(PhysReg); @@ -510,12 +507,7 @@ if (PhysReg) { DEBUG(std::cerr << " Last use of " << RegInfo->getName(PhysReg) << "[%reg" << VirtReg <<"], removing it from live set\n"); - // If the physical register was used, but there was no definition of - // the physical register (we are reading garbage), Live Variables will - // tell us that this is the last use of the register even though we - // don't know of anything in the register. No need to remove it. - if (VirtReg != PhysReg || PhysRegsUsed.count(PhysReg)) - removePhysReg(PhysReg); + removePhysReg(PhysReg); } } } From lattner at cs.uiuc.edu Mon Aug 4 22:54:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 22:54:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp Message-ID: <200308050353.WAA13287@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeEmitterGen.cpp updated: 1.21 -> 1.22 --- Log message: The CodeEmitterGenerator used to consider ANY uninitialized field as being an operand (unless it's annul or predict). Now we only consider fields to be operands if they are uninitialized AND used in the "Inst" field. --- Diffs of the changes: Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.21 llvm/utils/TableGen/CodeEmitterGen.cpp:1.22 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.21 Fri Aug 1 17:13:14 2003 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Mon Aug 4 22:53:04 2003 @@ -46,30 +46,22 @@ DEBUG(o << " // " << *R->getValue("Inst") << "\n"); o << " Value = " << Value << "U;\n\n"; - // Loop over all of the fields in the instruction adding in any - // contributions to this value (due to bit references). + // Loop over all of the fields in the instruction determining which are the + // operands to the instruction. // unsigned op = 0; - std::map OpOrder; - std::map OpContinuous; + std::map OpOrder; + std::map OpContinuous; for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - if (Vals[i].getName() != "Inst" && - !Vals[i].getValue()->isComplete() && + if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete() && /* ignore annul and predict bits since no one sets them yet */ - Vals[i].getName() != "annul" && - Vals[i].getName() != "predict") + Vals[i].getName() != "annul" && Vals[i].getName() != "predict") { - o << " // op" << op << ": " << Vals[i].getName() << "\n" - << " int64_t op" << op - <<" = getMachineOpValue(MI, MI.getOperand("<getNumBits()-1; bit >= 0; --bit) { @@ -111,9 +103,8 @@ // maintain same distance between bits in field and bits in // instruction. if the relative distances stay the same // throughout, - if ((beginBitInVar - (int)VBI->getBitNum()) != - (beginBitInInst - bit)) - { + if (beginBitInVar - (int)VBI->getBitNum() != + beginBitInInst - bit) { continuous = false; break; } @@ -121,39 +112,48 @@ } } - DEBUG(o << " // Var: begin = " << beginBitInVar - << ", end = " << endBitInVar - << "; Inst: begin = " << beginBitInInst - << ", end = " << endBitInInst << "\n"); - - if (continuous) { - DEBUG(o << " // continuous: op" << OpOrder[Vals[i].getName()] - << "\n"); + if (beginBitInInst != -1) { + o << " // op" << op << ": " << Vals[i].getName() << "\n" + << " int64_t op" << op + <<" = getMachineOpValue(MI, MI.getOperand("<>= " << endBitInVar << ";\n"; - beginBitInVar -= endBitInVar; - endBitInVar = 0; - } - - // High mask - o << " op" << OpOrder[Vals[i].getName()] - << " &= (1<<" << beginBitInVar+1 << ") - 1;\n"; - - // Shift the value to the correct place (according to place in instr) - if (endBitInInst != 0) + DEBUG(o << " // Var: begin = " << beginBitInVar + << ", end = " << endBitInVar + << "; Inst: begin = " << beginBitInInst + << ", end = " << endBitInInst << "\n"); + + if (continuous) { + DEBUG(o << " // continuous: op" << OpOrder[Vals[i].getName()] + << "\n"); + + // Mask off the right bits + // Low mask (ie. shift, if necessary) + if (endBitInVar != 0) { + o << " op" << OpOrder[Vals[i].getName()] + << " >>= " << endBitInVar << ";\n"; + beginBitInVar -= endBitInVar; + endBitInVar = 0; + } + + // High mask o << " op" << OpOrder[Vals[i].getName()] + << " &= (1<<" << beginBitInVar+1 << ") - 1;\n"; + + // Shift the value to the correct place (according to place in inst) + if (endBitInInst != 0) + o << " op" << OpOrder[Vals[i].getName()] << " <<= " << endBitInInst << ";\n"; - - // Just OR in the result - o << " Value |= op" << OpOrder[Vals[i].getName()] << ";\n"; + + // Just OR in the result + o << " Value |= op" << OpOrder[Vals[i].getName()] << ";\n"; + } + + // otherwise, will be taken care of in the loop below using this + // value: + OpContinuous[Vals[i].getName()] = continuous; } - - // otherwise, will be taken care of in the loop below using this value: - OpContinuous[Vals[i].getName()] = continuous; } } From lattner at cs.uiuc.edu Mon Aug 4 23:00:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 23:00:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp Message-ID: <200308050359.WAA15119@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeEmitterGen.cpp updated: 1.22 -> 1.23 --- Log message: No functional changes, comment the fix I just put in --- Diffs of the changes: Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.22 llvm/utils/TableGen/CodeEmitterGen.cpp:1.23 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.22 Mon Aug 4 22:53:04 2003 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Mon Aug 4 22:59:01 2003 @@ -54,9 +54,8 @@ std::map OpContinuous; for (unsigned i = 0, e = Vals.size(); i != e; ++i) { if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete() && - /* ignore annul and predict bits since no one sets them yet */ - Vals[i].getName() != "annul" && Vals[i].getName() != "predict") - { + // ignore annul and predict bits since no one sets them yet + Vals[i].getName() != "annul" && Vals[i].getName() != "predict") { // Is the operand continuous? If so, we can just mask and OR it in // instead of doing it bit-by-bit, saving a lot in runtime cost. const BitsInit *InstInit = BI; @@ -112,6 +111,8 @@ } } + // If we have found no bit in "Inst" which comes from this field, then + // this is not an operand!! if (beginBitInInst != -1) { o << " // op" << op << ": " << Vals[i].getName() << "\n" << " int64_t op" << op @@ -164,7 +165,7 @@ // Scan through the field looking for bit initializers of the current // variable... for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) { - if (BitInit *BI=dynamic_cast(FieldInitializer->getBit(i))) + if (BitInit *BI = dynamic_cast(FieldInitializer->getBit(i))) { DEBUG(o << " // bit init: f: " << f << ", i: " << i << "\n"); } else if (UnsetInit *UI = From lattner at cs.uiuc.edu Mon Aug 4 23:15:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 4 23:15:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200308050414.XAA16068@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.22 -> 1.23 --- Log message: Fix bugs handling ESP in alloca references --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.22 llvm/lib/CodeGen/RegAllocLocal.cpp:1.23 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.22 Mon Aug 4 19:49:09 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Mon Aug 4 23:13:58 2003 @@ -232,7 +232,8 @@ /// void RA::spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I, unsigned VirtReg, unsigned PhysReg) { - assert((VirtReg || DisableKill) && "Spilling a physical register is illegal!" + if (!VirtReg && DisableKill) return; + assert(VirtReg && "Spilling a physical register is illegal!" " Must not have appropriate kill for the register or use exists beyond" " the intended one."); DEBUG(std::cerr << " Spilling register " << RegInfo->getName(PhysReg); @@ -606,8 +607,10 @@ // Spill all physical registers holding virtual registers now. while (!PhysRegsUsed.empty()) - spillVirtReg(MBB, I, PhysRegsUsed.begin()->second, - PhysRegsUsed.begin()->first); + if (unsigned VirtReg = PhysRegsUsed.begin()->second) + spillVirtReg(MBB, I, VirtReg, PhysRegsUsed.begin()->first); + else + removePhysReg(PhysRegsUsed.begin()->first); for (std::map::iterator I = Virt2PhysRegMap.begin(), E = Virt2PhysRegMap.end(); I != E; ++I) From brukman at cs.uiuc.edu Tue Aug 5 09:35:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Aug 5 09:35:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9_F2.td Message-ID: <200308051434.JAA00678@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcV9_F2.td updated: 1.5 -> 1.6 --- Log message: * Set annul bit to be 0, because the Sparc backend currently does not use it. * Use the name of the predict field instead of just the const 1 in the Instruction. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcV9_F2.td diff -u llvm/lib/Target/Sparc/SparcV9_F2.td:1.5 llvm/lib/Target/Sparc/SparcV9_F2.td:1.6 --- llvm/lib/Target/Sparc/SparcV9_F2.td:1.5 Mon Aug 4 00:03:18 2003 +++ llvm/lib/Target/Sparc/SparcV9_F2.td Tue Aug 5 09:34:38 2003 @@ -27,7 +27,7 @@ class F2_2 cond, string name> : F2_br { // Format 2.2 instructions bits<22> disp; - bit annul; + bit annul = 0; // currently unused by Sparc backend let Name = name; let Inst{29} = annul; @@ -39,13 +39,13 @@ bits<2> cc; bits<19> disp; bit predict = 1; - bit annul; + bit annul = 0; // currently unused by Sparc backend let Name = name; let Inst{29} = annul; let Inst{28-25} = cond; let Inst{21-20} = cc; - let Inst{19} = 1; // predict; + let Inst{19} = predict; let Inst{18-0} = disp; } @@ -53,14 +53,14 @@ bits<5> rs1; bits<16> disp; bit predict = 1; - bit annul; + bit annul = 0; // currently unused by Sparc backend let Name = name; let Inst{29} = annul; let Inst{28} = 0; let Inst{27-25} = rcond; let Inst{21-20} = disp{15-14}; - let Inst{19} = 1; // predict; + let Inst{19} = predict; let Inst{18-14} = rs1; let Inst{13-0 } = disp{13-0}; } From brukman at cs.uiuc.edu Tue Aug 5 09:36:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Aug 5 09:36:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp Message-ID: <200308051435.JAA00707@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeEmitterGen.cpp updated: 1.23 -> 1.24 --- Log message: Stop special-casing annul and predict bits (which are Sparc-specific anyway) since those bits are now hard-coded in Sparc*.td files. --- Diffs of the changes: Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.23 llvm/utils/TableGen/CodeEmitterGen.cpp:1.24 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.23 Mon Aug 4 22:59:01 2003 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Tue Aug 5 09:35:35 2003 @@ -53,9 +53,7 @@ std::map OpOrder; std::map OpContinuous; for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete() && - // ignore annul and predict bits since no one sets them yet - Vals[i].getName() != "annul" && Vals[i].getName() != "predict") { + if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) { // Is the operand continuous? If so, we can just mask and OR it in // instead of doing it bit-by-bit, saving a lot in runtime cost. const BitsInit *InstInit = BI; @@ -198,11 +196,6 @@ o << "Error: UNIMPLEMENTED\n"; } } - } - } else { - // ignore annul and predict bits since no one sets them yet - if (Vals[f].getName() == "annul" || Vals[f].getName() == "predict") { - o << " // found " << Vals[f].getName() << "\n"; } } } From brukman at cs.uiuc.edu Tue Aug 5 10:27:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Aug 5 10:27:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CrashDebugger.cpp Message-ID: <200308051526.KAA00816@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CrashDebugger.cpp updated: 1.12 -> 1.13 --- Log message: Only test the vector of functions if it is non-empty. --- Diffs of the changes: Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.12 llvm/tools/bugpoint/CrashDebugger.cpp:1.13 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.12 Mon Aug 4 13:24:31 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Tue Aug 5 10:26:21 2003 @@ -80,7 +80,7 @@ virtual TestResult doTest(std::vector &Prefix, std::vector &Kept) { - if (TestFuncs(Kept)) + if (!Kept.empty() && TestFuncs(Kept)) return KeepSuffix; if (!Prefix.empty() && TestFuncs(Prefix)) return KeepPrefix; From lattner at cs.uiuc.edu Tue Aug 5 10:35:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 10:35:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200308051534.KAA14497@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.93 -> 1.94 --- Log message: Implement TODO: print out short form of Invoke if possible --- Diffs of the changes: Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.93 llvm/lib/VMCore/AsmWriter.cpp:1.94 --- llvm/lib/VMCore/AsmWriter.cpp:1.93 Wed Jul 23 10:30:06 2003 +++ llvm/lib/VMCore/AsmWriter.cpp Tue Aug 5 10:34:45 2003 @@ -777,15 +777,15 @@ } else if (isa(I) && !Operand) { Out << " void"; } else if (isa(I)) { - const PointerType *PTy = dyn_cast(Operand->getType()); - const FunctionType*MTy = PTy ? dyn_cast(PTy->getElementType()):0; - const Type *RetTy = MTy ? MTy->getReturnType() : 0; + const PointerType *PTy = cast(Operand->getType()); + const FunctionType *FTy = cast(PTy->getElementType()); + const Type *RetTy = FTy->getReturnType(); - // If possible, print out the short form of the call instruction, but we can + // If possible, print out the short form of the call instruction. We can // only do this if the first argument is a pointer to a nonvararg function, - // and if the value returned is not a pointer to a function. + // and if the return type is not a pointer to a function. // - if (RetTy && MTy && !MTy->isVarArg() && + if (!FTy->isVarArg() && (!isa(RetTy) || !isa(cast(RetTy)->getElementType()))) { Out << " "; printType(RetTy); @@ -802,8 +802,23 @@ Out << " )"; } else if (const InvokeInst *II = dyn_cast(&I)) { - // TODO: Should try to print out short form of the Invoke instruction - writeOperand(Operand, true); + const PointerType *PTy = cast(Operand->getType()); + const FunctionType *FTy = cast(PTy->getElementType()); + const Type *RetTy = FTy->getReturnType(); + + // If possible, print out the short form of the invoke instruction. We can + // only do this if the first argument is a pointer to a nonvararg function, + // and if the return type is not a pointer to a function. + // + if (!FTy->isVarArg() && + (!isa(RetTy) || + !isa(cast(RetTy)->getElementType()))) { + Out << " "; printType(RetTy); + writeOperand(Operand, false); + } else { + writeOperand(Operand, true); + } + Out << "("; if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true); for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) { From lattner at cs.uiuc.edu Tue Aug 5 10:52:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 10:52:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.h CrashDebugger.cpp ExtractFunction.cpp Message-ID: <200308051551.KAA15649@apoc.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.h updated: 1.13 -> 1.14 CrashDebugger.cpp updated: 1.13 -> 1.14 ExtractFunction.cpp updated: 1.11 -> 1.12 --- Log message: If we're debugging the SimplifyCFG pass, we _REALLY_ don't want to use it for narrowing, no matter what. --- Diffs of the changes: Index: llvm/tools/bugpoint/BugDriver.h diff -u llvm/tools/bugpoint/BugDriver.h:1.13 llvm/tools/bugpoint/BugDriver.h:1.14 --- llvm/tools/bugpoint/BugDriver.h:1.13 Fri Aug 1 11:13:49 2003 +++ llvm/tools/bugpoint/BugDriver.h Tue Aug 5 10:51:05 2003 @@ -27,6 +27,8 @@ class CBE; class GCC; +extern bool DisableSimplifyCFG; + class BugDriver { const std::string ToolName; // Name of bugpoint std::string ReferenceOutputFile; // Name of `good' output file Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.13 llvm/tools/bugpoint/CrashDebugger.cpp:1.14 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.13 Tue Aug 5 10:26:21 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Tue Aug 5 10:51:05 2003 @@ -304,11 +304,13 @@ // to a return instruction then running simplifycfg, which can potentially // shrinks the code dramatically quickly // - std::vector Blocks; - for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I) - for (Function::iterator FI = I->begin(), E = I->end(); FI != E; ++FI) - Blocks.push_back(FI); - ReduceCrashingBlocks(*this).reduceList(Blocks); + if (!DisableSimplifyCFG) { + std::vector Blocks; + for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I) + for (Function::iterator FI = I->begin(), E = I->end(); FI != E; ++FI) + Blocks.push_back(FI); + ReduceCrashingBlocks(*this).reduceList(Blocks); + } // FIXME: This should use the list reducer to converge faster by deleting // larger chunks of instructions at a time! Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.11 llvm/tools/bugpoint/ExtractFunction.cpp:1.12 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.11 Fri Aug 1 11:13:49 2003 +++ llvm/tools/bugpoint/ExtractFunction.cpp Tue Aug 5 10:51:05 2003 @@ -16,6 +16,8 @@ #include "llvm/Constant.h" #include "Support/CommandLine.h" +bool DisableSimplifyCFG = false; + namespace { cl::opt NoADCE("disable-adce", @@ -23,8 +25,8 @@ cl::opt NoDCE ("disable-dce", cl::desc("Do not use the -dce pass to reduce testcases")); - cl::opt - NoSCFG("disable-simplifycfg", + cl::opt + NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG), cl::desc("Do not use the -simplifycfg pass to reduce testcases")); cl::opt NoFinalCleanup("disable-final-cleanup", @@ -67,7 +69,7 @@ //Passes.add(createInstructionCombiningPass()); if (Simplification > 1 && !NoDCE) Passes.add(createDeadCodeEliminationPass()); - if (Simplification && !NoSCFG) + if (Simplification && !DisableSimplifyCFG) Passes.add(createCFGSimplificationPass()); // Delete dead control flow Passes.add(createVerifierPass()); From brukman at cs.uiuc.edu Tue Aug 5 11:03:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Aug 5 11:03:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/EmitAssembly.cpp Message-ID: <200308051602.LAA01209@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: EmitAssembly.cpp updated: 1.87 -> 1.88 --- Log message: * Removed `using' declaration, now use full namespace qualifier std::string * Simplified code by using an inline function instead of copy-pasted code --- Diffs of the changes: Index: llvm/lib/Target/Sparc/EmitAssembly.cpp diff -u llvm/lib/Target/Sparc/EmitAssembly.cpp:1.87 llvm/lib/Target/Sparc/EmitAssembly.cpp:1.88 --- llvm/lib/Target/Sparc/EmitAssembly.cpp:1.87 Fri Aug 1 10:55:53 2003 +++ llvm/lib/Target/Sparc/EmitAssembly.cpp Tue Aug 5 11:01:50 2003 @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "SparcInternals.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionInfo.h" @@ -22,7 +21,8 @@ #include "llvm/Pass.h" #include "llvm/Assembly/Writer.h" #include "Support/StringExtras.h" -using std::string; +#include "SparcInternals.h" +#include namespace { @@ -108,8 +108,8 @@ toAsm << "\n"; } - static string getValidSymbolName(const string &S) { - string Result; + static std::string getValidSymbolName(const std::string &S) { + std::string Result; // Symbol names in Sparc assembly language have these rules: // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }* @@ -138,10 +138,10 @@ // use a numbered value based on prefix otherwise. // FPrefix is always prepended to the output identifier. // - string getID(const Value *V, const char *Prefix, const char *FPrefix = 0) { - string Result = FPrefix ? FPrefix : ""; // "Forced prefix" + std::string getID(const Value *V, const char *Prefix, const char *FPrefix = 0) { + std::string Result = FPrefix ? FPrefix : ""; // "Forced prefix" - Result += V->hasName() ? V->getName() : string(Prefix); + Result += V->hasName() ? V->getName() : std::string(Prefix); // Qualify all internal names with a unique id. if (!isExternal(V)) { @@ -163,19 +163,19 @@ } // getID Wrappers - Ensure consistent usage... - string getID(const Function *F) { + std::string getID(const Function *F) { return getID(F, "LLVMFunction_"); } - string getID(const BasicBlock *BB) { + std::string getID(const BasicBlock *BB) { return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str()); } - string getID(const GlobalVariable *GV) { + std::string getID(const GlobalVariable *GV) { return getID(GV, "LLVMGlobal_"); } - string getID(const Constant *CV) { + std::string getID(const Constant *CV) { return getID(CV, "LLVMConst_", ".C_"); } - string getID(const GlobalValue *GV) { + std::string getID(const GlobalValue *GV) { if (const GlobalVariable *V = dyn_cast(GV)) return getID(V); else if (const Function *F = dyn_cast(GV)) @@ -184,17 +184,25 @@ return ""; } + // Combines expressions + inline std::string ConstantArithExprToString(const ConstantExpr* CE, + const TargetMachine &TM, + const std::string &op) { + return "(" + valToExprString(CE->getOperand(0), TM) + op + + valToExprString(CE->getOperand(1), TM) + ")"; + } + // ConstantExprToString() - Convert a ConstantExpr to an asm expression // and return this as a string. - string ConstantExprToString(const ConstantExpr* CE, - const TargetMachine& target) { - string S; + std::string ConstantExprToString(const ConstantExpr* CE, + const TargetMachine& target) { + std::string S; switch(CE->getOpcode()) { case Instruction::GetElementPtr: { // generate a symbolic expression for the byte address const Value* ptrVal = CE->getOperand(0); std::vector idxVec(CE->op_begin()+1, CE->op_end()); - const TargetData &TD = target.getTargetData(); + const TargetData &TD = target.getTargetData(); S += "(" + valToExprString(ptrVal, target) + ") + (" + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")"; break; @@ -209,48 +217,40 @@ break; case Instruction::Add: - S += "(" + valToExprString(CE->getOperand(0), target) + ") + (" - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, ") + ("); break; case Instruction::Sub: - S += "(" + valToExprString(CE->getOperand(0), target) + ") - (" - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, ") - ("); break; case Instruction::Mul: - S += "(" + valToExprString(CE->getOperand(0), target) + ") * (" - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, ") * ("); break; case Instruction::Div: - S += "(" + valToExprString(CE->getOperand(0), target) + ") / (" - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, ") / ("); break; case Instruction::Rem: - S += "(" + valToExprString(CE->getOperand(0), target) + ") % (" - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, ") % ("); break; case Instruction::And: // Logical && for booleans; bitwise & otherwise - S += "(" + valToExprString(CE->getOperand(0), target) - + ((CE->getType() == Type::BoolTy)? ") && (" : ") & (") - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, + ((CE->getType() == Type::BoolTy)? ") && (" : ") & (")); break; case Instruction::Or: // Logical || for booleans; bitwise | otherwise - S += "(" + valToExprString(CE->getOperand(0), target) - + ((CE->getType() == Type::BoolTy)? ") || (" : ") | (") - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, + ((CE->getType() == Type::BoolTy)? ") || (" : ") | (")); break; case Instruction::Xor: // Bitwise ^ for all types - S += "(" + valToExprString(CE->getOperand(0), target) + ") ^ (" - + valToExprString(CE->getOperand(1), target) + ")"; + S += ConstantArithExprToString(CE, target, ") ^ ("); break; default: @@ -264,13 +264,13 @@ // valToExprString - Helper function for ConstantExprToString(). // Appends result to argument string S. // - string valToExprString(const Value* V, const TargetMachine& target) { - string S; + std::string valToExprString(const Value* V, const TargetMachine& target) { + std::string S; bool failed = false; if (const Constant* CV = dyn_cast(V)) { // symbolic or known if (const ConstantBool *CB = dyn_cast(CV)) - S += string(CB == ConstantBool::True ? "1" : "0"); + S += std::string(CB == ConstantBool::True ? "1" : "0"); else if (const ConstantSInt *CI = dyn_cast(CV)) S += itostr(CI->getValue()); else if (const ConstantUInt *CI = dyn_cast(CV)) @@ -525,7 +525,7 @@ void SparcFunctionAsmPrinter::emitFunction(const Function &F) { - string methName = getID(&F); + std::string methName = getID(&F); toAsm << "!****** Outputing Function: " << methName << " ******\n"; enterSection(AsmPrinter::Text); toAsm << "\t.align\t4\n\t.global\t" << methName << "\n"; @@ -588,7 +588,7 @@ void PrintZeroBytesToPad (int numBytes); void printSingleConstantValue (const Constant* CV); void printConstantValueOnly (const Constant* CV, int numPadBytesAfter = 0); - void printConstant (const Constant* CV, string valID = ""); + void printConstant (const Constant* CV, std::string valID = ""); static void FoldConstants (const Module &M, hash_set &moduleConstants); @@ -618,10 +618,10 @@ // getAsCString - Return the specified array as a C compatible string, only if // the predicate isStringCompatible is true. // -static string getAsCString(const ConstantArray *CVA) { +static std::string getAsCString(const ConstantArray *CVA) { assert(isStringCompatible(CVA) && "Array is not string compatible!"); - string Result; + std::string Result; const Type *ETy = cast(CVA->getType())->getElementType(); Result = "\""; for (unsigned i = 0; i < CVA->getNumOperands(); ++i) { @@ -653,7 +653,7 @@ } -inline const string +inline const std::string TypeToDataDirective(const Type* type) { switch(type->getPrimitiveID()) @@ -866,7 +866,7 @@ // appropriate directives. Uses printConstantValueOnly() to print the // value or values. void -SparcModuleAsmPrinter::printConstant(const Constant* CV, string valID) +SparcModuleAsmPrinter::printConstant(const Constant* CV, std::string valID) { if (valID.length() == 0) valID = getID(CV); From lattner at cs.uiuc.edu Tue Aug 5 11:12:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 11:12:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll 2003-08-05-MishandleInvoke.ll Message-ID: <200308051611.LAA16166@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyCFG: 2003-08-05-InvokeCrash.ll added (r1.1) 2003-08-05-MishandleInvoke.ll added (r1.1) --- Log message: new testcases that simplifycfg breaks --- Diffs of the changes: Index: llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll diff -c /dev/null llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll:1.1 *** /dev/null Tue Aug 5 11:11:46 2003 --- llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll Tue Aug 5 11:11:36 2003 *************** *** 0 **** --- 1,9 ---- + ; Do not remove the invoke! + ; + ; RUN: as < %s | opt -simplifycfg -disable-output + + int %test() { + %A = invoke int %test() to label %Ret except label %Ret + Ret: + ret int %A + } Index: llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll diff -c /dev/null llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll:1.1 *** /dev/null Tue Aug 5 11:11:46 2003 --- llvm/test/Regression/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll Tue Aug 5 11:11:36 2003 *************** *** 0 **** --- 1,10 ---- + ; Do not remove the invoke! + ; + ; RUN: as < %s | opt -simplifycfg | dis | grep invoke + + int %test() { + invoke int %test() to label %Ret except label %Ret + Ret: + %A = add int 0, 1 + ret int %A + } From lattner at cs.uiuc.edu Tue Aug 5 11:28:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 11:28:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200308051627.LAA17734@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: SimplifyCFG.cpp updated: 1.11 -> 1.12 --- Log message: Fix bug: SimplifyCFG/2003-08-05-InvokeCrash.ll Fix bug: SimplifyCFG/2003-08-05-MishandleInvoke.ll --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.11 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.12 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.11 Wed Apr 23 11:37:44 2003 +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp Tue Aug 5 11:27:44 2003 @@ -201,7 +201,8 @@ } BasicBlock *OnlySucc = 0; - if (OnlyPred && OnlyPred != BB) { // Don't break self loops + if (OnlyPred && OnlyPred != BB && // Don't break self loops + OnlyPred->getTerminator()->getOpcode() != Instruction::Invoke) { // Check to see if there is only one distinct successor... succ_iterator SI(succ_begin(OnlyPred)), SE(succ_end(OnlyPred)); OnlySucc = BB; From lattner at cs.uiuc.edu Tue Aug 5 11:35:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 11:35:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.cpp Message-ID: <200308051634.LAA18257@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.cpp updated: 1.20 -> 1.21 --- Log message: Factor shared code --- Diffs of the changes: Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.20 llvm/lib/Target/X86/X86TargetMachine.cpp:1.21 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.20 Sat Jul 26 18:49:58 2003 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Tue Aug 5 11:34:44 2003 @@ -41,15 +41,12 @@ FrameInfo(TargetFrameInfo::StackGrowsDown, 8/*16 for SSE*/, 4) { } -// llc backend for x86 + +// addPassesToEmitAssembly - We currently use all of the same passes as the JIT +// does to emit statically compiled machine code. bool X86TargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) { - PM.add(createLowerSwitchPass()); - PM.add(createX86SimpleInstructionSelector(*this)); - PM.add(createLocalRegisterAllocator()); - PM.add(createX86FloatingPointStackifierPass()); - PM.add(createPrologEpilogCodeInserter()); - PM.add(createX86PeepholeOptimizerPass()); + addPassesToJITCompile(PM); PM.add(createX86CodePrinterPass(Out, *this)); return false; // success! } @@ -93,7 +90,6 @@ if (PrintCode) // Print the register-allocated code PM.add(createX86CodePrinterPass(std::cerr, *this)); - return false; // success! } From kowshik at cs.uiuc.edu Tue Aug 5 11:58:00 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue Aug 5 11:58:00 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/PoolAllocate.h Message-ID: <200308051657.LAA27390@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: PoolAllocate.h updated: 1.4 -> 1.5 --- Log message: Added the declaration of InlineIndirectCalls --- Diffs of the changes: Index: llvm/include/llvm/Transforms/PoolAllocate.h diff -u llvm/include/llvm/Transforms/PoolAllocate.h:1.4 llvm/include/llvm/Transforms/PoolAllocate.h:1.5 --- llvm/include/llvm/Transforms/PoolAllocate.h:1.4 Sun Jun 29 22:13:36 2003 +++ llvm/include/llvm/Transforms/PoolAllocate.h Tue Aug 5 11:56:59 2003 @@ -72,6 +72,8 @@ BUDataStructures *BU; TDDataStructures *TDDS; + + hash_set InlinedFuncs; std::map FunctionInfo; @@ -98,7 +100,7 @@ // If an equivalence class does not require pool arguments, it is not // on this map. std::map EqClass2LastPoolArg; - + public: bool run(Module &M); @@ -141,6 +143,9 @@ void TransformFunctionBody(Function &F, Function &OldF, DSGraph &G, PA::FuncInfo &FI); + + void InlineIndirectCalls(Function &F, DSGraph &G, + hash_set &visited); }; #endif From lattner at cs.uiuc.edu Tue Aug 5 11:59:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 11:59:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstr.cpp Message-ID: <200308051658.LAA27426@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.75 -> 1.76 --- Log message: All callers of these methods actually wanted them to preserve the flags, so get rid of the def/use parameters that were getting passed in. **** This now changes the semantics of these methods to preserve the flags, not clobber them! --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.75 llvm/lib/CodeGen/MachineInstr.cpp:1.76 --- llvm/lib/CodeGen/MachineInstr.cpp:1.75 Sun Aug 3 16:51:45 2003 +++ llvm/lib/CodeGen/MachineInstr.cpp Tue Aug 5 11:58:46 2003 @@ -80,24 +80,13 @@ operands.resize(numOperands, MachineOperand()); } -void -MachineInstr::SetMachineOperandVal(unsigned i, - MachineOperand::MachineOperandType opType, - Value* V, - bool isdef, - bool isDefAndUse) -{ +void MachineInstr::SetMachineOperandVal(unsigned i, + MachineOperand::MachineOperandType opTy, + Value* V) { assert(i < operands.size()); // may be explicit or implicit op - operands[i].opType = opType; + operands[i].opType = opTy; operands[i].value = V; operands[i].regNum = -1; - - if (isDefAndUse) - operands[i].flags = MachineOperand::DEFUSEFLAG; - else if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) - operands[i].flags = MachineOperand::DEFONLYFLAG; - else - operands[i].flags = 0; } void @@ -116,22 +105,12 @@ operands[i].flags = 0; } -void -MachineInstr::SetMachineOperandReg(unsigned i, - int regNum, - bool isdef) { +void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) { assert(i < getNumOperands()); // must be explicit op operands[i].opType = MachineOperand::MO_MachineRegister; operands[i].value = NULL; operands[i].regNum = regNum; - - if (isdef || TargetInstrDescriptors[opCode].resultPos == (int)i) { - assert(operands[i].flags == MachineOperand::DEFONLYFLAG && - "Shouldn't be changing a register type once set!"); - operands[i].flags = MachineOperand::DEFONLYFLAG; - } - insertUsedReg(regNum); } From lattner at cs.uiuc.edu Tue Aug 5 11:59:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 11:59:08 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200308051658.LAA27418@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.107 -> 1.108 --- Log message: All callers of these methods actually wanted them to preserve the flags, so get rid of the def/use parameters that were getting passed in. **** This now changes the semantics of these methods to preserve the flags, not clobber them! --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.107 llvm/include/llvm/CodeGen/MachineInstr.h:1.108 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.107 Fri Jul 25 15:58:57 2003 +++ llvm/include/llvm/CodeGen/MachineInstr.h Tue Aug 5 11:58:44 2003 @@ -432,12 +432,10 @@ ++numImplicitRefs; addRegOperand(V, isDef, isDefAndUse); } - void setImplicitRef(unsigned i, Value* V, bool isDef=false, - bool isDefAndUse=false) { + void setImplicitRef(unsigned i, Value* V) { assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!"); SetMachineOperandVal(i + getNumOperands(), - MachineOperand::MO_VirtualRegister, - V, isDef, isDefAndUse); + MachineOperand::MO_VirtualRegister, V); } // @@ -631,17 +629,13 @@ // void SetMachineOperandVal (unsigned i, MachineOperand::MachineOperandType operandType, - Value* V, - bool isDef=false, - bool isDefAndUse=false); + Value* V); void SetMachineOperandConst (unsigned i, MachineOperand::MachineOperandType operandType, int64_t intValue); - void SetMachineOperandReg (unsigned i, - int regNum, - bool isDef=false); + void SetMachineOperandReg(unsigned i, int regNum); unsigned substituteValue(const Value* oldVal, Value* newVal, From lattner at cs.uiuc.edu Tue Aug 5 12:00:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 12:00:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200308051659.LAA27495@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.110 -> 1.111 --- Log message: This method has now been changed to preserve flags for us! --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.110 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.111 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.110 Fri Aug 1 10:54:38 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Tue Aug 5 11:59:24 2003 @@ -1367,11 +1367,8 @@ } for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); igetImplicitRef(i) == unusedOp) { - minstr->setImplicitRef(i, fwdOp, - minstr->getImplicitOp(i).opIsDefOnly(), - minstr->getImplicitOp(i).opIsDefAndUse()); - } + if (minstr->getImplicitRef(i) == unusedOp) + minstr->setImplicitRef(i, fwdOp); } } } From lattner at cs.uiuc.edu Tue Aug 5 12:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 12:01:01 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/JIT/Emitter.cpp Message-ID: <200308051700.MAA27531@apoc.cs.uiuc.edu> Changes in directory llvm/tools/lli/JIT: Emitter.cpp updated: 1.21 -> 1.22 --- Log message: Specify DEBUG_TYPE's for the JIT debug messages --- Diffs of the changes: Index: llvm/tools/lli/JIT/Emitter.cpp diff -u llvm/tools/lli/JIT/Emitter.cpp:1.21 llvm/tools/lli/JIT/Emitter.cpp:1.22 --- llvm/tools/lli/JIT/Emitter.cpp:1.21 Fri Aug 1 17:13:56 2003 +++ llvm/tools/lli/JIT/Emitter.cpp Tue Aug 5 12:00:32 2003 @@ -5,6 +5,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "jit" #include "VM.h" #include "Config/sys/mman.h" #include "llvm/CodeGen/MachineCodeEmitter.h" From lattner at cs.uiuc.edu Tue Aug 5 12:01:09 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 12:01:09 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/ExecutionEngine.cpp Message-ID: <200308051700.MAA27524@apoc.cs.uiuc.edu> Changes in directory llvm/tools/lli: ExecutionEngine.cpp updated: 1.17 -> 1.18 --- Log message: Specify DEBUG_TYPE's for the JIT debug messages --- Diffs of the changes: Index: llvm/tools/lli/ExecutionEngine.cpp diff -u llvm/tools/lli/ExecutionEngine.cpp:1.17 llvm/tools/lli/ExecutionEngine.cpp:1.18 --- llvm/tools/lli/ExecutionEngine.cpp:1.17 Fri Aug 1 17:13:57 2003 +++ llvm/tools/lli/ExecutionEngine.cpp Tue Aug 5 12:00:30 2003 @@ -5,6 +5,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "jit" #include "ExecutionEngine.h" #include "GenericValue.h" #include "llvm/DerivedTypes.h" From kowshik at cs.uiuc.edu Tue Aug 5 12:03:01 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue Aug 5 12:03:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200308051702.MAA27582@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.12 -> 1.13 --- Log message: Major bug fixes including a memory leak and tracking some exceptional conditions. Also added support for including global and indirect call information in the DS graphs used by the pool allocation --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.12 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.13 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.12 Fri Aug 1 17:15:01 2003 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Tue Aug 5 12:01:54 2003 @@ -19,6 +19,8 @@ #include "Support/VectorExtras.h" using namespace PA; +#define DEBUG_TYPE "PoolAllocation" + namespace { const Type *VoidPtrTy = PointerType::get(Type::SByteTy); @@ -55,6 +57,15 @@ } } +static void printNTOMap(std::map &NTOM) { + std::cerr << "NTOM MAP\n"; + for (std::map::iterator I = NTOM.begin(), + E = NTOM.end(); I != E; ++I) { + if (!isa(I->first) && !isa(I->first)) + std::cerr << *I->first << " to " << *I->second << "\n"; + } +} + void PoolAllocate::buildIndirectFunctionSets(Module &M) { // Iterate over the module looking for indirect calls to functions @@ -121,7 +132,7 @@ std::map FuncMap; - // Loop over the functions in the original program finding the pool desc. + // Loop over the functions in the original program finding the pool desc. // arguments necessary for each function that is indirectly callable. // For each equivalence class, make a list of pool arguments and update // the PoolArgFirst and PoolArgLast values for each function. @@ -195,8 +206,65 @@ } +// Inline the DSGraphs of functions corresponding to the potential targets at +// indirect call sites into the DS Graph of the callee. +// This is required to know what pools to create/pass at the call site in the +// caller +// +void PoolAllocate::InlineIndirectCalls(Function &F, DSGraph &G, + hash_set &visited) { + std::vector callSites = G.getFunctionCalls(); + + visited.insert(&F); + + // For each indirect call site in the function, inline all the potential + // targets + for (std::vector::iterator CSI = callSites.begin(), + CSE = callSites.end(); CSI != CSE; ++CSI) { + if (CSI->isIndirectCall()) { + CallInst &CI = CSI->getCallInst(); + std::pair::iterator, + std::multimap::iterator> Targets = + CallInstTargets.equal_range(&CI); + for (std::multimap::iterator TFI = Targets.first, + TFE = Targets.second; TFI != TFE; ++TFI) { + DSGraph &TargetG = BU->getDSGraph(*TFI->second); + // Call the function recursively if the callee is not yet inlined + // and if it hasn't been visited in this sequence of calls + // The latter is dependent on the fact that the graphs of all functions + // in an SCC are actually the same + if (InlinedFuncs.find(TFI->second) == InlinedFuncs.end() && + visited.find(TFI->second) == visited.end()) { + InlineIndirectCalls(*TFI->second, TargetG, visited); + } + G.mergeInGraph(*CSI, *TFI->second, TargetG, DSGraph::KeepModRefBits | + DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes | + DSGraph::DontCloneAuxCallNodes); + } + } + } + + // Mark this function as one whose graph is inlined with its indirect + // function targets' DS Graphs. This ensures that every function is inlined + // exactly once + InlinedFuncs.insert(&F); + + +} + void PoolAllocate::FindFunctionPoolArgs(Function &F) { + + // The DSGraph is merged with the globals graph. DSGraph &G = BU->getDSGraph(F); + G.mergeInGlobalsGraph(); + + // Inline the potential targets of indirect calls + hash_set visitedFuncs; + InlineIndirectCalls(F, G, visitedFuncs); + + // At this point the DS Graphs have been modified in place including + // information about globals as well as indirect calls, making it useful + // for pool allocation std::vector &Nodes = G.getNodes(); if (Nodes.empty()) return ; // No memory activity, nothing is required @@ -225,10 +293,13 @@ // Mark globals and incomplete nodes as live... (this handles arguments) if (F.getName() != "main") - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - if ((Nodes[i]->isGlobalNode() || Nodes[i]->isIncomplete()) && - Nodes[i]->isHeapNode()) + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + if (Nodes[i]->isGlobalNode() && !Nodes[i]->isIncomplete()) + DEBUG(std::cerr << "Global node is not Incomplete\n"); + if ((Nodes[i]->isIncomplete() || Nodes[i]->isGlobalNode()) && + Nodes[i]->isHeapNode()) Nodes[i]->markReachableNodes(MarkedNodes); + } // Marked the returned node as alive... if (DSNode *RetNode = G.getReturnNodeFor(F).getNode()) @@ -238,9 +309,20 @@ if (MarkedNodes.empty()) // We don't need to clone the function if there return; // are no incoming arguments to be added. + // Erase any marked node that is not a heap node + for (hash_set::iterator I = MarkedNodes.begin(), - E = MarkedNodes.end(); I != E; ++I) - FI.PoolArgLast++; + E = MarkedNodes.end(); I != E; ) { + // erase invalidates hash_set iterators if the iterator points to the + // element being erased + if (!(*I)->isHeapNode()) + MarkedNodes.erase(I++); + else + ++I; + } + + FI.PoolArgLast += MarkedNodes.size(); + if (FuncECs.findClass(&F)) { // Update the equivalence class last pool argument information @@ -260,6 +342,7 @@ Function *PoolAllocate::MakeFunctionClone(Function &F) { DSGraph &G = BU->getDSGraph(F); + std::vector &Nodes = G.getNodes(); if (Nodes.empty()) return 0; @@ -270,7 +353,6 @@ if (!FuncECs.findClass(&F)) { // Not in any equivalence class - if (MarkedNodes.empty()) return 0; } else { @@ -396,6 +478,7 @@ // void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) { DSGraph &G = BU->getDSGraph(F); + std::vector &Nodes = G.getNodes(); if (Nodes.empty()) return; // Quick exit if nothing to do... @@ -455,8 +538,10 @@ // Void types in DS graph are never used if (Node->getType() != Type::VoidTy) ElSize = ConstantUInt::get(Type::UIntTy, TD.getTypeSize(Node->getType())); - else + else { + std::cerr << "Potential node collapsing in " << F.getName() << "\n"; ElSize = ConstantUInt::get(Type::UIntTy, 0); + } // Insert the call to initialize the pool... new CallInst(PoolInit, make_vector(AI, ElSize, 0), "", InsertPoint); @@ -477,8 +562,8 @@ /// allocated functions. struct FuncTransform : public InstVisitor { PoolAllocate &PAInfo; - DSGraph &G; - DSGraph &TDG; + DSGraph &G; // The Bottom-up DS Graph + DSGraph &TDG; // The Top-down DS Graph FuncInfo &FI; FuncTransform(PoolAllocate &P, DSGraph &g, DSGraph &tdg, FuncInfo &fi) @@ -509,9 +594,9 @@ } private: - DSNode *getDSNodeFor(Value *V) { - if (isa(V)) - return 0; + DSNodeHandle& getDSNodeHFor(Value *V) { + // if (isa(V)) + // return DSNodeHandle(); if (!FI.NewToOldValueMap.empty()) { // If the NewToOldValueMap is in effect, use it. @@ -520,10 +605,11 @@ V = (Value*)I->second; } - return G.getScalarMap()[V].getNode(); + return G.getScalarMap()[V]; } + Value *getPoolHandle(Value *V) { - DSNode *Node = getDSNodeFor(V); + DSNode *Node = getDSNodeHFor(V).getNode(); // Get the pool handle for this DSNode... std::map::iterator I = FI.PoolDescriptors.find(Node); return I != FI.PoolDescriptors.end() ? I->second : 0; @@ -595,51 +681,87 @@ return 0; } -void FuncTransform::visitReturnInst (ReturnInst &I) { - if (I.getNumOperands()) - if (Value *clonedFunc = retCloneIfFunc(I.getOperand(0))) { - // Cast the clone of I.getOperand(0) to the non-pool-allocated type - CastInst *CastI = new CastInst(clonedFunc, I.getOperand(0)->getType(), - "tmp", &I); +void FuncTransform::visitReturnInst (ReturnInst &RI) { + if (RI.getNumOperands()) + if (Value *clonedFunc = retCloneIfFunc(RI.getOperand(0))) { + // Cast the clone of RI.getOperand(0) to the non-pool-allocated type + CastInst *CastI = new CastInst(clonedFunc, RI.getOperand(0)->getType(), + "tmp", &RI); // Insert return instruction that returns the casted value - new ReturnInst(CastI, &I); + ReturnInst *RetI = new ReturnInst(CastI, &RI); // Remove original return instruction - I.getParent()->getInstList().erase(&I); + RI.getParent()->getInstList().erase(&RI); + + if (!FI.NewToOldValueMap.empty()) { + std::map::iterator II = + FI.NewToOldValueMap.find(&RI); + assert(II != FI.NewToOldValueMap.end() && + "RI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(RetI, II->second)); + FI.NewToOldValueMap.erase(II); + } } } -void FuncTransform::visitStoreInst (StoreInst &I) { +void FuncTransform::visitStoreInst (StoreInst &SI) { // Check if a constant function is being stored - if (Value *clonedFunc = retCloneIfFunc(I.getOperand(0))) { - CastInst *CastI = new CastInst(clonedFunc, I.getOperand(0)->getType(), - "tmp", &I); - new StoreInst(CastI, I.getOperand(1), &I); - I.getParent()->getInstList().erase(&I); + if (Value *clonedFunc = retCloneIfFunc(SI.getOperand(0))) { + CastInst *CastI = new CastInst(clonedFunc, SI.getOperand(0)->getType(), + "tmp", &SI); + StoreInst *StoreI = new StoreInst(CastI, SI.getOperand(1), &SI); + SI.getParent()->getInstList().erase(&SI); + + // Update the NewToOldValueMap if this is a clone + if (!FI.NewToOldValueMap.empty()) { + std::map::iterator II = + FI.NewToOldValueMap.find(&SI); + assert(II != FI.NewToOldValueMap.end() && + "SI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(StoreI, II->second)); + FI.NewToOldValueMap.erase(II); + } } } -void FuncTransform::visitPHINode(PHINode &I) { +void FuncTransform::visitPHINode(PHINode &PI) { // If any of the operands of the PHI node is a constant function pointer // that is cloned, the cast instruction has to be inserted at the end of the // previous basic block - if (isFuncPtr(&I)) { - PHINode *V = new PHINode(I.getType(), I.getName(), &I); - for (unsigned i = 0 ; i < I.getNumIncomingValues(); ++i) { - if (Value *clonedFunc = retCloneIfFunc(I.getIncomingValue(i))) { - // Insert CastInst at the end of I.getIncomingBlock(i) - BasicBlock::iterator BBI = --I.getIncomingBlock(i)->end(); + if (isFuncPtr(&PI)) { + PHINode *V = new PHINode(PI.getType(), PI.getName(), &PI); + for (unsigned i = 0 ; i < PI.getNumIncomingValues(); ++i) { + if (Value *clonedFunc = retCloneIfFunc(PI.getIncomingValue(i))) { + // Insert CastInst at the end of PI.getIncomingBlock(i) + BasicBlock::iterator BBI = --PI.getIncomingBlock(i)->end(); // BBI now points to the terminator instruction of the basic block. - CastInst *CastI = new CastInst(clonedFunc, I.getType(), "tmp", BBI); - V->addIncoming(CastI, I.getIncomingBlock(i)); + CastInst *CastI = new CastInst(clonedFunc, PI.getType(), "tmp", BBI); + V->addIncoming(CastI, PI.getIncomingBlock(i)); } else { - V->addIncoming(I.getIncomingValue(i), I.getIncomingBlock(i)); + V->addIncoming(PI.getIncomingValue(i), PI.getIncomingBlock(i)); } } - I.replaceAllUsesWith(V); - I.getParent()->getInstList().erase(&I); + PI.replaceAllUsesWith(V); + PI.getParent()->getInstList().erase(&PI); + + DSGraph::ScalarMapTy &SM = G.getScalarMap(); + DSGraph::ScalarMapTy::iterator PII = SM.find(&PI); + + // Update Scalar map of DSGraph if this is one of the original functions + // Otherwise update the NewToOldValueMap + if (PII != SM.end()) { + SM.insert(std::make_pair(V, PII->second)); + SM.erase(PII); // Destroy the PHINode + } else { + std::map::iterator II = + FI.NewToOldValueMap.find(&PI); + assert(II != FI.NewToOldValueMap.end() && + "PhiI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(V, II->second)); + FI.NewToOldValueMap.erase(II); + } } } @@ -660,12 +782,16 @@ MI.setName(""); // Nuke MIs name - // Cast to the appropriate type... - Value *Casted = new CastInst(V, MI.getType(), V->getName(), &MI); - + Value *Casted = V; + + // Cast to the appropriate type if necessary + if (V->getType() != MI.getType()) { + Casted = new CastInst(V, MI.getType(), V->getName(), &MI); + } + // Update def-use info MI.replaceAllUsesWith(Casted); - + // Remove old malloc instruction MI.getParent()->getInstList().erase(&MI); @@ -676,56 +802,96 @@ if (MII != SM.end()) { // V and Casted now point to whatever the original malloc did... SM.insert(std::make_pair(V, MII->second)); - SM.insert(std::make_pair(Casted, MII->second)); + if (V != Casted) + SM.insert(std::make_pair(Casted, MII->second)); SM.erase(MII); // The malloc is now destroyed } else { // Otherwise, update the NewToOldValueMap std::map::iterator MII = FI.NewToOldValueMap.find(&MI); assert(MII != FI.NewToOldValueMap.end() && "MI not found in clone?"); FI.NewToOldValueMap.insert(std::make_pair(V, MII->second)); - FI.NewToOldValueMap.insert(std::make_pair(Casted, MII->second)); + if (V != Casted) + FI.NewToOldValueMap.insert(std::make_pair(Casted, MII->second)); FI.NewToOldValueMap.erase(MII); } } -void FuncTransform::visitFreeInst(FreeInst &FI) { - Value *Arg = FI.getOperand(0); +void FuncTransform::visitFreeInst(FreeInst &FrI) { + Value *Arg = FrI.getOperand(0); Value *PH = getPoolHandle(Arg); // Get the pool handle for this DSNode... if (PH == 0) return; // Insert a cast and a call to poolfree... - Value *Casted = new CastInst(Arg, PointerType::get(Type::SByteTy), - Arg->getName()+".casted", &FI); - new CallInst(PAInfo.PoolFree, make_vector(PH, Casted, 0), "", &FI); - + Value *Casted = Arg; + if (Arg->getType() != PointerType::get(Type::SByteTy)) + Casted = new CastInst(Arg, PointerType::get(Type::SByteTy), + Arg->getName()+".casted", &FrI); + + CallInst *FreeI = new CallInst(PAInfo.PoolFree, make_vector(PH, Casted, 0), + "", &FrI); // Delete the now obsolete free instruction... - FI.getParent()->getInstList().erase(&FI); + FrI.getParent()->getInstList().erase(&FrI); + + // Update the NewToOldValueMap if this is a clone + if (!FI.NewToOldValueMap.empty()) { + std::map::iterator II = + FI.NewToOldValueMap.find(&FrI); + assert(II != FI.NewToOldValueMap.end() && + "FrI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(FreeI, II->second)); + FI.NewToOldValueMap.erase(II); + } } -static void CalcNodeMapping(DSNode *Caller, DSNode *Callee, +static void CalcNodeMapping(DSNodeHandle& Caller, DSNodeHandle& Callee, std::map &NodeMapping) { - if (Callee == 0) return; - // assert(Caller && "Callee has node but caller doesn't??"); + DSNode *CalleeNode = Callee.getNode(); + DSNode *CallerNode = Caller.getNode(); + + unsigned CalleeOffset = Callee.getOffset(); + unsigned CallerOffset = Caller.getOffset(); + + if (CalleeNode == 0) return; // If callee has a node and caller doesn't, then a constant argument was // passed by the caller - if (Caller == 0) { - NodeMapping.insert(NodeMapping.end(), std::make_pair(Callee, (DSNode*) 0)); + if (CallerNode == 0) { + NodeMapping.insert(NodeMapping.end(), std::make_pair(CalleeNode, + (DSNode *) 0)); } - std::map::iterator I = NodeMapping.find(Callee); + // Map the callee node to the caller node. + // NB: The callee node could be of a different type. Eg. if it points to the + // field of a struct that the caller points to + std::map::iterator I = NodeMapping.find(CalleeNode); if (I != NodeMapping.end()) { // Node already in map... - assert(I->second == Caller && "Node maps to different nodes on paths?"); + assert(I->second == CallerNode && + "Node maps to different nodes on paths?"); } else { - NodeMapping.insert(I, std::make_pair(Callee, Caller)); + NodeMapping.insert(I, std::make_pair(CalleeNode, CallerNode)); - // Recursively add pointed to nodes... - unsigned numCallerLinks = Caller->getNumLinks(); - unsigned numCalleeLinks = Callee->getNumLinks(); + if (CalleeNode->getType() != CallerNode->getType() && CallerOffset == 0) + DEBUG(std::cerr << "NB: Mapping of nodes between different types\n"); - assert (numCallerLinks <= numCalleeLinks || numCalleeLinks == 0); - - for (unsigned i = 0, e = numCalleeLinks; i != e; ++i) - CalcNodeMapping(Caller->getLink((i%numCallerLinks) << DS::PointerShift).getNode(), Callee->getLink(i << DS::PointerShift).getNode(), NodeMapping); + // Recursively map the callee links to the caller links starting from the + // offset in the node into which they are mapped. + // Being a BU Graph, the callee ought to have smaller number of links unless + // there is collapsing in the caller + unsigned numCallerLinks = CallerNode->getNumLinks() - CallerOffset; + unsigned numCalleeLinks = CalleeNode->getNumLinks() - CalleeOffset; + + if (numCallerLinks > 0) { + if (numCallerLinks < numCalleeLinks) { + std::cerr << "Potential node collapsing in caller\n"; + for (unsigned i = 0, e = numCalleeLinks; i != e; ++i) + CalcNodeMapping(CallerNode->getLink(((i%numCallerLinks) << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping); + } else { + for (unsigned i = 0, e = numCalleeLinks; i != e; ++i) + CalcNodeMapping(CallerNode->getLink((i << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping); + } + } else if (numCalleeLinks > 0) { + std::cerr << + "Caller has unexpanded node, due to indirect call perhaps!\n"; + } } } @@ -750,6 +916,8 @@ } + DSGraph &CallerG = G; + std::vector Args; if (!CF) { // Indirect call DEBUG(std::cerr << " Handling call: " << CI); @@ -781,17 +949,27 @@ unsigned OpNum = 1; for ( ; AI != AE; ++AI, ++OpNum) { if (!isa(CI.getOperand(OpNum))) - CalcNodeMapping(getDSNodeFor(CI.getOperand(OpNum)), - CG.getScalarMap()[AI].getNode(), + CalcNodeMapping(getDSNodeHFor(CI.getOperand(OpNum)), + CG.getScalarMap()[AI], NodeMapping); } assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!"); if (CI.getType() != Type::VoidTy) - CalcNodeMapping(getDSNodeFor(&CI), - CG.getReturnNodeFor(*TFI->second).getNode(), + CalcNodeMapping(getDSNodeHFor(&CI), + CG.getReturnNodeFor(*TFI->second), NodeMapping); + // Map the nodes that are pointed to by globals. + // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g) + for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(), + SME = G.getScalarMap().end(); SMI != SME; ++SMI) + if (isa(SMI->first)) { + CalcNodeMapping(SMI->second, + CG.getScalarMap()[SMI->first], + NodeMapping); + } + unsigned idx = CFI->PoolArgFirst; // The following loop determines the pool pointers corresponding to @@ -845,6 +1023,30 @@ CI.replaceAllUsesWith(NewCall); DEBUG(std::cerr << " Result Call: " << *NewCall); + + if (CI.getType() != Type::VoidTy) { + // If we are modifying the original function, update the DSGraph... + DSGraph::ScalarMapTy &SM = G.getScalarMap(); + DSGraph::ScalarMapTy::iterator CII = SM.find(&CI); + if (CII != SM.end()) { + SM.insert(std::make_pair(NewCall, CII->second)); + SM.erase(CII); // Destroy the CallInst + } else { + // Otherwise update the NewToOldValueMap with the new CI return value + std::map::iterator CII = + FI.NewToOldValueMap.find(&CI); + assert(CII != FI.NewToOldValueMap.end() && "CI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(NewCall, CII->second)); + FI.NewToOldValueMap.erase(CII); + } + } else if (!FI.NewToOldValueMap.empty()) { + std::map::iterator II = + FI.NewToOldValueMap.find(&CI); + assert(II != FI.NewToOldValueMap.end() && + "CI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(NewCall, II->second)); + FI.NewToOldValueMap.erase(II); + } } else { @@ -855,7 +1057,7 @@ DEBUG(std::cerr << " Handling call: " << CI); DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(*CF); // Callee graph - + // We need to figure out which local pool descriptors correspond to the pool // descriptor arguments passed into the function call. Calculate a mapping // from callee DSNodes to caller DSNodes. We construct a partial isomophism @@ -867,21 +1069,27 @@ Function::aiterator AI = CF->abegin(), AE = CF->aend(); unsigned OpNum = 1; for (; AI != AE; ++AI, ++OpNum) { - // Check if the operand of the call is a return of another call - // for the operand will be transformed in which case. - // Look up the OldToNewRetValMap to see if the operand is a new value. Value *callOp = CI.getOperand(OpNum); if (!isa(callOp)) - CalcNodeMapping(getDSNodeFor(callOp),CG.getScalarMap()[AI].getNode(), + CalcNodeMapping(getDSNodeHFor(callOp), CG.getScalarMap()[AI], NodeMapping); } assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!"); // Map the return value as well... if (CI.getType() != Type::VoidTy) - CalcNodeMapping(getDSNodeFor(&CI), CG.getReturnNodeFor(*CF).getNode(), + CalcNodeMapping(getDSNodeHFor(&CI), CG.getReturnNodeFor(*CF), NodeMapping); + // Map the nodes that are pointed to by globals. + // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g) + for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(), + SME = G.getScalarMap().end(); SMI != SME; ++SMI) + if (isa(SMI->first)) { + CalcNodeMapping(SMI->second, + CG.getScalarMap()[SMI->first], NodeMapping); + } + // Okay, now that we have established our mapping, we can figure out which // pool descriptors to pass in... @@ -893,13 +1101,12 @@ for (unsigned i = 0, e = CFI->ArgNodes.size(); i != e; ++i) { if (NodeMapping.count(CFI->ArgNodes[i])) { - assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!"); + DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second; if (LocalNode) { assert(FI.PoolDescriptors.count(LocalNode) && "Node not pool allocated?"); Args.push_back(FI.PoolDescriptors.find(LocalNode)->second); - } - else + } else Args.push_back(Constant::getNullValue(PoolDescPtr)); } else { Args.push_back(Constant::getNullValue(PoolDescPtr)); @@ -917,11 +1124,38 @@ Args.insert(Args.end(), CI.op_begin()+1, CI.op_end()); std::string Name = CI.getName(); + + std::map::iterator CNewII; + Value *NewCall = new CallInst(CFI->Clone, Args, Name, &CI); + CI.replaceAllUsesWith(NewCall); DEBUG(std::cerr << " Result Call: " << *NewCall); + if (CI.getType() != Type::VoidTy) { + // If we are modifying the original function, update the DSGraph... + DSGraph::ScalarMapTy &SM = G.getScalarMap(); + DSGraph::ScalarMapTy::iterator CII = SM.find(&CI); + if (CII != SM.end()) { + SM.insert(std::make_pair(NewCall, CII->second)); + SM.erase(CII); // Destroy the CallInst + } else { + // Otherwise update the NewToOldValueMap with the new CI return value + std::map::iterator CNII = + FI.NewToOldValueMap.find(&CI); + assert(CNII != FI.NewToOldValueMap.end() && CNII->second && + "CI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(NewCall, CNII->second)); + FI.NewToOldValueMap.erase(CNII); + } + } else if (!FI.NewToOldValueMap.empty()) { + std::map::iterator II = + FI.NewToOldValueMap.find(&CI); + assert(II != FI.NewToOldValueMap.end() && "CI not found in clone?"); + FI.NewToOldValueMap.insert(std::make_pair(NewCall, II->second)); + FI.NewToOldValueMap.erase(II); + } } - + CI.getParent()->getInstList().erase(&CI); } From kowshik at cs.uiuc.edu Tue Aug 5 12:05:02 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue Aug 5 12:05:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200308051704.MAA27608@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.117 -> 1.118 --- Log message: Added function mergeInGlobalsGraph which merges in the entire globals graph with the graph of a function --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.117 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.118 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.117 Fri Aug 1 17:14:28 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Tue Aug 5 12:04:41 2003 @@ -1582,3 +1582,32 @@ AssertAuxCallNodesInGraph(); } +// A function useful for clients to incorporate the globals graph +// into the DS, BU or TD graph for a function. This code retains +// all globals, i.e., does not delete unreachable globals after they +// are inlined. +// +void DSGraph::mergeInGlobalsGraph() +{ + NodeMapTy GlobalNodeMap; + ScalarMapTy OldValMap; + ReturnNodesTy OldRetNodes; + this->cloneInto(*GlobalsGraph, OldValMap, OldRetNodes, GlobalNodeMap, + DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes | + DSGraph::DontCloneAuxCallNodes); + + // Now merge existing global nodes in the GlobalsGraph with their copies + for (ScalarMapTy::iterator I = ScalarMap.begin(), E = ScalarMap.end(); + I != E; ++I) + if (isa(I->first)) { // Found a global node + DSNodeHandle &GH = I->second; + DSNodeHandle &GGNodeH = GlobalsGraph->getScalarMap()[I->first]; + GH.mergeWith(GlobalNodeMap[GGNodeH.getNode()]); + } + + // Merging leaves behind unused nodes: get rid of them now. + GlobalNodeMap.clear(); + OldValMap.clear(); + OldRetNodes.clear(); + removeTriviallyDeadNodes(); +} From kowshik at cs.uiuc.edu Tue Aug 5 12:07:01 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue Aug 5 12:07:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200308051706.MAA27633@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.56 -> 1.57 --- Log message: Added declaration of mergeInGlobalsGraph --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.56 llvm/include/llvm/Analysis/DSGraph.h:1.57 --- llvm/include/llvm/Analysis/DSGraph.h:1.56 Wed Jul 16 16:45:15 2003 +++ llvm/include/llvm/Analysis/DSGraph.h Tue Aug 5 12:06:18 2003 @@ -290,6 +290,8 @@ void AssertGraphOK() const; + void DSGraph::mergeInGlobalsGraph(); + public: // removeTriviallyDeadNodes - After the graph has been constructed, this // method removes all unreachable nodes that are created because they got From lattner at cs.uiuc.edu Tue Aug 5 12:10:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 12:10:04 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200308051709.MAA27656@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.108 -> 1.109 --- Log message: Remove unused method --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.108 llvm/include/llvm/CodeGen/MachineInstr.h:1.109 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.108 Tue Aug 5 11:58:44 2003 +++ llvm/include/llvm/CodeGen/MachineInstr.h Tue Aug 5 12:09:08 2003 @@ -444,9 +444,6 @@ const std::set &getRegsUsed() const { return regsUsed; } - bool isRegUsed(int regNum) const { - return regsUsed.find(regNum) != regsUsed.end(); - } void insertUsedReg(unsigned Reg) { assert(((int) Reg) >= 0 && "Invalid register being marked as used"); regsUsed.insert((int) Reg); From gaeke at cs.uiuc.edu Tue Aug 5 13:22:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Aug 5 13:22:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp GetTimer.h Makefile SLI.cpp SecondTrigger.cpp Timer.cpp Message-ID: <200308051821.NAA23635@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: FirstTrigger.cpp updated: 1.5 -> 1.6 GetTimer.h updated: 1.1 -> 1.2 Makefile updated: 1.2 -> 1.3 SLI.cpp updated: 1.1 -> 1.2 SecondTrigger.cpp updated: 1.2 -> 1.3 Timer.cpp updated: 1.1 -> 1.2 --- Log message: Miscellaneous cleanups. FirstTrigger.cpp, SecondTrigger.cpp: Rewrite top-of-file comment. Remove excess #includes; include C++ versions instead of C versions. Rewrite some comments and remove some dead code & variables. Take default values of env. variables from #defines in GetTimer.h. GetTimer.h: Add top-of-file comment and #include guards. Move more configuration variables into this file. Makefile: Get rid of excess LIBRARYNAME definitions. SLI.cpp: Remove excess #includes. Timer.cpp: Include C++ headers instead of C versions, and include GetTimer.h. Remove some dead code & variables. Take default values of env. variables from #defines in GetTimer.h. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.5 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.6 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.5 Fri Jul 18 17:45:59 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp Tue Aug 5 13:21:26 2003 @@ -1,9 +1,10 @@ -//==llvm/Reoptimizer/LightwtProfiling/Trigger/FirstTrigger.cpp----*- C++ -*--=// -// Implements First level trigger function +//===-- LightWtProfiling/Trigger/FirstTrigger.cpp ----------------*- C++ -*--=// // -// The trigger function is called at run time by instrumented code. -// The trigger function must analyse, and potentially optimize -// the trace that executes +// This file implements the reoptimizer's first-level trigger. The +// first-level trigger is a call, placed at the back-edge of each loop, to +// the function llvm_first_trigger(). It counts how many times each branch +// is taken, and if the counter exceeds a threshold, performs second-level +// instrumentation on the loop. // //===----------------------------------------------------------------------===// @@ -11,27 +12,24 @@ #include "llvm/Reoptimizer/InstrUtils.h" #include "llvm/Reoptimizer/TraceCache.h" #include "llvm/Reoptimizer/GetTraceTime.h" -#include -#include -#include -#include -#include #include "llvm/Reoptimizer/CFG.h" +#include +#include #include #include "GetTimer.h" +#ifdef __sparc +#include +#endif using namespace std; extern long THRESHOLD_LEVEL_2; extern long LEVEL_TWO_EXITS; +// Function used as space for the trace cache: +extern int dummyFunction2(int); -#ifdef __sparc -#include -#endif - -//global counters for diagonistcs -//extern "C" int initialize_timer(); +// Global counters for diagnostics: int initialize_timer(); extern uint64_t llvm_interval_counter; extern std::map exitCounter; @@ -39,21 +37,11 @@ extern std::map firstTriggerAddr; //tracestart addr extern std::map > backOffCounters; -#ifdef GET_ALL_INFO -int global_threshold2; -#endif - -//#define THRESHOLD_LEVEL_2 50 - -//good, bad backoff +// Good, bad backoff void insert_address_at(uint64_t n, uint64_t m); - void doInstrumentation(uint64_t addr1, uint64_t addr2, VirtualMem *vm); -//function used as dummy function -int dummyFunction2(int); - -int reopt_threshold=30; +int reopt_threshold = DEFAULT_THRESHOLD_LEVEL_1; int exit_count=0; TraceCache *tr; @@ -77,14 +65,14 @@ if(getenv("THRESHOLD_LEVEL_2")!=NULL) THRESHOLD_LEVEL_2 = atoi(getenv("THRESHOLD_LEVEL_2")); else - THRESHOLD_LEVEL_2= 50; + THRESHOLD_LEVEL_2= DEFAULT_THRESHOLD_LEVEL_2; LEVEL_TWO_EXITS = THRESHOLD_LEVEL_2/3; if(getenv("THRESHOLD_LEVEL_1")!=NULL) reopt_threshold = atoi(getenv("THRESHOLD_LEVEL_1")); else - reopt_threshold = 30; + reopt_threshold = DEFAULT_THRESHOLD_LEVEL_1; *t=30; Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.1 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.2 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.1 Fri Jul 18 11:06:05 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h Tue Aug 5 13:21:26 2003 @@ -1,6 +1,26 @@ -//Define common #defines here -//#define GET_ALL_INFO +//===-- GetTimer.h - LightWtProfiling reoptimizer knobs ----------*- C++ -*-==// +// +// Configuration parameters for the LightWtProfiling reoptimizer. +// +//===----------------------------------------------------------------------===// +#ifndef GETTIMER_H +#define GETTIMER_H + +#define GET_ALL_INFO +// #undef GET_COVERAGE #define MAX_PATH_HISTORIES 12 #define MAX_ALLOWED_PATHS 6 #define THRESHOLD_PERCENTAGE 90 + +// Default values for the THRESHOLD_LEVEL_2 and THRESHOLD_LEVEL_1 +// environment variables, used in FirstTrigger.cpp and SecondTrigger.cpp +#define DEFAULT_THRESHOLD_LEVEL_2 50 +#define DEFAULT_THRESHOLD_LEVEL_1 30 + +// Default values for the LLVM_TIMER_INTERVAL_SEC and LLVM_TIMER_INTERVAL_MSEC +// environment variables, used in Timer.cpp +#define DEFAULT_LLVM_TIMER_INTERVAL_SEC 3 +#define DEFAULT_LLVM_TIMER_INTERVAL_MSEC 0 + +#endif // GETTIMER_H Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Makefile diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Makefile:1.2 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Makefile:1.3 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Makefile:1.2 Fri Jul 18 11:04:09 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Makefile Tue Aug 5 13:21:26 2003 @@ -1,12 +1,5 @@ LEVEL = ../../../.. -ifdef GET_COVERAGE -LIBRARYNAME = firstTrigger2 -else -ifdef GET_EXTENSIVE -LIBRARYNAME = firstTrigger3 -else LIBRARYNAME = firstTrigger -endif -endif + include $(LEVEL)/Makefile.common Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp:1.1 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp:1.2 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp:1.1 Fri Jul 18 11:03:45 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp Tue Aug 5 13:21:27 2003 @@ -9,9 +9,6 @@ #include "llvm/Module.h" #include "GetTimer.h" #include -#include -#include -#include using namespace std; Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.2 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.3 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.2 Fri Jul 18 11:07:16 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Tue Aug 5 13:21:27 2003 @@ -1,10 +1,10 @@ - -//==llvm/Reoptimizer/LightwtProfiling/Trigger/SecondTrigger.cpp----*- C++ -*--=// -// Implements Second level trigger function +//===-- LightWtProfiling/Trigger/SecondTrigger.cpp ---------------*- C++ -*--=// // -// The trigger function is called at run time by instrumented code. -// The trigger function must analyse, and potentially optimize -// the trace that executes +// This file implements the reoptimizer's second-level trigger. +// Second-level instrumentation is performed by the first-level trigger +// function (see FirstTrigger.cpp). It records the paths taken through the +// instrumented region, as well as the number of early exits taken from +// the region. // //===----------------------------------------------------------------------===// @@ -18,12 +18,8 @@ #include "llvm/Module.h" #include "GetTimer.h" #include -#include -#include #include -#include -#include -#include +#include #ifdef __sparc #include @@ -32,9 +28,6 @@ using std::map; using std::vector; using std::pair; - -//#define GET_COVERAGE -//undef GET_COVERAGE extern "C" void llvm_time_end2(); extern "C" void llvm_time_start(); Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.cpp:1.1 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.cpp:1.2 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.cpp:1.1 Fri Jul 18 17:46:34 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.cpp Tue Aug 5 13:21:27 2003 @@ -1,12 +1,10 @@ #include #include #include -#include -#include -#include - -#define INTERVAL_USEC 000000 -#define INTERVAL_SEC 10 +#include +#include +#include +#include "GetTimer.h" extern "C" void do_timer_interval(); uint64_t llvm_interval_counter; @@ -15,9 +13,6 @@ sigset_t sig_old; sigset_t sig_all; - - - void mask_interrupt() { //sigprocmask(SIG_BLOCK, &sig_usr2, &sig_old); @@ -52,8 +47,7 @@ int initialize_timer() { - //printf("Intializing timer\n"); - int duration_sec=0, duration_msec=0; + int duration_sec, duration_msec; //struct sigaction *nvec, *ovec; timer_t timer_id; struct sigevent timer_evp; @@ -66,11 +60,11 @@ //duration of timer if(getenv("LLVM_TIMER_INTERVAL_SEC")!=NULL) duration_sec = atoi(getenv("LLVM_TIMER_INTERVAL_SEC")); - else duration_sec = 3; + else duration_sec = DEFAULT_LLVM_TIMER_INTERVAL_SEC; if(getenv("LLVM_TIMER_INTERVAL_MSEC")!=NULL) duration_sec = atoi(getenv("LLVM_TIMER_INTERVAL_MSEC")); - else duration_msec = 0; + else duration_msec = DEFAULT_LLVM_TIMER_INTERVAL_MSEC; if(timer_create(CLOCK_REALTIME, &timer_evp, &timer_id)<0) printf(" error\n"); From lattner at cs.uiuc.edu Tue Aug 5 13:39:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 13:39:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200308051838.NAA29791@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.57 -> 1.58 --- Log message: Add a comment to the method decl --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.57 llvm/include/llvm/Analysis/DSGraph.h:1.58 --- llvm/include/llvm/Analysis/DSGraph.h:1.57 Tue Aug 5 12:06:18 2003 +++ llvm/include/llvm/Analysis/DSGraph.h Tue Aug 5 13:38:16 2003 @@ -290,14 +290,18 @@ void AssertGraphOK() const; - void DSGraph::mergeInGlobalsGraph(); + /// mergeInGlobalsGraph - This method is useful for clients to incorporate the + /// globals graph into the DS, BU or TD graph for a function. This code + /// retains all globals, i.e., does not delete unreachable globals after they + /// are inlined. + /// + void mergeInGlobalsGraph(); -public: - // removeTriviallyDeadNodes - After the graph has been constructed, this - // method removes all unreachable nodes that are created because they got - // merged with other nodes in the graph. This is used as the first step of - // removeDeadNodes. - // + /// removeTriviallyDeadNodes - After the graph has been constructed, this + /// method removes all unreachable nodes that are created because they got + /// merged with other nodes in the graph. This is used as the first step of + /// removeDeadNodes. + /// void removeTriviallyDeadNodes(); }; From lattner at cs.uiuc.edu Tue Aug 5 13:39:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 13:39:11 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200308051838.NAA29808@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.118 -> 1.119 --- Log message: Add more verbose comment --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.118 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.119 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.118 Tue Aug 5 12:04:41 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Tue Aug 5 13:38:37 2003 @@ -1582,19 +1582,18 @@ AssertAuxCallNodesInGraph(); } -// A function useful for clients to incorporate the globals graph -// into the DS, BU or TD graph for a function. This code retains -// all globals, i.e., does not delete unreachable globals after they -// are inlined. -// -void DSGraph::mergeInGlobalsGraph() -{ +/// mergeInGlobalsGraph - This method is useful for clients to incorporate the +/// globals graph into the DS, BU or TD graph for a function. This code retains +/// all globals, i.e., does not delete unreachable globals after they are +/// inlined. +/// +void DSGraph::mergeInGlobalsGraph() { NodeMapTy GlobalNodeMap; ScalarMapTy OldValMap; ReturnNodesTy OldRetNodes; - this->cloneInto(*GlobalsGraph, OldValMap, OldRetNodes, GlobalNodeMap, - DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes | - DSGraph::DontCloneAuxCallNodes); + cloneInto(*GlobalsGraph, OldValMap, OldRetNodes, GlobalNodeMap, + DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes | + DSGraph::DontCloneAuxCallNodes); // Now merge existing global nodes in the GlobalsGraph with their copies for (ScalarMapTy::iterator I = ScalarMap.begin(), E = ScalarMap.end(); From lattner at cs.uiuc.edu Tue Aug 5 13:45:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 13:45:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200308051844.NAA30333@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.13 -> 1.14 --- Log message: Minor changes: * Expand most tabs into spaces * Move #define DEBUG_TYPE to top of file to avoid warning --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.13 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.14 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.13 Tue Aug 5 12:01:54 2003 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Tue Aug 5 13:44:12 2003 @@ -5,6 +5,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "PoolAllocation" #include "llvm/Transforms/PoolAllocate.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Analysis/DataStructure.h" @@ -19,8 +20,6 @@ #include "Support/VectorExtras.h" using namespace PA; -#define DEBUG_TYPE "PoolAllocation" - namespace { const Type *VoidPtrTy = PointerType::get(Type::SByteTy); @@ -212,7 +211,7 @@ // caller // void PoolAllocate::InlineIndirectCalls(Function &F, DSGraph &G, - hash_set &visited) { + hash_set &visited) { std::vector callSites = G.getFunctionCalls(); visited.insert(&F); @@ -220,26 +219,26 @@ // For each indirect call site in the function, inline all the potential // targets for (std::vector::iterator CSI = callSites.begin(), - CSE = callSites.end(); CSI != CSE; ++CSI) { + CSE = callSites.end(); CSI != CSE; ++CSI) { if (CSI->isIndirectCall()) { CallInst &CI = CSI->getCallInst(); std::pair::iterator, - std::multimap::iterator> Targets = - CallInstTargets.equal_range(&CI); + std::multimap::iterator> Targets = + CallInstTargets.equal_range(&CI); for (std::multimap::iterator TFI = Targets.first, - TFE = Targets.second; TFI != TFE; ++TFI) { + TFE = Targets.second; TFI != TFE; ++TFI) { DSGraph &TargetG = BU->getDSGraph(*TFI->second); - // Call the function recursively if the callee is not yet inlined - // and if it hasn't been visited in this sequence of calls - // The latter is dependent on the fact that the graphs of all functions - // in an SCC are actually the same - if (InlinedFuncs.find(TFI->second) == InlinedFuncs.end() && - visited.find(TFI->second) == visited.end()) { - InlineIndirectCalls(*TFI->second, TargetG, visited); - } - G.mergeInGraph(*CSI, *TFI->second, TargetG, DSGraph::KeepModRefBits | - DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes | - DSGraph::DontCloneAuxCallNodes); + // Call the function recursively if the callee is not yet inlined + // and if it hasn't been visited in this sequence of calls + // The latter is dependent on the fact that the graphs of all functions + // in an SCC are actually the same + if (InlinedFuncs.find(TFI->second) == InlinedFuncs.end() && + visited.find(TFI->second) == visited.end()) { + InlineIndirectCalls(*TFI->second, TargetG, visited); + } + G.mergeInGraph(*CSI, *TFI->second, TargetG, DSGraph::KeepModRefBits | + DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes | + DSGraph::DontCloneAuxCallNodes); } } } @@ -248,8 +247,6 @@ // function targets' DS Graphs. This ensures that every function is inlined // exactly once InlinedFuncs.insert(&F); - - } void PoolAllocate::FindFunctionPoolArgs(Function &F) { @@ -295,7 +292,7 @@ if (F.getName() != "main") for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { if (Nodes[i]->isGlobalNode() && !Nodes[i]->isIncomplete()) - DEBUG(std::cerr << "Global node is not Incomplete\n"); + DEBUG(std::cerr << "Global node is not Incomplete\n"); if ((Nodes[i]->isIncomplete() || Nodes[i]->isGlobalNode()) && Nodes[i]->isHeapNode()) Nodes[i]->markReachableNodes(MarkedNodes); @@ -950,58 +947,56 @@ for ( ; AI != AE; ++AI, ++OpNum) { if (!isa(CI.getOperand(OpNum))) CalcNodeMapping(getDSNodeHFor(CI.getOperand(OpNum)), - CG.getScalarMap()[AI], - NodeMapping); + CG.getScalarMap()[AI], NodeMapping); } assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!"); if (CI.getType() != Type::VoidTy) - CalcNodeMapping(getDSNodeHFor(&CI), - CG.getReturnNodeFor(*TFI->second), - NodeMapping); + CalcNodeMapping(getDSNodeHFor(&CI), + CG.getReturnNodeFor(*TFI->second), NodeMapping); // Map the nodes that are pointed to by globals. // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g) for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(), - SME = G.getScalarMap().end(); SMI != SME; ++SMI) - if (isa(SMI->first)) { - CalcNodeMapping(SMI->second, - CG.getScalarMap()[SMI->first], - NodeMapping); - } + SME = G.getScalarMap().end(); SMI != SME; ++SMI) + if (isa(SMI->first)) { + CalcNodeMapping(SMI->second, + CG.getScalarMap()[SMI->first], NodeMapping); + } unsigned idx = CFI->PoolArgFirst; // The following loop determines the pool pointers corresponding to // CFI. for (unsigned i = 0, e = CFI->ArgNodes.size(); i != e; ++i, ++idx) { - if (NodeMapping.count(CFI->ArgNodes[i])) { - assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!"); - DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second; - if (LocalNode) { - assert(FI.PoolDescriptors.count(LocalNode) && "Node not pool allocated?"); - PoolArgs[idx] = FI.PoolDescriptors.find(LocalNode)->second; - } - else - // LocalNode is null when a constant is passed in as a parameter - PoolArgs[idx] = Constant::getNullValue(PoolDescPtr); - } else { - PoolArgs[idx] = Constant::getNullValue(PoolDescPtr); - } + if (NodeMapping.count(CFI->ArgNodes[i])) { + assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!"); + DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second; + if (LocalNode) { + assert(FI.PoolDescriptors.count(LocalNode) && + "Node not pool allocated?"); + PoolArgs[idx] = FI.PoolDescriptors.find(LocalNode)->second; + } + else + // LocalNode is null when a constant is passed in as a parameter + PoolArgs[idx] = Constant::getNullValue(PoolDescPtr); + } else { + PoolArgs[idx] = Constant::getNullValue(PoolDescPtr); + } } } // Push the pool arguments into Args. if (PAInfo.EqClass2LastPoolArg.count(FuncClass)) { for (int i = 0; i <= PAInfo.EqClass2LastPoolArg[FuncClass]; ++i) { - if (PoolArgs.find(i) != PoolArgs.end()) - Args.push_back(PoolArgs[i]); - else - Args.push_back(Constant::getNullValue(PoolDescPtr)); + if (PoolArgs.find(i) != PoolArgs.end()) + Args.push_back(PoolArgs[i]); + else + Args.push_back(Constant::getNullValue(PoolDescPtr)); } - assert (Args.size()== (unsigned) PAInfo.EqClass2LastPoolArg[FuncClass] + 1 - && "Call has same number of pool args as the called function"); + assert(Args.size()== (unsigned) PAInfo.EqClass2LastPoolArg[FuncClass] + 1 + && "Call has same number of pool args as the called function"); } // Add the rest of the arguments (the original arguments of the function)... @@ -1104,7 +1099,8 @@ DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second; if (LocalNode) { - assert(FI.PoolDescriptors.count(LocalNode) && "Node not pool allocated?"); + assert(FI.PoolDescriptors.count(LocalNode) && + "Node not pool allocated?"); Args.push_back(FI.PoolDescriptors.find(LocalNode)->second); } else Args.push_back(Constant::getNullValue(PoolDescPtr)); From tbrethou at niobe.cs.uiuc.edu Tue Aug 5 13:46:01 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Tue Aug 5 13:46:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200308051845.h75Ijvd13928@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.28 -> 1.29 --- Log message: Fixed LICM bug that hoists trapping instructions that are not guaranteed to execute. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.28 llvm/lib/Transforms/Scalar/LICM.cpp:1.29 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.28 Fri Aug 1 17:15:03 2003 +++ llvm/lib/Transforms/Scalar/LICM.cpp Tue Aug 5 13:45:46 2003 @@ -67,6 +67,7 @@ BasicBlock *Preheader; // The preheader block of the current loop... Loop *CurLoop; // The current loop we are working on... AliasSetTracker *CurAST; // AliasSet information for the current loop... + DominatorTree *CurDT; // Dominator Tree for the current Loop... /// visitLoop - Hoist expressions out of the specified loop... /// @@ -96,6 +97,11 @@ /// void hoist(Instruction &I); + /// SafeToHoist - Only hoist an instruction if it is not a trapping instruction + /// or if it is a trapping instruction and is guaranteed to execute + /// + bool SafeToHoist(Instruction &I); + /// pointerInvalidatedByLoop - Return true if the body of this loop may /// store into the memory location pointed to by V. /// @@ -133,12 +139,12 @@ /// friend class InstVisitor; void visitBinaryOperator(Instruction &I) { - if (isLoopInvariant(I.getOperand(0)) && isLoopInvariant(I.getOperand(1))) + if (isLoopInvariant(I.getOperand(0)) && isLoopInvariant(I.getOperand(1)) && SafeToHoist(I)) hoist(I); } void visitCastInst(CastInst &CI) { Instruction &I = (Instruction&)CI; - if (isLoopInvariant(I.getOperand(0))) hoist(I); + if (isLoopInvariant(I.getOperand(0)) && SafeToHoist(CI)) hoist(I); } void visitShiftInst(ShiftInst &I) { visitBinaryOperator((Instruction&)I); } @@ -148,7 +154,8 @@ Instruction &I = (Instruction&)GEPI; for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) if (!isLoopInvariant(I.getOperand(i))) return; - hoist(I); + if(SafeToHoist(GEPI)) + hoist(I); } }; @@ -216,7 +223,9 @@ // that we are guaranteed to see definitions before we see uses. This allows // us to perform the LICM transformation in one pass, without iteration. // - HoistRegion(getAnalysis()[L->getHeader()]); + CurDT = &getAnalysis(); + + HoistRegion(CurDT->getNode(L->getHeader())); // Now that all loop invariants have been removed from the loop, promote any // memory references to scalars that we can... @@ -269,10 +278,55 @@ Changed = true; } +/// SafeToHoist - Only hoist an instruction if it is not a trapping instruction +/// or if it is a trapping instruction and is guaranteed to execute +/// +bool LICM::SafeToHoist(Instruction &Inst) { + + //If it is a trapping instruction, then check if its guaranteed to execute. + if(Inst.isTrapping()) { + + //Get the instruction's basic block. + BasicBlock *InstBB = Inst.getParent(); + + //Get the Dominator Tree Node for the instruction's basic block/ + DominatorTree::Node *InstDTNode = CurDT->getNode(InstBB); + + //Get the exit blocks for the current loop. + const std::vector ExitBlocks = CurLoop->getExitBlocks(); + + //For each exit block, get the DT node and walk up the DT until + //the instruction's basic block is found or we exit the loop. + for(unsigned i=0; i < ExitBlocks.size(); ++i) { + DominatorTree::Node *IDom = CurDT->getNode(ExitBlocks[i]); + + //Using boolean variable because exit nodes are not "contained" + //in the loop, so can not use that as the while test condition + //for first pass. + bool inLoop = true; + + while(inLoop) { + + //compare Instruction DT node to Current DT Node + if(IDom == InstDTNode) + return true; + + //Get next Immediate Dominator. + IDom = IDom->getIDom(); + + //See if we exited the loop. + inLoop = CurLoop->contains(IDom->getNode()); + } + return false; + } + } + return true; +} + void LICM::visitLoadInst(LoadInst &LI) { if (isLoopInvariant(LI.getOperand(0)) && - !pointerInvalidatedByLoop(LI.getOperand(0))) { + !pointerInvalidatedByLoop(LI.getOperand(0)) && SafeToHoist(LI)) { hoist(LI); ++NumHoistedLoads; } From tbrethou at niobe.cs.uiuc.edu Tue Aug 5 13:53:01 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Tue Aug 5 13:53:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll 2003-08-04-TrappingInstOkHoist.ll Message-ID: <200308051852.h75Iqqd14007@niobe.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: 2003-08-04-TrappingInstHoist.ll added (r1.1) 2003-08-04-TrappingInstOkHoist.ll added (r1.1) --- Log message: Added LICM test cases to: 1) Check that trapping instructionns that are not guaranteed to execute are not hoisted. 2) Check that trapping instructions that are guaranteed to execute are hoisted. --- Diffs of the changes: Index: llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll diff -c /dev/null llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll:1.1 *** /dev/null Tue Aug 5 13:52:52 2003 --- llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll Tue Aug 5 13:52:42 2003 *************** *** 0 **** --- 1,27 ---- + ; This testcase tests for a problem where LICM hoists + ; potentially trapping instructions when they are not guaranteed to execute. + ; + ; RUN: as < %s | opt -licm | dis | grep -C 2 "IfUnEqual" | grep div + + %X = global int 0 + declare void %foo() + + int %test(bool %c) { + %A = load int *%X + br label %Loop + Loop: + call void %foo() + br bool %c, label %LoopTail, label %IfUnEqual + + IfUnEqual: + %B1 = div int 4, %A ;; Should not hoist this div! + br label %LoopTail + + LoopTail: + %B = phi int [ 0, %Loop ], [ %B1, %IfUnEqual] + br bool %c, label %Loop, label %Out + + Out: + %C = sub int %A, %B + ret int %C + } Index: llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll diff -c /dev/null llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll:1.1 *** /dev/null Tue Aug 5 13:52:52 2003 --- llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll Tue Aug 5 13:52:42 2003 *************** *** 0 **** --- 1,20 ---- + ; This testcase tests to make sure a trapping instruction is hoisted when + ; it is guaranteed to execute. + ; + ; RUN: as < %s | opt -licm | dis | grep -C 2 "test" | grep div + + %X = global int 0 + declare void %foo() + + int %test(bool %c) { + %A = load int *%X + br label %Loop + Loop: + call void %foo() + %B = div int 4, %A ;; Should have hoisted this div! + br bool %c, label %Loop, label %Out + + Out: + %C = sub int %A, %B + ret int %C + } From gaeke at cs.uiuc.edu Tue Aug 5 14:17:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Aug 5 14:17:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h FirstTrigger.cpp Message-ID: <200308051916.OAA24497@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: RegSaveRestore.h added (r1.1) FirstTrigger.cpp updated: 1.6 -> 1.7 --- Log message: Incorporate register save/restore asms into macros in RegSaveRestore.h. Use these in FirstTrigger.cpp instead of asms. Add better comments. Fix a lot of extraneous whitespace. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h diff -c /dev/null llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h:1.1 *** /dev/null Tue Aug 5 14:16:54 2003 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h Tue Aug 5 14:16:41 2003 *************** *** 0 **** --- 1,168 ---- + #ifndef REGSAVERESTORE_H + #define REGSAVERESTORE_H + + #define SAVE_I_REGS(i_reg_save) \ + do { \ + asm volatile ("stx %%i0, %0": "=m"(i_reg_save[0])); \ + asm volatile ("stx %%i1, %0": "=m"(i_reg_save[1])); \ + asm volatile ("stx %%i2, %0": "=m"(i_reg_save[2])); \ + asm volatile ("stx %%i3, %0": "=m"(i_reg_save[3])); \ + asm volatile ("stx %%i4, %0": "=m"(i_reg_save[4])); \ + asm volatile ("stx %%i5, %0": "=m"(i_reg_save[5])); \ + } while (0) + + #define LOAD_I_REGS(i_reg_save) \ + do { \ + asm volatile ("ldx %0, %%i0":: "m"(i_reg_save[0])); \ + asm volatile ("ldx %0, %%i1":: "m"(i_reg_save[1])); \ + asm volatile ("ldx %0, %%i2":: "m"(i_reg_save[2])); \ + asm volatile ("ldx %0, %%i3":: "m"(i_reg_save[3])); \ + asm volatile ("ldx %0, %%i4":: "m"(i_reg_save[4])); \ + asm volatile ("ldx %0, %%i5":: "m"(i_reg_save[5])); \ + } while (0) + + #define SAVE_G1_REG(g1_reg) \ + asm volatile ("stx %%g1, %0": "=m"(g1_reg)) + + #define LOAD_G1_REG(g1_reg) \ + asm volatile ("ldx %0, %%g1":: "m"(g1_reg)) + + #define SAVE_F_REGS_1(f_reg_save) \ + do { \ + asm volatile ("st %%f0, %0": "=m"(f_reg_save[0])); \ + asm volatile ("st %%f1, %0": "=m"(f_reg_save[1])); \ + asm volatile ("st %%f2, %0": "=m"(f_reg_save[2])); \ + asm volatile ("st %%f3, %0": "=m"(f_reg_save[3])); \ + asm volatile ("st %%f4, %0": "=m"(f_reg_save[4])); \ + asm volatile ("st %%f5, %0": "=m"(f_reg_save[5])); \ + asm volatile ("st %%f6, %0": "=m"(f_reg_save[6])); \ + asm volatile ("st %%f7, %0": "=m"(f_reg_save[7])); \ + asm volatile ("st %%f8, %0": "=m"(f_reg_save[8])); \ + asm volatile ("st %%f9, %0": "=m"(f_reg_save[9])); \ + asm volatile ("st %%f10, %0": "=m"(f_reg_save[10])); \ + asm volatile ("st %%f11, %0": "=m"(f_reg_save[11])); \ + asm volatile ("st %%f12, %0": "=m"(f_reg_save[12])); \ + asm volatile ("st %%f13, %0": "=m"(f_reg_save[13])); \ + asm volatile ("st %%f14, %0": "=m"(f_reg_save[14])); \ + asm volatile ("st %%f15, %0": "=m"(f_reg_save[15])); \ + } while (0) + + #define LOAD_F_REGS_1(f_reg_save) \ + do { \ + asm volatile ("ld %0, %%f0":: "m"(f_reg_save[0])); \ + asm volatile ("ld %0, %%f1":: "m"(f_reg_save[1])); \ + asm volatile ("ld %0, %%f2":: "m"(f_reg_save[2])); \ + asm volatile ("ld %0, %%f3":: "m"(f_reg_save[3])); \ + asm volatile ("ld %0, %%f4":: "m"(f_reg_save[4])); \ + asm volatile ("ld %0, %%f5":: "m"(f_reg_save[5])); \ + asm volatile ("ld %0, %%f6":: "m"(f_reg_save[6])); \ + asm volatile ("ld %0, %%f7":: "m"(f_reg_save[7])); \ + asm volatile ("ld %0, %%f8":: "m"(f_reg_save[8])); \ + asm volatile ("ld %0, %%f9":: "m"(f_reg_save[9])); \ + asm volatile ("ld %0, %%f10":: "m"(f_reg_save[10])); \ + asm volatile ("ld %0, %%f11":: "m"(f_reg_save[11])); \ + asm volatile ("ld %0, %%f12":: "m"(f_reg_save[12])); \ + asm volatile ("ld %0, %%f13":: "m"(f_reg_save[13])); \ + asm volatile ("ld %0, %%f14":: "m"(f_reg_save[14])); \ + asm volatile ("ld %0, %%f15":: "m"(f_reg_save[15])); \ + } while (0) + + #define SAVE_F_REGS_2(f_reg_save) \ + do { \ + asm volatile ("st %%f16, %0": "=m"(f_reg_save[16])); \ + asm volatile ("st %%f17, %0": "=m"(f_reg_save[17])); \ + asm volatile ("st %%f18, %0": "=m"(f_reg_save[18])); \ + asm volatile ("st %%f19, %0": "=m"(f_reg_save[19])); \ + asm volatile ("st %%f20, %0": "=m"(f_reg_save[20])); \ + asm volatile ("st %%f21, %0": "=m"(f_reg_save[21])); \ + asm volatile ("st %%f22, %0": "=m"(f_reg_save[22])); \ + asm volatile ("st %%f23, %0": "=m"(f_reg_save[23])); \ + asm volatile ("st %%f24, %0": "=m"(f_reg_save[24])); \ + asm volatile ("st %%f25, %0": "=m"(f_reg_save[25])); \ + asm volatile ("st %%f26, %0": "=m"(f_reg_save[26])); \ + asm volatile ("st %%f27, %0": "=m"(f_reg_save[27])); \ + asm volatile ("st %%f28, %0": "=m"(f_reg_save[28])); \ + asm volatile ("st %%f29, %0": "=m"(f_reg_save[29])); \ + asm volatile ("st %%f30, %0": "=m"(f_reg_save[30])); \ + asm volatile ("st %%f31, %0": "=m"(f_reg_save[31])); \ + } while (0) + + #define LOAD_F_REGS_2(f_reg_save) \ + do { \ + asm volatile ("ld %0, %%f16":: "m"(f_reg_save[16])); \ + asm volatile ("ld %0, %%f17":: "m"(f_reg_save[17])); \ + asm volatile ("ld %0, %%f18":: "m"(f_reg_save[18])); \ + asm volatile ("ld %0, %%f19":: "m"(f_reg_save[19])); \ + asm volatile ("ld %0, %%f20":: "m"(f_reg_save[20])); \ + asm volatile ("ld %0, %%f21":: "m"(f_reg_save[21])); \ + asm volatile ("ld %0, %%f22":: "m"(f_reg_save[22])); \ + asm volatile ("ld %0, %%f23":: "m"(f_reg_save[23])); \ + asm volatile ("ld %0, %%f24":: "m"(f_reg_save[24])); \ + asm volatile ("ld %0, %%f25":: "m"(f_reg_save[25])); \ + asm volatile ("ld %0, %%f26":: "m"(f_reg_save[26])); \ + asm volatile ("ld %0, %%f27":: "m"(f_reg_save[27])); \ + asm volatile ("ld %0, %%f28":: "m"(f_reg_save[28])); \ + asm volatile ("ld %0, %%f29":: "m"(f_reg_save[29])); \ + asm volatile ("ld %0, %%f30":: "m"(f_reg_save[30])); \ + asm volatile ("ld %0, %%f31":: "m"(f_reg_save[31])); \ + } while (0) + + #define SAVE_FD_REGS(fd_reg_save) \ + do { \ + asm volatile ("std %%f32, %0": "=m"(fd_reg_save[32/2-16])); \ + asm volatile ("std %%f34, %0": "=m"(fd_reg_save[34/2-16])); \ + asm volatile ("std %%f36, %0": "=m"(fd_reg_save[36/2-16])); \ + asm volatile ("std %%f38, %0": "=m"(fd_reg_save[38/2-16])); \ + asm volatile ("std %%f40, %0": "=m"(fd_reg_save[40/2-16])); \ + asm volatile ("std %%f42, %0": "=m"(fd_reg_save[42/2-16])); \ + asm volatile ("std %%f44, %0": "=m"(fd_reg_save[44/2-16])); \ + asm volatile ("std %%f46, %0": "=m"(fd_reg_save[46/2-16])); \ + asm volatile ("std %%f48, %0": "=m"(fd_reg_save[48/2-16])); \ + asm volatile ("std %%f50, %0": "=m"(fd_reg_save[50/2-16])); \ + asm volatile ("std %%f52, %0": "=m"(fd_reg_save[52/2-16])); \ + asm volatile ("std %%f54, %0": "=m"(fd_reg_save[54/2-16])); \ + asm volatile ("std %%f56, %0": "=m"(fd_reg_save[56/2-16])); \ + asm volatile ("std %%f58, %0": "=m"(fd_reg_save[58/2-16])); \ + asm volatile ("std %%f60, %0": "=m"(fd_reg_save[60/2-16])); \ + asm volatile ("std %%f62, %0": "=m"(fd_reg_save[62/2-16])); \ + } while (0) + + #define LOAD_FD_REGS(fd_reg_save) \ + do { \ + asm volatile ("ldd %0, %%f32":: "m"(fd_reg_save[32/2-16])); \ + asm volatile ("ldd %0, %%f34":: "m"(fd_reg_save[34/2-16])); \ + asm volatile ("ldd %0, %%f36":: "m"(fd_reg_save[36/2-16])); \ + asm volatile ("ldd %0, %%f38":: "m"(fd_reg_save[38/2-16])); \ + asm volatile ("ldd %0, %%f40":: "m"(fd_reg_save[40/2-16])); \ + asm volatile ("ldd %0, %%f42":: "m"(fd_reg_save[42/2-16])); \ + asm volatile ("ldd %0, %%f44":: "m"(fd_reg_save[44/2-16])); \ + asm volatile ("ldd %0, %%f46":: "m"(fd_reg_save[46/2-16])); \ + asm volatile ("ldd %0, %%f48":: "m"(fd_reg_save[48/2-16])); \ + asm volatile ("ldd %0, %%f50":: "m"(fd_reg_save[50/2-16])); \ + asm volatile ("ldd %0, %%f52":: "m"(fd_reg_save[52/2-16])); \ + asm volatile ("ldd %0, %%f54":: "m"(fd_reg_save[54/2-16])); \ + asm volatile ("ldd %0, %%f56":: "m"(fd_reg_save[56/2-16])); \ + asm volatile ("ldd %0, %%f58":: "m"(fd_reg_save[58/2-16])); \ + asm volatile ("ldd %0, %%f60":: "m"(fd_reg_save[60/2-16])); \ + asm volatile ("ldd %0, %%f62":: "m"(fd_reg_save[62/2-16])); \ + } while (0) + + #define SAVE_FSR_REG(fsr_reg) \ + asm volatile ("stx %%fsr, %0": "=m" (fsr_reg)) + + #define LOAD_FSR_REG(fsr_reg) \ + asm volatile ("ldx %0, %%fsr":: "m"(fsr_reg)) + + #define SAVE_FPRS_REG(fprs_reg) \ + asm volatile ("rd %%fprs, %0": "=r"(fprs_reg)) + + #define LOAD_FPRS_REG(fprs_reg) \ + asm volatile ("wr %0, 0, %%fprs":: "r"(fprs_reg)) + + #define SAVE_CCR_REG(ccr_reg) \ + asm volatile ("rd %%ccr, %0": "=r"(ccr_reg)) + + #define LOAD_CCR_REG(ccr_reg) \ + asm volatile ("wr %0, 0, %%ccr":: "r"(ccr_reg)) + + #endif // REGSAVERESTORE_H Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.6 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.7 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.6 Tue Aug 5 13:21:26 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp Tue Aug 5 14:16:41 2003 @@ -20,6 +20,7 @@ #ifdef __sparc #include #endif +#include "RegSaveRestore.h" using namespace std; @@ -80,8 +81,6 @@ } extern "C" void llvm_first_trigger(){ - - //save regs uint64_t i_reg_save[6]; uint32_t f_reg_save[32]; uint64_t fd_reg_save[16]; @@ -90,119 +89,58 @@ uint64_t fsr_reg; uint64_t g1_reg; - //#ifdef __sparc - asm volatile ("stx %%i0, %0": "=m"(i_reg_save[0])); - asm volatile ("stx %%i1, %0": "=m"(i_reg_save[1])); - asm volatile ("stx %%i2, %0": "=m"(i_reg_save[2])); - asm volatile ("stx %%i3, %0": "=m"(i_reg_save[3])); - asm volatile ("stx %%i4, %0": "=m"(i_reg_save[4])); - asm volatile ("stx %%i5, %0": "=m"(i_reg_save[5])); - - asm volatile ("stx %%g1, %0": "=m"(g1_reg)); - asm volatile ("st %%f0, %0": "=m"(f_reg_save[0])); - asm volatile ("st %%f1, %0": "=m"(f_reg_save[1])); - asm volatile ("st %%f2, %0": "=m"(f_reg_save[2])); - asm volatile ("st %%f3, %0": "=m"(f_reg_save[3])); - asm volatile ("st %%f4, %0": "=m"(f_reg_save[4])); - asm volatile ("st %%f5, %0": "=m"(f_reg_save[5])); - asm volatile ("st %%f6, %0": "=m"(f_reg_save[6])); - asm volatile ("st %%f7, %0": "=m"(f_reg_save[7])); - asm volatile ("st %%f8, %0": "=m"(f_reg_save[8])); - asm volatile ("st %%f9, %0": "=m"(f_reg_save[9])); - asm volatile ("st %%f10, %0": "=m"(f_reg_save[10])); - asm volatile ("st %%f11, %0": "=m"(f_reg_save[11])); - asm volatile ("st %%f12, %0": "=m"(f_reg_save[12])); - asm volatile ("st %%f13, %0": "=m"(f_reg_save[13])); - asm volatile ("st %%f14, %0": "=m"(f_reg_save[14])); - asm volatile ("st %%f15, %0": "=m"(f_reg_save[15])); - - /* - asm volatile ("st %%f16, %0": "=m"(f_reg_save[16])); - asm volatile ("st %%f17, %0": "=m"(f_reg_save[17])); - asm volatile ("st %%f18, %0": "=m"(f_reg_save[18])); - asm volatile ("st %%f19, %0": "=m"(f_reg_save[19])); - asm volatile ("st %%f20, %0": "=m"(f_reg_save[20])); - asm volatile ("st %%f21, %0": "=m"(f_reg_save[21])); - asm volatile ("st %%f22, %0": "=m"(f_reg_save[22])); - asm volatile ("st %%f23, %0": "=m"(f_reg_save[23])); - asm volatile ("st %%f24, %0": "=m"(f_reg_save[24])); - asm volatile ("st %%f25, %0": "=m"(f_reg_save[25])); - asm volatile ("st %%f26, %0": "=m"(f_reg_save[26])); - asm volatile ("st %%f27, %0": "=m"(f_reg_save[27])); - asm volatile ("st %%f28, %0": "=m"(f_reg_save[28])); - asm volatile ("st %%f29, %0": "=m"(f_reg_save[29])); - asm volatile ("st %%f30, %0": "=m"(f_reg_save[30])); - asm volatile ("st %%f31, %0": "=m"(f_reg_save[31]));*/ - - asm volatile ("std %%f32, %0": "=m"(fd_reg_save[32/2-16])); - asm volatile ("std %%f34, %0": "=m"(fd_reg_save[34/2-16])); - asm volatile ("std %%f36, %0": "=m"(fd_reg_save[36/2-16])); - asm volatile ("std %%f38, %0": "=m"(fd_reg_save[38/2-16])); - asm volatile ("std %%f40, %0": "=m"(fd_reg_save[40/2-16])); - asm volatile ("std %%f42, %0": "=m"(fd_reg_save[42/2-16])); - asm volatile ("std %%f44, %0": "=m"(fd_reg_save[44/2-16])); - asm volatile ("std %%f46, %0": "=m"(fd_reg_save[46/2-16])); - //*/ - asm volatile ("std %%f48, %0": "=m"(fd_reg_save[48/2-16])); - asm volatile ("std %%f50, %0": "=m"(fd_reg_save[50/2-16])); - asm volatile ("std %%f52, %0": "=m"(fd_reg_save[52/2-16])); - asm volatile ("std %%f54, %0": "=m"(fd_reg_save[54/2-16])); - asm volatile ("std %%f56, %0": "=m"(fd_reg_save[56/2-16])); - asm volatile ("std %%f58, %0": "=m"(fd_reg_save[58/2-16])); - asm volatile ("std %%f60, %0": "=m"(fd_reg_save[60/2-16])); - asm volatile ("std %%f62, %0": "=m"(fd_reg_save[62/2-16])); - - asm volatile ("stx %%fsr, %0": "=m" (fsr_reg)); - asm volatile ("rd %%fprs, %0": "=r"(fprs_reg)); - - asm volatile ("rd %%ccr, %0": "=r"(ccr_reg)); - - //#endif - //a map of counters + // Save registers on the stack, in the local variables declared above. + // FIXME: Why don't we save the upper f registers? + SAVE_I_REGS(i_reg_save); + SAVE_G1_REG(g1_reg); + SAVE_F_REGS_1(f_reg_save); + // SAVE_F_REGS_2(f_reg_save); + SAVE_FD_REGS(fd_reg_save); + SAVE_FSR_REG(fsr_reg); + SAVE_FPRS_REG(fprs_reg); + SAVE_CCR_REG(ccr_reg); + // Maps of counters we use: static map counterMap; static map seenOccur; + // FIXME: What is brAddr? uint64_t brAddr; - #ifdef __sparc asm("add %%i7, %1, %0":"=r"(brAddr):"i" (0)); #else assert(false && "Case not handled for this processor architecture!"); #endif - //if(counterMap[brAddr] > 200) - //return; + // Increment the counter for this branch, and check it against + // THRESHOLD_LEVEL_1. If it exceeds the threshold, we may have to + // generate second-level instrumentation (SLI). if(++counterMap[brAddr] > reopt_threshold){ - counterMap.erase(brAddr); - //std::cerr<<"Originally Removed from addr: "<<(void *)brAddr<<"\n"; + // Scan forward through memory starting from brAddr, looking for a branch + // instruction. char offst = 8; unsigned int brInst = vm->readInstrFrmVm(brAddr + offst, tr, tr2); - while(!isBranchInstr(brInst)){ offst += 4; brInst = vm->readInstrFrmVm(brAddr + offst, tr, tr2); } - assert(isBranchInstr(brInst) && "Not a branch!"); - uint64_t brTarget = getBranchTarget(brInst, brAddr+offst); - firstTriggerAddr[brTarget] = brAddr; - //check if tracecache already has optimized code. If yes, - //do not generate SLI - if(!tr->hasTraceAddr(brTarget, brAddr+offst)){ + // Check if trace cache already has optimized code. If it does, + // we do not generate SLI. + if(!tr->hasTraceAddr(brTarget, brAddr+offst)) { + // No optimized code in trace cache; generate SLI now. getFirstTrace(brTarget, brAddr+offst, 100, vm, tr); - } - else{ + } else { #ifdef GET_ALL_INFO std::cerr<<"SLI-exists\t"<<(void *)brTarget<<"\t"<<(void *)(brTarget+offst)<<"\n"; #endif - //write a branch going to top of trace in tr + // Write a branch going to the top of the trace in tr. uint64_t traceAddrInTC = tr->getStartAddr(brTarget); vm->writeInstToVM(traceAddrInTC, tr->getAddr(brTarget)); @@ -216,70 +154,16 @@ doFlush(brAddr-8, brAddr+16); } - //#ifdef __sparc fprs_reg ^= 0; ccr_reg ^= 0; - asm volatile ("wr %0, 0, %%ccr":: "r"(ccr_reg)); - asm volatile ("ldx %0, %%i0":: "m"(i_reg_save[0])); - asm volatile ("ldx %0, %%i1":: "m"(i_reg_save[1])); - asm volatile ("ldx %0, %%i2":: "m"(i_reg_save[2])); - asm volatile ("ldx %0, %%i3":: "m"(i_reg_save[3])); - asm volatile ("ldx %0, %%i4":: "m"(i_reg_save[4])); - asm volatile ("ldx %0, %%i5":: "m"(i_reg_save[5])); - - asm volatile ("wr %0, 0, %%fprs":: "r"(fprs_reg)); - asm volatile ("ldx %0, %%g1":: "m"(g1_reg)); - asm volatile ("ld %0, %%f0":: "m"(f_reg_save[0])); - asm volatile ("ld %0, %%f1":: "m"(f_reg_save[1])); - asm volatile ("ld %0, %%f2":: "m"(f_reg_save[2])); - asm volatile ("ld %0, %%f3":: "m"(f_reg_save[3])); - asm volatile ("ld %0, %%f4":: "m"(f_reg_save[4])); - asm volatile ("ld %0, %%f5":: "m"(f_reg_save[5])); - asm volatile ("ld %0, %%f6":: "m"(f_reg_save[6])); - asm volatile ("ld %0, %%f7":: "m"(f_reg_save[7])); - asm volatile ("ld %0, %%f8":: "m"(f_reg_save[8])); - asm volatile ("ld %0, %%f9":: "m"(f_reg_save[9])); - asm volatile ("ld %0, %%f10":: "m"(f_reg_save[10])); - asm volatile ("ld %0, %%f11":: "m"(f_reg_save[11])); - asm volatile ("ld %0, %%f12":: "m"(f_reg_save[12])); - asm volatile ("ld %0, %%f13":: "m"(f_reg_save[13])); - asm volatile ("ld %0, %%f14":: "m"(f_reg_save[14])); - asm volatile ("ld %0, %%f15":: "m"(f_reg_save[15])); - /* - asm volatile ("ld %0, %%f16":: "m"(f_reg_save[16])); - asm volatile ("ld %0, %%f17":: "m"(f_reg_save[17])); - asm volatile ("ld %0, %%f18":: "m"(f_reg_save[18])); - asm volatile ("ld %0, %%f19":: "m"(f_reg_save[19])); - asm volatile ("ld %0, %%f20":: "m"(f_reg_save[20])); - asm volatile ("ld %0, %%f21":: "m"(f_reg_save[21])); - asm volatile ("ld %0, %%f22":: "m"(f_reg_save[22])); - asm volatile ("ld %0, %%f23":: "m"(f_reg_save[23])); - asm volatile ("ld %0, %%f24":: "m"(f_reg_save[24])); - asm volatile ("ld %0, %%f25":: "m"(f_reg_save[25])); - asm volatile ("ld %0, %%f26":: "m"(f_reg_save[26])); - asm volatile ("ld %0, %%f27":: "m"(f_reg_save[27])); - asm volatile ("ld %0, %%f28":: "m"(f_reg_save[28])); - asm volatile ("ld %0, %%f29":: "m"(f_reg_save[29])); - asm volatile ("ld %0, %%f30":: "m"(f_reg_save[30])); - asm volatile ("ld %0, %%f31":: "m"(f_reg_save[31]));*/ - asm volatile ("ldd %0, %%f32":: "m"(fd_reg_save[32/2-16])); - asm volatile ("ldd %0, %%f34":: "m"(fd_reg_save[34/2-16])); - asm volatile ("ldd %0, %%f36":: "m"(fd_reg_save[36/2-16])); - asm volatile ("ldd %0, %%f38":: "m"(fd_reg_save[38/2-16])); - asm volatile ("ldd %0, %%f40":: "m"(fd_reg_save[40/2-16])); - asm volatile ("ldd %0, %%f42":: "m"(fd_reg_save[42/2-16])); - asm volatile ("ldd %0, %%f44":: "m"(fd_reg_save[44/2-16])); - asm volatile ("ldd %0, %%f46":: "m"(fd_reg_save[46/2-16])); - //*/ - asm volatile ("ldd %0, %%f48":: "m"(fd_reg_save[48/2-16])); - asm volatile ("ldd %0, %%f50":: "m"(fd_reg_save[50/2-16])); - asm volatile ("ldd %0, %%f52":: "m"(fd_reg_save[52/2-16])); - asm volatile ("ldd %0, %%f54":: "m"(fd_reg_save[54/2-16])); - asm volatile ("ldd %0, %%f56":: "m"(fd_reg_save[56/2-16])); - asm volatile ("ldd %0, %%f58":: "m"(fd_reg_save[58/2-16])); - asm volatile ("ldd %0, %%f60":: "m"(fd_reg_save[60/2-16])); - asm volatile ("ldd %0, %%f62":: "m"(fd_reg_save[62/2-16])); - asm volatile ("ldx %0, %%fsr":: "m"(fsr_reg)); - //#endif + // Restore registers from local variables, and return to executing code. + LOAD_CCR_REG(ccr_reg); + LOAD_I_REGS(i_reg_save); + LOAD_FPRS_REG(fprs_reg); + LOAD_G1_REG(g1_reg); + LOAD_F_REGS_1(f_reg_save); + // LOAD_F_REGS_2(f_reg_save); + LOAD_FD_REGS(fd_reg_save); + LOAD_FSR_REG(fsr_reg); } From gaeke at cs.uiuc.edu Tue Aug 5 14:35:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Aug 5 14:35:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp RegSaveRestore.h SecondTrigger.cpp Message-ID: <200308051934.OAA24546@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: FirstTrigger.cpp updated: 1.7 -> 1.8 RegSaveRestore.h updated: 1.1 -> 1.2 SecondTrigger.cpp updated: 1.3 -> 1.4 --- Log message: FirstTrigger.cpp: Add FIXME comment. RegSaveRestore.h: Add SAVE_G5_REG and LOAD_G5_REG. SecondTrigger.cpp: Remove excess whitespace. Use SAVE/LOAD macros from RegSaveRestore.h. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.7 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.8 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.7 Tue Aug 5 14:16:41 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp Tue Aug 5 14:34:19 2003 @@ -91,6 +91,8 @@ // Save registers on the stack, in the local variables declared above. // FIXME: Why don't we save the upper f registers? + // FIXME: Using this code to save registers is not guaranteed to work + // because the compiler could move instructions across the `asm's. SAVE_I_REGS(i_reg_save); SAVE_G1_REG(g1_reg); SAVE_F_REGS_1(f_reg_save); Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h:1.1 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h:1.2 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h:1.1 Tue Aug 5 14:16:41 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/RegSaveRestore.h Tue Aug 5 14:34:19 2003 @@ -27,6 +27,12 @@ #define LOAD_G1_REG(g1_reg) \ asm volatile ("ldx %0, %%g1":: "m"(g1_reg)) +#define SAVE_G5_REG(g1_reg) \ + asm volatile ("stx %%g5, %0": "=m"(g5_reg)) + +#define LOAD_G5_REG(g1_reg) \ + asm volatile ("ldx %0, %%g5":: "m"(g5_reg)) + #define SAVE_F_REGS_1(f_reg_save) \ do { \ asm volatile ("st %%f0, %0": "=m"(f_reg_save[0])); \ Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.3 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.4 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.3 Tue Aug 5 13:21:27 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Tue Aug 5 14:34:20 2003 @@ -34,7 +34,6 @@ #define CALL 0x40000000 - long THRESHOLD_LEVEL_2; long LEVEL_TWO_EXITS; @@ -43,7 +42,6 @@ extern VirtualMem *vm; extern Module *M; - static std::map *> pathCounter; static std::map totalCount; @@ -57,7 +55,6 @@ void getReturnCode(vector &traces, int &index, uint64_t ret); - extern uint64_t llvm_interval_counter; std::map exitCounter; //std::map iterationCounter; @@ -67,7 +64,6 @@ void triggerBB(vector &vBB, VirtualMem *vm, TraceCache *tr, TraceCache *tr2, uint64_t a); - extern "C" void llvm_time_start(){ #ifdef __sparc cpc_count_usr_events(1); @@ -82,7 +78,6 @@ extern "C" void llvm_time_end(){ uint64_t i_reg_save[6]; - uint32_t f_reg_save[32]; uint64_t fd_reg_save[16]; uint64_t ccr_reg; @@ -91,73 +86,19 @@ uint64_t g1_reg; uint64_t g5_reg; - asm volatile ("stx %%i0, %0": "=m"(i_reg_save[0])); - asm volatile ("stx %%i1, %0": "=m"(i_reg_save[1])); - asm volatile ("stx %%i2, %0": "=m"(i_reg_save[2])); - asm volatile ("stx %%i3, %0": "=m"(i_reg_save[3])); - asm volatile ("stx %%i4, %0": "=m"(i_reg_save[4])); - asm volatile ("stx %%i5, %0": "=m"(i_reg_save[5])); - - asm volatile ("stx %%g1, %0": "=m"(g1_reg)); - asm volatile ("stx %%g5, %0": "=m"(g5_reg)); - - asm volatile ("st %%f0, %0": "=m"(f_reg_save[0])); - asm volatile ("st %%f1, %0": "=m"(f_reg_save[1])); - asm volatile ("st %%f2, %0": "=m"(f_reg_save[2])); - asm volatile ("st %%f3, %0": "=m"(f_reg_save[3])); - asm volatile ("st %%f4, %0": "=m"(f_reg_save[4])); - asm volatile ("st %%f5, %0": "=m"(f_reg_save[5])); - asm volatile ("st %%f6, %0": "=m"(f_reg_save[6])); - asm volatile ("st %%f7, %0": "=m"(f_reg_save[7])); - asm volatile ("st %%f8, %0": "=m"(f_reg_save[8])); - asm volatile ("st %%f9, %0": "=m"(f_reg_save[9])); - asm volatile ("st %%f10, %0": "=m"(f_reg_save[10])); - asm volatile ("st %%f11, %0": "=m"(f_reg_save[11])); - asm volatile ("st %%f12, %0": "=m"(f_reg_save[12])); - asm volatile ("st %%f13, %0": "=m"(f_reg_save[13])); - asm volatile ("st %%f14, %0": "=m"(f_reg_save[14])); - asm volatile ("st %%f15, %0": "=m"(f_reg_save[15])); - /* - asm volatile ("st %%f16, %0": "=m"(f_reg_save[16])); - asm volatile ("st %%f17, %0": "=m"(f_reg_save[17])); - asm volatile ("st %%f18, %0": "=m"(f_reg_save[18])); - asm volatile ("st %%f19, %0": "=m"(f_reg_save[19])); - asm volatile ("st %%f20, %0": "=m"(f_reg_save[20])); - asm volatile ("st %%f21, %0": "=m"(f_reg_save[21])); - asm volatile ("st %%f22, %0": "=m"(f_reg_save[22])); - asm volatile ("st %%f23, %0": "=m"(f_reg_save[23])); - asm volatile ("st %%f24, %0": "=m"(f_reg_save[24])); - asm volatile ("st %%f25, %0": "=m"(f_reg_save[25])); - asm volatile ("st %%f26, %0": "=m"(f_reg_save[26])); - asm volatile ("st %%f27, %0": "=m"(f_reg_save[27])); - asm volatile ("st %%f28, %0": "=m"(f_reg_save[28])); - asm volatile ("st %%f29, %0": "=m"(f_reg_save[29])); - asm volatile ("st %%f30, %0": "=m"(f_reg_save[30])); - asm volatile ("st %%f31, %0": "=m"(f_reg_save[31])); - */ - asm volatile ("std %%f32, %0": "=m"(fd_reg_save[32/2-16])); - asm volatile ("std %%f34, %0": "=m"(fd_reg_save[34/2-16])); - asm volatile ("std %%f36, %0": "=m"(fd_reg_save[36/2-16])); - asm volatile ("std %%f38, %0": "=m"(fd_reg_save[38/2-16])); - asm volatile ("std %%f40, %0": "=m"(fd_reg_save[40/2-16])); - asm volatile ("std %%f42, %0": "=m"(fd_reg_save[42/2-16])); - asm volatile ("std %%f44, %0": "=m"(fd_reg_save[44/2-16])); - asm volatile ("std %%f46, %0": "=m"(fd_reg_save[46/2-16])); - - asm volatile ("std %%f48, %0": "=m"(fd_reg_save[48/2-16])); - asm volatile ("std %%f50, %0": "=m"(fd_reg_save[50/2-16])); - asm volatile ("std %%f52, %0": "=m"(fd_reg_save[52/2-16])); - asm volatile ("std %%f54, %0": "=m"(fd_reg_save[54/2-16])); - asm volatile ("std %%f56, %0": "=m"(fd_reg_save[56/2-16])); - asm volatile ("std %%f58, %0": "=m"(fd_reg_save[58/2-16])); - asm volatile ("std %%f60, %0": "=m"(fd_reg_save[60/2-16])); - asm volatile ("std %%f62, %0": "=m"(fd_reg_save[62/2-16])); - - asm volatile ("stx %%fsr, %0": "=m" (fsr_reg)); - asm volatile ("rd %%fprs, %0": "=r"(fprs_reg)); - - asm volatile ("rd %%ccr, %0": "=r"(ccr_reg)); - + // Save registers on the stack, in the local variables declared above. + // FIXME: Why don't we save the upper f registers? + // FIXME: Using this code to save registers is not guaranteed to work + // because the compiler could move instructions across the `asm's. + SAVE_I_REGS(i_reg_save); + SAVE_G1_REG(g1_reg); + SAVE_G5_REG(g1_reg); + SAVE_F_REGS_1(f_reg_save); + // SAVE_F_REGS_2(f_reg_save); + SAVE_FD_REGS(fd_reg_save); + SAVE_FSR_REG(fsr_reg); + SAVE_FPRS_REG(fprs_reg); + SAVE_CCR_REG(ccr_reg); uint64_t brAddr; #ifdef __sparc @@ -192,74 +133,20 @@ backOffCounters[reverseAddr].second, firstTriggerAddr[reverseAddr]); } - fprs_reg ^= 0; ccr_reg ^= 0; - asm volatile ("wr %0, 0, %%ccr":: "r"(ccr_reg)); - asm volatile ("ldx %0, %%i0":: "m"(i_reg_save[0])); - asm volatile ("ldx %0, %%i1":: "m"(i_reg_save[1])); - asm volatile ("ldx %0, %%i2":: "m"(i_reg_save[2])); - asm volatile ("ldx %0, %%i3":: "m"(i_reg_save[3])); - asm volatile ("ldx %0, %%i4":: "m"(i_reg_save[4])); - asm volatile ("ldx %0, %%i5":: "m"(i_reg_save[5])); - asm volatile ("ldx %0, %%g1":: "m"(g1_reg)); - asm volatile ("ldx %0, %%g5":: "m"(g5_reg)); - - asm volatile ("wr %0, 0, %%fprs":: "r"(fprs_reg)); - asm volatile ("ld %0, %%f0":: "m"(f_reg_save[0])); - asm volatile ("ld %0, %%f1":: "m"(f_reg_save[1])); - asm volatile ("ld %0, %%f2":: "m"(f_reg_save[2])); - asm volatile ("ld %0, %%f3":: "m"(f_reg_save[3])); - asm volatile ("ld %0, %%f4":: "m"(f_reg_save[4])); - asm volatile ("ld %0, %%f5":: "m"(f_reg_save[5])); - asm volatile ("ld %0, %%f6":: "m"(f_reg_save[6])); - asm volatile ("ld %0, %%f7":: "m"(f_reg_save[7])); - asm volatile ("ld %0, %%f8":: "m"(f_reg_save[8])); - asm volatile ("ld %0, %%f9":: "m"(f_reg_save[9])); - asm volatile ("ld %0, %%f10":: "m"(f_reg_save[10])); - asm volatile ("ld %0, %%f11":: "m"(f_reg_save[11])); - asm volatile ("ld %0, %%f12":: "m"(f_reg_save[12])); - asm volatile ("ld %0, %%f13":: "m"(f_reg_save[13])); - asm volatile ("ld %0, %%f14":: "m"(f_reg_save[14])); - asm volatile ("ld %0, %%f15":: "m"(f_reg_save[15])); - /* - asm volatile ("ld %0, %%f16":: "m"(f_reg_save[16])); - asm volatile ("ld %0, %%f17":: "m"(f_reg_save[17])); - asm volatile ("ld %0, %%f18":: "m"(f_reg_save[18])); - asm volatile ("ld %0, %%f19":: "m"(f_reg_save[19])); - asm volatile ("ld %0, %%f20":: "m"(f_reg_save[20])); - asm volatile ("ld %0, %%f21":: "m"(f_reg_save[21])); - asm volatile ("ld %0, %%f22":: "m"(f_reg_save[22])); - asm volatile ("ld %0, %%f23":: "m"(f_reg_save[23])); - asm volatile ("ld %0, %%f24":: "m"(f_reg_save[24])); - asm volatile ("ld %0, %%f25":: "m"(f_reg_save[25])); - asm volatile ("ld %0, %%f26":: "m"(f_reg_save[26])); - asm volatile ("ld %0, %%f27":: "m"(f_reg_save[27])); - asm volatile ("ld %0, %%f28":: "m"(f_reg_save[28])); - asm volatile ("ld %0, %%f29":: "m"(f_reg_save[29])); - asm volatile ("ld %0, %%f30":: "m"(f_reg_save[30])); - asm volatile ("ld %0, %%f31":: "m"(f_reg_save[31])); - */ - asm volatile ("ldd %0, %%f32":: "m"(fd_reg_save[32/2-16])); - asm volatile ("ldd %0, %%f34":: "m"(fd_reg_save[34/2-16])); - asm volatile ("ldd %0, %%f36":: "m"(fd_reg_save[36/2-16])); - asm volatile ("ldd %0, %%f38":: "m"(fd_reg_save[38/2-16])); - asm volatile ("ldd %0, %%f40":: "m"(fd_reg_save[40/2-16])); - asm volatile ("ldd %0, %%f42":: "m"(fd_reg_save[42/2-16])); - asm volatile ("ldd %0, %%f44":: "m"(fd_reg_save[44/2-16])); - asm volatile ("ldd %0, %%f46":: "m"(fd_reg_save[46/2-16])); - - asm volatile ("ldd %0, %%f48":: "m"(fd_reg_save[48/2-16])); - asm volatile ("ldd %0, %%f50":: "m"(fd_reg_save[50/2-16])); - asm volatile ("ldd %0, %%f52":: "m"(fd_reg_save[52/2-16])); - asm volatile ("ldd %0, %%f54":: "m"(fd_reg_save[54/2-16])); - asm volatile ("ldd %0, %%f56":: "m"(fd_reg_save[56/2-16])); - asm volatile ("ldd %0, %%f58":: "m"(fd_reg_save[58/2-16])); - asm volatile ("ldd %0, %%f60":: "m"(fd_reg_save[60/2-16])); - asm volatile ("ldd %0, %%f62":: "m"(fd_reg_save[62/2-16])); - asm volatile ("ldx %0, %%fsr":: "m"(fsr_reg)); + // Restore registers from local variables. + LOAD_CCR_REG(ccr_reg); + LOAD_I_REGS(i_reg_save); + LOAD_G1_REG(g1_reg); + LOAD_G5_REG(g5_reg); + LOAD_FPRS_REG(fprs_reg); + LOAD_F_REGS_1(f_reg_save); + // LOAD_F_REGS_2(f_reg_save); + LOAD_FD_REGS(fd_reg_save); + LOAD_FSR_REG(fsr_reg); } From gaeke at cs.uiuc.edu Tue Aug 5 14:38:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Aug 5 14:38:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/README Message-ID: <200308051937.OAA24575@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer: README added (r1.1) --- Log message: Documentation, such as it is. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/README diff -c /dev/null llvm/lib/Reoptimizer/README:1.1 *** /dev/null Tue Aug 5 14:37:25 2003 --- llvm/lib/Reoptimizer/README Tue Aug 5 14:37:15 2003 *************** *** 0 **** --- 1,39 ---- + + Field guide to subdirectories of lib/Reoptimizer + ************************************************ + + Inst + - Joel Stanley's project. + + SSAPRE + - Contains a project by Tanya Brethour that does loop invariant + code motion for traces. + + Trigger + - Anand's OLD reoptimizer. + + Mapping + - Functions to query the mapping between LLVM Instructions and MachineInstrs + which can be generated by opt and output as part of the SPARC + assembly by LLC. + + LightWtProfiling/Trigger + - Anand's redesigned reoptimizer. + + TraceCache + - Manages traces for the reoptimizers. + - Classes TraceCache, VirtualMem, MemoryManager. + - Used by: Trigger, LightWtProfiling/Trigger, Inst/lib, BinInterface + + ScratchMemory + - Contains two files with functions that have large blocks of for + loops. These for loops are overwritten by code which is written into + the trace cache. + - Used by: LightWtProfiling/Trigger, TraceCache/MemoryManager.cpp + + BinInterface + - Analyze SPARC instructions, construct pseudo-SSA form, and manipulate + traces. Also includes a SPARC disassembler. Primarily done by + Cameron Buschardt. + - Used by: Trigger, SSAPRE/RuntimeLICM.cpp (only LLVMTrace), + Inst/lib/SparcInstManip.{cpp,h} From gaeke at cs.uiuc.edu Tue Aug 5 14:52:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Aug 5 14:52:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Message-ID: <200308051951.OAA25361@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: SecondTrigger.cpp updated: 1.4 -> 1.5 --- Log message: Include RegSaveRestore.h. Remove a few dead comments. Fix typo I introduced in llvm_time_end(). Use SAVE/LOAD macros in countPath(). --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.4 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.5 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.4 Tue Aug 5 14:34:20 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Tue Aug 5 14:51:06 2003 @@ -17,6 +17,7 @@ #include "llvm/Support/CFG.h" #include "llvm/Module.h" #include "GetTimer.h" +#include "RegSaveRestore.h" #include #include #include @@ -92,7 +93,7 @@ // because the compiler could move instructions across the `asm's. SAVE_I_REGS(i_reg_save); SAVE_G1_REG(g1_reg); - SAVE_G5_REG(g1_reg); + SAVE_G5_REG(g5_reg); SAVE_F_REGS_1(f_reg_save); // SAVE_F_REGS_2(f_reg_save); SAVE_FD_REGS(fd_reg_save); @@ -149,8 +150,6 @@ LOAD_FSR_REG(fsr_reg); } - - void getPaths(std::vector &paths, std::map *mMap, int total){ std::multimap mulMap; @@ -188,9 +187,8 @@ } } -void countPath(){//unsigned int br){ +void countPath () { uint64_t branchHist; - //save regs uint64_t i_reg_save[6]; uint32_t f_reg_save[32]; uint64_t fd_reg_save[16]; @@ -198,74 +196,17 @@ uint64_t fprs_reg; uint64_t fsr_reg; uint64_t g1_reg; - //#ifdef __sparc - asm volatile ("stx %%i0, %0": "=m"(i_reg_save[0])); - asm volatile ("stx %%i1, %0": "=m"(i_reg_save[1])); - asm volatile ("stx %%i2, %0": "=m"(i_reg_save[2])); - asm volatile ("stx %%i3, %0": "=m"(i_reg_save[3])); - asm volatile ("stx %%i4, %0": "=m"(i_reg_save[4])); - asm volatile ("stx %%i5, %0": "=m"(i_reg_save[5])); - asm volatile ("stx %%g1, %0": "=m"(branchHist)); - asm volatile ("stx %%g1, %0": "=m"(g1_reg)); - - asm volatile ("st %%f0, %0": "=m"(f_reg_save[0])); - asm volatile ("st %%f1, %0": "=m"(f_reg_save[1])); - asm volatile ("st %%f2, %0": "=m"(f_reg_save[2])); - asm volatile ("st %%f3, %0": "=m"(f_reg_save[3])); - asm volatile ("st %%f4, %0": "=m"(f_reg_save[4])); - asm volatile ("st %%f5, %0": "=m"(f_reg_save[5])); - asm volatile ("st %%f6, %0": "=m"(f_reg_save[6])); - asm volatile ("st %%f7, %0": "=m"(f_reg_save[7])); - asm volatile ("st %%f8, %0": "=m"(f_reg_save[8])); - asm volatile ("st %%f9, %0": "=m"(f_reg_save[9])); - asm volatile ("st %%f10, %0": "=m"(f_reg_save[10])); - asm volatile ("st %%f11, %0": "=m"(f_reg_save[11])); - asm volatile ("st %%f12, %0": "=m"(f_reg_save[12])); - asm volatile ("st %%f13, %0": "=m"(f_reg_save[13])); - asm volatile ("st %%f14, %0": "=m"(f_reg_save[14])); - asm volatile ("st %%f15, %0": "=m"(f_reg_save[15])); - - /* - asm volatile ("st %%f16, %0": "=m"(f_reg_save[16])); - asm volatile ("st %%f17, %0": "=m"(f_reg_save[17])); - asm volatile ("st %%f18, %0": "=m"(f_reg_save[18])); - asm volatile ("st %%f19, %0": "=m"(f_reg_save[19])); - asm volatile ("st %%f20, %0": "=m"(f_reg_save[20])); - asm volatile ("st %%f21, %0": "=m"(f_reg_save[21])); - asm volatile ("st %%f22, %0": "=m"(f_reg_save[22])); - asm volatile ("st %%f23, %0": "=m"(f_reg_save[23])); - asm volatile ("st %%f24, %0": "=m"(f_reg_save[24])); - asm volatile ("st %%f25, %0": "=m"(f_reg_save[25])); - asm volatile ("st %%f26, %0": "=m"(f_reg_save[26])); - asm volatile ("st %%f27, %0": "=m"(f_reg_save[27])); - asm volatile ("st %%f28, %0": "=m"(f_reg_save[28])); - asm volatile ("st %%f29, %0": "=m"(f_reg_save[29])); - asm volatile ("st %%f30, %0": "=m"(f_reg_save[30])); - asm volatile ("st %%f31, %0": "=m"(f_reg_save[31]));*/ - asm volatile ("std %%f32, %0": "=m"(fd_reg_save[32/2-16])); - asm volatile ("std %%f34, %0": "=m"(fd_reg_save[34/2-16])); - asm volatile ("std %%f36, %0": "=m"(fd_reg_save[36/2-16])); - asm volatile ("std %%f38, %0": "=m"(fd_reg_save[38/2-16])); - asm volatile ("std %%f40, %0": "=m"(fd_reg_save[40/2-16])); - asm volatile ("std %%f42, %0": "=m"(fd_reg_save[42/2-16])); - asm volatile ("std %%f44, %0": "=m"(fd_reg_save[44/2-16])); - asm volatile ("std %%f46, %0": "=m"(fd_reg_save[46/2-16])); - //*/ - asm volatile ("std %%f48, %0": "=m"(fd_reg_save[48/2-16])); - asm volatile ("std %%f50, %0": "=m"(fd_reg_save[50/2-16])); - asm volatile ("std %%f52, %0": "=m"(fd_reg_save[52/2-16])); - asm volatile ("std %%f54, %0": "=m"(fd_reg_save[54/2-16])); - asm volatile ("std %%f56, %0": "=m"(fd_reg_save[56/2-16])); - asm volatile ("std %%f58, %0": "=m"(fd_reg_save[58/2-16])); - asm volatile ("std %%f60, %0": "=m"(fd_reg_save[60/2-16])); - asm volatile ("std %%f62, %0": "=m"(fd_reg_save[62/2-16])); - - asm volatile ("stx %%fsr, %0": "=m" (fsr_reg)); - asm volatile ("rd %%fprs, %0": "=r"(fprs_reg)); - asm volatile ("rd %%ccr, %0": "=r"(ccr_reg)); - - //static TraceCache2 *tr2 = new TraceCache2(); + SAVE_I_REGS(i_reg_save); + SAVE_G1_REG(branchHist); + SAVE_G1_REG(g1_reg); + SAVE_F_REGS_1(f_reg_save); + // SAVE_F_REGS_2(f_reg_save); + SAVE_FD_REGS(fd_reg_save); + SAVE_FSR_REG(fsr_reg); + SAVE_FPRS_REG(fprs_reg); + SAVE_CCR_REG(ccr_reg); + uint64_t pcAddr, startAddr, endAddr; //get the PC address for call to trigger @@ -423,74 +364,17 @@ pathCounter[pcAddr] = newMap; } - //#ifdef __sparc fprs_reg ^= 0; ccr_reg ^= 0; - asm volatile ("wr %0, 0, %%ccr":: "r"(ccr_reg)); - asm volatile ("ldx %0, %%i0":: "m"(i_reg_save[0])); - asm volatile ("ldx %0, %%i1":: "m"(i_reg_save[1])); - asm volatile ("ldx %0, %%i2":: "m"(i_reg_save[2])); - asm volatile ("ldx %0, %%i3":: "m"(i_reg_save[3])); - asm volatile ("ldx %0, %%i4":: "m"(i_reg_save[4])); - asm volatile ("ldx %0, %%i5":: "m"(i_reg_save[5])); - asm volatile ("ldx %0, %%g1":: "m"(g1_reg)); - - asm volatile ("wr %0, 0, %%fprs":: "r"(fprs_reg)); - asm volatile ("ld %0, %%f0":: "m"(f_reg_save[0])); - asm volatile ("ld %0, %%f1":: "m"(f_reg_save[1])); - asm volatile ("ld %0, %%f2":: "m"(f_reg_save[2])); - asm volatile ("ld %0, %%f3":: "m"(f_reg_save[3])); - asm volatile ("ld %0, %%f4":: "m"(f_reg_save[4])); - asm volatile ("ld %0, %%f5":: "m"(f_reg_save[5])); - asm volatile ("ld %0, %%f6":: "m"(f_reg_save[6])); - asm volatile ("ld %0, %%f7":: "m"(f_reg_save[7])); - asm volatile ("ld %0, %%f8":: "m"(f_reg_save[8])); - asm volatile ("ld %0, %%f9":: "m"(f_reg_save[9])); - asm volatile ("ld %0, %%f10":: "m"(f_reg_save[10])); - asm volatile ("ld %0, %%f11":: "m"(f_reg_save[11])); - asm volatile ("ld %0, %%f12":: "m"(f_reg_save[12])); - asm volatile ("ld %0, %%f13":: "m"(f_reg_save[13])); - asm volatile ("ld %0, %%f14":: "m"(f_reg_save[14])); - asm volatile ("ld %0, %%f15":: "m"(f_reg_save[15])); - - /* - asm volatile ("ld %0, %%f16":: "m"(f_reg_save[16])); - asm volatile ("ld %0, %%f17":: "m"(f_reg_save[17])); - asm volatile ("ld %0, %%f18":: "m"(f_reg_save[18])); - asm volatile ("ld %0, %%f19":: "m"(f_reg_save[19])); - asm volatile ("ld %0, %%f20":: "m"(f_reg_save[20])); - asm volatile ("ld %0, %%f21":: "m"(f_reg_save[21])); - asm volatile ("ld %0, %%f22":: "m"(f_reg_save[22])); - asm volatile ("ld %0, %%f23":: "m"(f_reg_save[23])); - asm volatile ("ld %0, %%f24":: "m"(f_reg_save[24])); - asm volatile ("ld %0, %%f25":: "m"(f_reg_save[25])); - asm volatile ("ld %0, %%f26":: "m"(f_reg_save[26])); - asm volatile ("ld %0, %%f27":: "m"(f_reg_save[27])); - asm volatile ("ld %0, %%f28":: "m"(f_reg_save[28])); - asm volatile ("ld %0, %%f29":: "m"(f_reg_save[29])); - asm volatile ("ld %0, %%f30":: "m"(f_reg_save[30])); - asm volatile ("ld %0, %%f31":: "m"(f_reg_save[31]));*/ - asm volatile ("ldd %0, %%f32":: "m"(fd_reg_save[32/2-16])); - asm volatile ("ldd %0, %%f34":: "m"(fd_reg_save[34/2-16])); - asm volatile ("ldd %0, %%f36":: "m"(fd_reg_save[36/2-16])); - asm volatile ("ldd %0, %%f38":: "m"(fd_reg_save[38/2-16])); - asm volatile ("ldd %0, %%f40":: "m"(fd_reg_save[40/2-16])); - asm volatile ("ldd %0, %%f42":: "m"(fd_reg_save[42/2-16])); - asm volatile ("ldd %0, %%f44":: "m"(fd_reg_save[44/2-16])); - asm volatile ("ldd %0, %%f46":: "m"(fd_reg_save[46/2-16])); - //*/ - asm volatile ("ldd %0, %%f48":: "m"(fd_reg_save[48/2-16])); - asm volatile ("ldd %0, %%f50":: "m"(fd_reg_save[50/2-16])); - asm volatile ("ldd %0, %%f52":: "m"(fd_reg_save[52/2-16])); - asm volatile ("ldd %0, %%f54":: "m"(fd_reg_save[54/2-16])); - asm volatile ("ldd %0, %%f56":: "m"(fd_reg_save[56/2-16])); - asm volatile ("ldd %0, %%f58":: "m"(fd_reg_save[58/2-16])); - asm volatile ("ldd %0, %%f60":: "m"(fd_reg_save[60/2-16])); - asm volatile ("ldd %0, %%f62":: "m"(fd_reg_save[62/2-16])); - - asm volatile ("ldx %0, %%fsr":: "m"(fsr_reg)); - //#endif + LOAD_CCR_REG(ccr_reg); + LOAD_I_REGS(i_reg_save); + LOAD_G1_REG(g1_reg); + LOAD_FPRS_REG(fprs_reg); + LOAD_F_REGS_1(f_reg_save); + // LOAD_F_REGS_2(f_reg_save); + LOAD_FD_REGS(fd_reg_save); + LOAD_FSR_REG(fsr_reg); } void getBranchExitCode(std::vector &instVec, From gaeke at cs.uiuc.edu Tue Aug 5 15:01:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Aug 5 15:01:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h SecondTrigger.cpp Message-ID: <200308052000.PAA25948@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: GetTimer.h updated: 1.2 -> 1.3 SecondTrigger.cpp updated: 1.5 -> 1.6 --- Log message: Move FOR_DEBUG macro to GetTimer.h along with the other configuration parameters; I will probably merge this with GET_ALL_INFO into a DEBUG macro similar to what the rest of LLVM uses. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.2 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.3 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.2 Tue Aug 5 13:21:26 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h Tue Aug 5 15:00:18 2003 @@ -9,6 +9,7 @@ #define GET_ALL_INFO // #undef GET_COVERAGE +// #undef FOR_DEBUG #define MAX_PATH_HISTORIES 12 #define MAX_ALLOWED_PATHS 6 #define THRESHOLD_PERCENTAGE 90 Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.5 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.6 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.5 Tue Aug 5 14:51:06 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Tue Aug 5 15:00:18 2003 @@ -440,7 +440,6 @@ std::cerr<<"\n"; } -//#define FOR_DEBUG #if 0 void doTrigger(unsigned int path, uint64_t start, uint64_t firstLevelTraceStartAddr){ From tbrethou at niobe.cs.uiuc.edu Tue Aug 5 15:40:01 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Tue Aug 5 15:40:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200308052039.h75KdCA14221@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.29 -> 1.30 --- Log message: Fixed minor bug in SafeToHoist and made some changes suggested by Chris. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.29 llvm/lib/Transforms/Scalar/LICM.cpp:1.30 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.29 Tue Aug 5 13:45:46 2003 +++ llvm/lib/Transforms/Scalar/LICM.cpp Tue Aug 5 15:39:02 2003 @@ -67,7 +67,7 @@ BasicBlock *Preheader; // The preheader block of the current loop... Loop *CurLoop; // The current loop we are working on... AliasSetTracker *CurAST; // AliasSet information for the current loop... - DominatorTree *CurDT; // Dominator Tree for the current Loop... + DominatorTree *DT; // Dominator Tree for the current Loop... /// visitLoop - Hoist expressions out of the specified loop... /// @@ -173,6 +173,7 @@ // Get our Loop and Alias Analysis information... LI = &getAnalysis(); AA = &getAnalysis(); + DT = &getAnalysis(); // Hoist expressions out of all of the top-level loops. const std::vector &TopLevelLoops = LI->getTopLevelLoops(); @@ -223,9 +224,7 @@ // that we are guaranteed to see definitions before we see uses. This allows // us to perform the LICM transformation in one pass, without iteration. // - CurDT = &getAnalysis(); - - HoistRegion(CurDT->getNode(L->getHeader())); + HoistRegion(DT->getNode(L->getHeader())); // Now that all loop invariants have been removed from the loop, promote any // memory references to scalars that we can... @@ -290,36 +289,28 @@ BasicBlock *InstBB = Inst.getParent(); //Get the Dominator Tree Node for the instruction's basic block/ - DominatorTree::Node *InstDTNode = CurDT->getNode(InstBB); + DominatorTree::Node *InstDTNode = DT->getNode(InstBB); //Get the exit blocks for the current loop. - const std::vector ExitBlocks = CurLoop->getExitBlocks(); + const std::vector &ExitBlocks = CurLoop->getExitBlocks(); //For each exit block, get the DT node and walk up the DT until //the instruction's basic block is found or we exit the loop. for(unsigned i=0; i < ExitBlocks.size(); ++i) { - DominatorTree::Node *IDom = CurDT->getNode(ExitBlocks[i]); + DominatorTree::Node *IDom = DT->getNode(ExitBlocks[i]); - //Using boolean variable because exit nodes are not "contained" - //in the loop, so can not use that as the while test condition - //for first pass. - bool inLoop = true; - - while(inLoop) { + while(IDom != InstDTNode) { - //compare Instruction DT node to Current DT Node - if(IDom == InstDTNode) - return true; - //Get next Immediate Dominator. IDom = IDom->getIDom(); //See if we exited the loop. - inLoop = CurLoop->contains(IDom->getNode()); + if(!CurLoop->contains(IDom->getNode())) + return false; } - return false; } } + return true; } From criswell at cs.uiuc.edu Tue Aug 5 16:23:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Aug 5 16:23:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308052122.QAA30701@psmith.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.106 -> 1.107 --- Log message: Switched from using diff to cmp for two reasons: o Not all versions of diff have the -q option o The cmp program is probably faster than diff Fixed the logic that only copies the file over if no differences are found. --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.106 llvm/Makefile.common:1.107 --- llvm/Makefile.common:1.106 Mon Aug 4 15:07:01 2003 +++ llvm/Makefile.common Tue Aug 5 16:21:58 2003 @@ -773,7 +773,7 @@ $(SED) 's/void \*yy_flex_realloc/inline void *yy_flex_realloc/' | \ $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' \ > $@.tmp - $(VERB) diff -q $@ $@.tmp > /dev/null || ${MV} -f $@.tmp $@ + $(VERB) cmp $@ $@.tmp > /dev/null && ${MV} -f $@.tmp $@ @# remove the output of flex if it didn't get moved over... @rm -f $@.tmp @@ -783,8 +783,8 @@ %.cpp %.h : %.y @echo Bison\'ing $<... $(VERB) $(BISON) -v -d -p $(<:%Parser.y=%) $*.y - $(VERB) diff -q $*.tab.c $*.cpp > /dev/null || ${MV} -f $*.tab.c $*.cpp - $(VERB) diff -q $*.tab.h $*.h > /dev/null || ${MV} -f $*.tab.h $*.h + $(VERB) cmp $*.tab.c $*.cpp > /dev/null && ${MV} -f $*.tab.c $*.cpp + $(VERB) cmp $*.tab.h $*.h > /dev/null && ${MV} -f $*.tab.h $*.h @# If the files were not updated, don't leave them lying around... @rm -f $*.tab.c $*.tab.h From criswell at cs.uiuc.edu Tue Aug 5 16:39:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Aug 5 16:39:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308052138.QAA31461@psmith.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.107 -> 1.108 --- Log message: Reverted back to using OR for cmp/mv operations for lex/yacc output. The shell AND/OR operators short-circuit on command success/failure, which is the inverse of exit status (i.e. 0 means success, non-zero means failure). --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.107 llvm/Makefile.common:1.108 --- llvm/Makefile.common:1.107 Tue Aug 5 16:21:58 2003 +++ llvm/Makefile.common Tue Aug 5 16:38:28 2003 @@ -773,7 +773,7 @@ $(SED) 's/void \*yy_flex_realloc/inline void *yy_flex_realloc/' | \ $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' \ > $@.tmp - $(VERB) cmp $@ $@.tmp > /dev/null && ${MV} -f $@.tmp $@ + $(VERB) cmp $@ $@.tmp > /dev/null || ${MV} -f $@.tmp $@ @# remove the output of flex if it didn't get moved over... @rm -f $@.tmp @@ -783,8 +783,8 @@ %.cpp %.h : %.y @echo Bison\'ing $<... $(VERB) $(BISON) -v -d -p $(<:%Parser.y=%) $*.y - $(VERB) cmp $*.tab.c $*.cpp > /dev/null && ${MV} -f $*.tab.c $*.cpp - $(VERB) cmp $*.tab.h $*.h > /dev/null && ${MV} -f $*.tab.h $*.h + $(VERB) cmp $*.tab.c $*.cpp > /dev/null || ${MV} -f $*.tab.c $*.cpp + $(VERB) cmp $*.tab.h $*.h > /dev/null || ${MV} -f $*.tab.h $*.h @# If the files were not updated, don't leave them lying around... @rm -f $*.tab.c $*.tab.h From lattner at cs.uiuc.edu Tue Aug 5 16:56:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 16:56:00 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstr.cpp Message-ID: <200308052155.QAA09777@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.76 -> 1.77 --- Log message: Do not insert physical regsiters into the regsUsed set --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.76 llvm/lib/CodeGen/MachineInstr.cpp:1.77 --- llvm/lib/CodeGen/MachineInstr.cpp:1.76 Tue Aug 5 11:58:46 2003 +++ llvm/lib/CodeGen/MachineInstr.cpp Tue Aug 5 16:55:20 2003 @@ -111,7 +111,6 @@ operands[i].opType = MachineOperand::MO_MachineRegister; operands[i].value = NULL; operands[i].regNum = regNum; - insertUsedReg(regNum); } void @@ -119,14 +118,12 @@ { assert(i < getNumOperands()); // must be explicit op operands[i].setRegForValue(regNum); - insertUsedReg(regNum); } void MachineInstr::SetRegForImplicitRef(unsigned i, int regNum) { getImplicitOp(i).setRegForValue(regNum); - insertUsedReg(regNum); } From lattner at cs.uiuc.edu Tue Aug 5 16:56:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 16:56:11 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200308052155.QAA09761@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.109 -> 1.110 --- Log message: Do not insert physical regsiters into the regsUsed set --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.109 llvm/include/llvm/CodeGen/MachineInstr.h:1.110 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.109 Tue Aug 5 12:09:08 2003 +++ llvm/include/llvm/CodeGen/MachineInstr.h Tue Aug 5 16:55:06 2003 @@ -530,7 +530,6 @@ "Trying to add an operand to a machine instr that is already done!"); operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister, isDef ? MOTy::Def : MOTy::Use)); - insertUsedReg(reg); } /// addMachineRegOperand - Add a virtual register operand to this MachineInstr @@ -540,7 +539,6 @@ "Trying to add an operand to a machine instr that is already done!"); operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister, UTy)); - insertUsedReg(reg); } /// addZeroExtImmOperand - Add a zero extended constant argument to the From lattner at cs.uiuc.edu Tue Aug 5 16:57:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 16:57:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200308052156.QAA09797@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.101 -> 1.102 --- Log message: Physical registers no longer live in the regsUsed set for each machine instr --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.101 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.102 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.101 Tue Jul 29 14:49:21 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Tue Aug 5 16:55:58 2003 @@ -1150,32 +1150,44 @@ // instructions. Both explicit and implicit operands are set. //---------------------------------------------------------------------------- -void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC, - const int RegType, - const MachineInstr *MInst ) +static void markRegisterUsed(int RegNo, RegClass *RC, int RegType, + const TargetRegInfo &TRI) { + unsigned classId = 0; + int classRegNum = TRI.getClassRegNum(RegNo, classId); + if (RC->getID() == classId) + RC->markColorsUsed(classRegNum, RegType, RegType); +} + +void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC, int RegType, + const MachineInstr *MI) { - assert(OperandsColoredMap[MInst] == true && + assert(OperandsColoredMap[MI] == true && "Illegal to call setRelRegsUsedByThisInst() until colored operands " "are marked for an instruction."); - // Add the registers already marked as used by the instruction. - // This should include any scratch registers that are used to save - // values across the instruction (e.g., for saving state register values). - const std::set ®sUsed = MInst->getRegsUsed(); - for (std::set::iterator I=regsUsed.begin(),E=regsUsed.end(); I != E; ++I) - { - int i = *I; - unsigned classId = 0; - int classRegNum = MRI.getClassRegNum(i, classId); - if (RC->getID() == classId) - RC->markColorsUsed(classRegNum, RegType, RegType); - } + // Add the registers already marked as used by the instruction. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) + if (MI->getOperand(i).hasAllocatedReg()) + markRegisterUsed(MI->getOperand(i).getAllocatedRegNum(), RC, RegType,MRI); + + for (unsigned i = 0, e = MI->getNumImplicitRefs(); i != e; ++i) + if (MI->getImplicitOp(i).hasAllocatedReg()) + markRegisterUsed(MI->getImplicitOp(i).getAllocatedRegNum(), RC, + RegType,MRI); + + // The getRegsUsed() method returns the set of scratch registers that are used + // to save values across the instruction (e.g., for saving state register + // values). + const std::set ®sUsed = MI->getRegsUsed(); + for (std::set::iterator I = regsUsed.begin(), + E = regsUsed.end(); I != E; ++I) + markRegisterUsed(*I, RC, RegType, MRI); // If there are implicit references, mark their allocated regs as well // - for (unsigned z=0; z < MInst->getNumImplicitRefs(); z++) + for (unsigned z=0; z < MI->getNumImplicitRefs(); z++) if (const LiveRange* - LRofImpRef = LRI.getLiveRangeForValue(MInst->getImplicitRef(z))) + LRofImpRef = LRI.getLiveRangeForValue(MI->getImplicitRef(z))) if (LRofImpRef->hasColor()) // this implicit reference is in a LR that received a color RC->markColorsUsed(LRofImpRef->getColor(), From lattner at cs.uiuc.edu Tue Aug 5 17:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 17:04:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/PhyRegAlloc.h Message-ID: <200308052203.RAA15557@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: PhyRegAlloc.h updated: 1.44 -> 1.45 --- Log message: Minor cleanups --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/PhyRegAlloc.h diff -u llvm/include/llvm/CodeGen/PhyRegAlloc.h:1.44 llvm/include/llvm/CodeGen/PhyRegAlloc.h:1.45 --- llvm/include/llvm/CodeGen/PhyRegAlloc.h:1.44 Tue Jul 29 14:37:41 2003 +++ llvm/include/llvm/CodeGen/PhyRegAlloc.h Tue Aug 5 17:03:27 2003 @@ -21,7 +21,6 @@ #include "llvm/CodeGen/LiveRangeInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" -#include "Support/NonCopyable.h" #include class MachineFunction; @@ -51,7 +50,7 @@ // registers for a Function. //---------------------------------------------------------------------------- -class PhyRegAlloc : public NonCopyable { +class PhyRegAlloc { std::vector RegClassList; // vector of register classes const TargetMachine &TM; // target machine const Function *Fn; // name of the function we work on @@ -73,6 +72,8 @@ AddedInstrns AddedInstrAtEntry; // to store instrns added at entry LoopInfo *LoopDepthCalc; // to calculate loop depths + PhyRegAlloc(const PhyRegAlloc&); // DO NOT IMPLEMENT + void operator=(const PhyRegAlloc&); // DO NOT IMPLEMENT public: PhyRegAlloc(Function *F, const TargetMachine& TM, FunctionLiveVarInfo *Lvi, LoopInfo *LoopDepthCalc); @@ -84,10 +85,10 @@ // access to register classes by class ID // - const RegClass* getRegClassByID(unsigned int id) const { + const RegClass* getRegClassByID(unsigned id) const { return RegClassList[id]; } - RegClass* getRegClassByID(unsigned int id) { + RegClass* getRegClassByID(unsigned id) { return RegClassList[id]; } @@ -99,19 +100,18 @@ void createIGNodeListsAndIGs(); void buildInterferenceGraphs(); - void setCallInterferences(const MachineInstr *MInst, - const ValueSet *LVSetAft ); + void setCallInterferences(const MachineInstr *MI, + const ValueSet *LVSetAft); void move2DelayedInstr(const MachineInstr *OrigMI, - const MachineInstr *DelayedMI ); + const MachineInstr *DelayedMI); void markUnusableSugColors(); void allocateStackSpace4SpilledLRs(); - void insertCode4SpilledLR (const LiveRange *LR, - MachineBasicBlock::iterator& MII, - MachineBasicBlock &MBB, - const unsigned OpNum); + void insertCode4SpilledLR(const LiveRange *LR, + MachineBasicBlock::iterator& MII, + MachineBasicBlock &MBB, unsigned OpNum); // Method for inserting caller saving code. The caller must save all the // volatile registers live across a call. @@ -128,33 +128,32 @@ void updateInstruction(MachineBasicBlock::iterator& MII, MachineBasicBlock &MBB); - void printLabel(const Value *const Val); + void printLabel(const Value *Val); void printMachineCode(); - int getUsableUniRegAtMI(int RegType, - const ValueSet *LVSetBef, - MachineInstr *MInst, + int getUsableUniRegAtMI(int RegType, const ValueSet *LVSetBef, + MachineInstr *MI, std::vector& MIBef, std::vector& MIAft); // Callback method used to find unused registers. // LVSetBef is the live variable set to search for an unused register. - // If it is not specified, the LV set before the current MInst is used. + // If it is not specified, the LV set before the current MI is used. // This is sufficient as long as no new copy instructions are generated // to copy the free register to memory. // - int getUnusedUniRegAtMI(RegClass *RC, const int RegType, - const MachineInstr *MInst, + int getUnusedUniRegAtMI(RegClass *RC, int RegType, + const MachineInstr *MI, const ValueSet *LVSetBef = 0); - void setRelRegsUsedByThisInst(RegClass *RC, const int RegType, - const MachineInstr *MInst ); + void setRelRegsUsedByThisInst(RegClass *RC, int RegType, + const MachineInstr *MI); - int getUniRegNotUsedByThisInst(RegClass *RC, const int RegType, - const MachineInstr *MInst); + int getUniRegNotUsedByThisInst(RegClass *RC, int RegType, + const MachineInstr *MI); - void addInterf4PseudoInstr(const MachineInstr *MInst); + void addInterf4PseudoInstr(const MachineInstr *MI); }; From lattner at cs.uiuc.edu Tue Aug 5 17:10:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 17:10:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/PhyRegAlloc.h Message-ID: <200308052209.RAA16119@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: PhyRegAlloc.h updated: 1.45 -> 1.46 --- Log message: Add a map --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/PhyRegAlloc.h diff -u llvm/include/llvm/CodeGen/PhyRegAlloc.h:1.45 llvm/include/llvm/CodeGen/PhyRegAlloc.h:1.46 --- llvm/include/llvm/CodeGen/PhyRegAlloc.h:1.45 Tue Aug 5 17:03:27 2003 +++ llvm/include/llvm/CodeGen/PhyRegAlloc.h Tue Aug 5 17:09:31 2003 @@ -69,6 +69,10 @@ // AddedInstrMap - Used to store instrns added in this phase std::map AddedInstrMap; + // ScratchRegsUsed - Contains scratch register uses for a particular MI. + typedef std::multimap ScratchRegsUsedTy; + ScratchRegsUsedTy ScratchRegsUsed; + AddedInstrns AddedInstrAtEntry; // to store instrns added at entry LoopInfo *LoopDepthCalc; // to calculate loop depths From lattner at cs.uiuc.edu Tue Aug 5 17:12:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 17:12:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200308052211.RAA16144@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.102 -> 1.103 --- Log message: Use a new local data structure instead of the MachineInstr::regsUsed set --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.102 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.103 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.102 Tue Aug 5 16:55:58 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Tue Aug 5 17:11:13 2003 @@ -1059,7 +1059,7 @@ // of copying it to memory and back. But we have to mark the // register as used by this instruction, so it does not get used // as a scratch reg. by another operand or anyone else. - MInst->insertUsedReg(scratchReg); + ScratchRegsUsed.insert(std::make_pair(MInst, scratchReg)); MRI.cpReg2RegMI(MIBef, RegU, scratchReg, RegType); MRI.cpReg2RegMI(MIAft, scratchReg, RegU, RegType); } @@ -1175,13 +1175,12 @@ markRegisterUsed(MI->getImplicitOp(i).getAllocatedRegNum(), RC, RegType,MRI); - // The getRegsUsed() method returns the set of scratch registers that are used - // to save values across the instruction (e.g., for saving state register - // values). - const std::set ®sUsed = MI->getRegsUsed(); - for (std::set::iterator I = regsUsed.begin(), - E = regsUsed.end(); I != E; ++I) - markRegisterUsed(*I, RC, RegType, MRI); + // Add all of the scratch registers that are used to save values across the + // instruction (e.g., for saving state register values). + std::pair + IR = ScratchRegsUsed.equal_range(MI); + for (ScratchRegsUsedTy::iterator I = IR.first; I != IR.second; ++I) + markRegisterUsed(I->second, RC, RegType, MRI); // If there are implicit references, mark their allocated regs as well // From lattner at cs.uiuc.edu Tue Aug 5 17:40:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 17:40:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200308052239.RAA22926@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.110 -> 1.111 --- Log message: Completely eliminate the per-machine-instruction regsUsed set. This substantially shrinks the size of each machine instruction, which should make allocation faster and the cache footprint of the machine code lighter. Here are some timings for code generation of the larger benchmarks we have. This are timings of code generation phases of the X86 JIT, when compiled in debug mode: Before After Diff 164.gzip: InstSel 0.0878 0.0722 -21.6% RegAlloc 0.2031 0.1757 -15.6% TOTAL 0.5585 0.4999 -11.7% Ptrdist-bc: InstSel 0.0878 0.0722 -21.6% RegAlloc 0.2070 0.1933 - 7.1% TOTAL 0.6972 0.6464 - 7.9% 197.parser: InstSel 0.2148 0.2148 - 0.0% RegAlloc 0.4941 0.4277 -15.5% TOTAL 1.3749 1.2851 - 7.0% 175.vpr: InstSel 0.2519 0.2109 -19.4% RegAlloc 0.5976 0.5663 - 5.5% TOTAL 1.6933 1.6347 - 3.5% 254.gap: InstSel 1.1328 0.9921 -14.2% RegAlloc 2.6933 2.4804 - 8.6% TOTAL 7.7871 7.2499 - 7.4% --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.110 llvm/include/llvm/CodeGen/MachineInstr.h:1.111 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.110 Tue Aug 5 16:55:06 2003 +++ llvm/include/llvm/CodeGen/MachineInstr.h Tue Aug 5 17:39:13 2003 @@ -346,10 +346,6 @@ std::vector operands; // the operands unsigned numImplicitRefs; // number of implicit operands - // regsUsed - all machine registers used for this instruction, including regs - // used to save values across the instruction. This is a bitset of registers. - std::set regsUsed; - // OperandComplete - Return true if it's illegal to add a new operand bool OperandsComplete() const; @@ -436,17 +432,6 @@ assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!"); SetMachineOperandVal(i + getNumOperands(), MachineOperand::MO_VirtualRegister, V); - } - - // - // Information about registers used in this instruction. - // - const std::set &getRegsUsed() const { - return regsUsed; - } - void insertUsedReg(unsigned Reg) { - assert(((int) Reg) >= 0 && "Invalid register being marked as used"); - regsUsed.insert((int) Reg); } // From lattner at cs.uiuc.edu Tue Aug 5 17:55:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 17:55:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/ProgrammersManual.html Message-ID: <200308052254.RAA12248@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: ProgrammersManual.html updated: 1.43 -> 1.44 --- Log message: "fix" coding style stuff Change some <>'s into <>'s --- Diffs of the changes: Index: llvm/www/docs/ProgrammersManual.html diff -u llvm/www/docs/ProgrammersManual.html:1.43 llvm/www/docs/ProgrammersManual.html:1.44 --- llvm/www/docs/ProgrammersManual.html:1.43 Fri Aug 1 17:26:27 2003 +++ llvm/www/docs/ProgrammersManual.html Tue Aug 5 17:54:23 2003 @@ -244,7 +244,7 @@ return true; // Otherwise, it must be an instruction... - return !L->contains(cast<Instruction>(V)->getParent()); + return !L->contains(cast<Instruction>(V)->getParent());

Note that you should not use an isa<> test followed by a @@ -275,7 +275,7 @@

   // Loop over all of the phi nodes in a basic block
-  BasicBlock::iterator BBI = BB->begin();
+  BasicBlock::iterator BBI = BB->begin();
   for (; PHINode *PN = dyn_cast<PHINode>(BBI); ++BBI)
     cerr << *PN;
 

@@ -560,7 +560,7 @@

   // func is a pointer to a Function instance
-  for(Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
+  for (Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
 
       // print out the name of the basic block if it has one, and then the
       // number of instructions that it contains
@@ -573,7 +573,7 @@
 Note that i can be used as if it were a pointer for the purposes of
 invoking member functions of the Instruction class.  This is
 because the indirection operator is overloaded for the iterator
-classes.  In the above code, the expression i->size() is
+classes.  In the above code, the expression i->size() is
 exactly equivalent to (*i).size() just like you'd expect.
 
 
@@ -588,7 +588,7 @@
 
 
   // blk is a pointer to a BasicBlock instance
-  for(BasicBlock::iterator i = blk->begin(), e = blk->end(); i != e; ++i)
+  for (BasicBlock::iterator i = blk->begin(), e = blk->end(); i != e; ++i)
      // the next statement works since operator<<(ostream&,...) 
      // is overloaded for Instruction&
      cerr << *i << "\n";
@@ -625,7 +625,7 @@
 #include "llvm/Support/InstIterator.h"
 ...
 // Suppose F is a ptr to a function
-for(inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
+for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
   cerr << **i << "\n";
 
@@ -683,7 +683,7 @@ void printNextInstruction(Instruction* inst) { BasicBlock::iterator it(inst); ++it; // after this line, it refers to the instruction after *inst. - if(it != inst->getParent()->end()) cerr << *it << "\n"; + if (it != inst->getParent()->end()) cerr << *it << "\n"; }
Of course, this example is strictly pedagogical, because it'd be much @@ -708,7 +708,7 @@ for each Function f in the Module for each BasicBlock b in f for each Instruction i in b - if(i is a CallInst and calls the given function) + if (i is a CallInst and calls the given function) increment callCounter @@ -724,14 +724,14 @@ OurFunctionPass(): callCounter(0) { } virtual runOnFunction(Function& F) { - for(Function::iterator b = F.begin(), be = F.end(); b != be; ++b) { - for(BasicBlock::iterator i = b->begin(); ie = b->end(); i != ie; ++i) { + for (Function::iterator b = F.begin(), be = F.end(); b != be; ++b) { + for (BasicBlock::iterator i = b->begin(); ie = b->end(); i != ie; ++i) { if (CallInst* callInst = dyn_cast<CallInst>(&*i)) { // we know we've encountered a call instruction, so we // need to determine if it's a call to the // function pointed to by m_func or not. - if(callInst->getCalledFunction() == targetFunc) + if (callInst->getCalledFunction() == targetFunc) ++callCounter; } } @@ -759,8 +759,8 @@
 Function* F = ...;
 
-for(Value::use_iterator i = F->use_begin(), e = F->use_end(); i != e; ++i) {
-    if(Instruction* Inst = dyn_cast<Instruction>(*i)) {
+for (Value::use_iterator i = F->use_begin(), e = F->use_end(); i != e; ++i) {
+    if (Instruction *Inst = dyn_cast<Instruction>(*i)) {
         cerr << "F is used in instruction:\n";
         cerr << *Inst << "\n";
     }
@@ -778,7 +778,7 @@
 
 Instruction* pi = ...;
 
-for(User::op_iterator i = pi->op_begin(), e = pi->op_end(); i != e; ++i) {
+for (User::op_iterator i = pi->op_begin(), e = pi->op_end(); i != e; ++i) {
     Value* v = *i;
     ...
 }
@@ -861,10 +861,10 @@
 we wish to insert before *pi, we do the following:
 
 
-BasicBlock* pb = ...;
-Instruction* pi = ...;
-Instruction* newInst = new Instruction(...);
-pb->getInstList().insert(pi, newInst); // inserts newInst before pi in pb
+  BasicBlock *pb = ...;
+  Instruction *pi = ...;
+  Instruction *newInst = new Instruction(...);
+  pb->getInstList().insert(pi, newInst); // inserts newInst before pi in pb
 

@@ -875,9 +875,9 @@ Thus, we could have accomplished the same thing as the above code without being given a BasicBlock by doing:
-Instruction* pi = ...;
-Instruction* newInst = new Instruction(...);
-pi->getParent()->getInstList().insert(pi, newInst);
+  Instruction *pi = ...;
+  Instruction *newInst = new Instruction(...);
+  pi->getParent()->getInstList().insert(pi, newInst);
 
In fact, this sequence of steps occurs so frequently that the Instruction class and Instruction-derived classes @@ -1689,11 +1689,11 @@
  • ConstantArray : This represents a constant array.
      -
    • const std::vector &getValues() const: Returns a Vecotr of component constants that makeup this array. +
    • const std::vector<Use> &getValues() const: Returns a Vecotr of component constants that makeup this array.
  • ConstantStruct : This represents a constant struct.
      -
    • const std::vector &getValues() const: Returns a Vecotr of component constants that makeup this array. +
    • const std::vector<Use> &getValues() const: Returns a Vecotr of component constants that makeup this array.
  • ConstantPointerRef : This represents a constant pointer value that is initialized to point to a global value, which lies at a constant fixed address.
      @@ -1789,6 +1789,6 @@ Chris Lattner -Last modified: Fri Aug 1 17:26:10 CDT 2003 +Last modified: Tue Aug 5 17:53:43 CDT 2003 From kowshik at cs.uiuc.edu Tue Aug 5 20:04:02 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Tue Aug 5 20:04:02 2003 Subject: [llvm-commits] CVS: llvm/test/Makefile.tests Message-ID: <200308060103.UAA30437@apoc.cs.uiuc.edu> Changes in directory llvm/test: Makefile.tests updated: 1.71 -> 1.72 --- Log message: Added POOLFLAGS option to run pool allocation --- Diffs of the changes: Index: llvm/test/Makefile.tests diff -u llvm/test/Makefile.tests:1.71 llvm/test/Makefile.tests:1.72 --- llvm/test/Makefile.tests:1.71 Fri Jul 25 17:26:17 2003 +++ llvm/test/Makefile.tests Tue Aug 5 20:03:28 2003 @@ -77,7 +77,16 @@ TRACELIBS := -L$(LEVEL)/test/Libraries/Output -linstr.$(ARCH) endif -LLCLIBS += -lm +POOLFLAGS = +DOPOOLALLOC = +## If POOLALLOC is "yes", set the opt flag and the POOLLIBS varoab;e +ifeq ($(POOLALLOC), yes) + POOLFLAGS += -poolalloc + DOPOOLALLOC = yes + POOLLIBS := -L$(LEVEL)/test/Libraries/Output +endif + +LLCLIBS := $(LLCLIBS) -lm clean:: $(RM) -f a.out core From lattner at cs.uiuc.edu Tue Aug 5 23:24:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 23:24:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGenBackend.h TableGenBackend.cpp Message-ID: <200308060423.XAA00490@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGenBackend.h added (r1.1) TableGenBackend.cpp added (r1.1) --- Log message: New common interface for backends to use --- Diffs of the changes: Index: llvm/utils/TableGen/TableGenBackend.h diff -c /dev/null llvm/utils/TableGen/TableGenBackend.h:1.1 *** /dev/null Tue Aug 5 23:23:14 2003 --- llvm/utils/TableGen/TableGenBackend.h Tue Aug 5 23:23:04 2003 *************** *** 0 **** --- 1,26 ---- + //===- TableGenBackend.h - Base class for TableGen Backends -----*- C++ -*-===// + // + // The TableGenBackend class is provided as a common interface for all TableGen + // backends. It provides useful services and an standardized interface. + // + //===----------------------------------------------------------------------===// + + #ifndef TABLEGENBACKEND_H + #define TABLEGENBACKEND_H + + #include + #include + + struct TableGenBackend { + + // run - All TableGen backends should implement the run method, which should + // be the main entry point. + virtual void run(std::ostream &OS) = 0; + + + public: // Useful helper routines... + void EmitSourceFileHeader(const std::string &Desc, std::ostream &OS) const; + + }; + + #endif Index: llvm/utils/TableGen/TableGenBackend.cpp diff -c /dev/null llvm/utils/TableGen/TableGenBackend.cpp:1.1 *** /dev/null Tue Aug 5 23:23:14 2003 --- llvm/utils/TableGen/TableGenBackend.cpp Tue Aug 5 23:23:04 2003 *************** *** 0 **** --- 1,17 ---- + //===- TableGenBackend.cpp - Base class for TableGen Backends ---*- C++ -*-===// + // + // This file provides useful services for TableGen backends... + // + //===----------------------------------------------------------------------===// + + #include "TableGenBackend.h" + #include + + void TableGenBackend::EmitSourceFileHeader(const std::string &Desc, + std::ostream &OS) { + OS << "//===- TableGen'erated file -------------------------------------*-" + " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" + "d file, do not edit!\n//\n//===------------------------------------" + "----------------------------------===//\n\n"; + } + From lattner at cs.uiuc.edu Tue Aug 5 23:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 23:32:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGenBackend.h TableGenBackend.cpp Message-ID: <200308060431.XAA02374@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGenBackend.h updated: 1.1 -> 1.2 TableGenBackend.cpp updated: 1.1 -> 1.2 --- Log message: Add more helper methods --- Diffs of the changes: Index: llvm/utils/TableGen/TableGenBackend.h diff -u llvm/utils/TableGen/TableGenBackend.h:1.1 llvm/utils/TableGen/TableGenBackend.h:1.2 --- llvm/utils/TableGen/TableGenBackend.h:1.1 Tue Aug 5 23:23:04 2003 +++ llvm/utils/TableGen/TableGenBackend.h Tue Aug 5 23:31:26 2003 @@ -10,6 +10,8 @@ #include #include +class Record; +class RecordKeeper; struct TableGenBackend { @@ -19,8 +21,16 @@ public: // Useful helper routines... + /// EmitSourceFileHeader - Output a LLVM style file header to the specified + /// ostream. void EmitSourceFileHeader(const std::string &Desc, std::ostream &OS) const; + /// getQualifiedName - Return the name of the specified record, with a + /// namespace qualifier if the record contains one. + std::string getQualifiedName(Record *R) const; + + /// getTarget - Return the current instance of the Target class. + Record *getTarget(RecordKeeper &RC) const; }; #endif Index: llvm/utils/TableGen/TableGenBackend.cpp diff -u llvm/utils/TableGen/TableGenBackend.cpp:1.1 llvm/utils/TableGen/TableGenBackend.cpp:1.2 --- llvm/utils/TableGen/TableGenBackend.cpp:1.1 Tue Aug 5 23:23:04 2003 +++ llvm/utils/TableGen/TableGenBackend.cpp Tue Aug 5 23:31:26 2003 @@ -5,13 +5,32 @@ //===----------------------------------------------------------------------===// #include "TableGenBackend.h" +#include "Record.h" #include void TableGenBackend::EmitSourceFileHeader(const std::string &Desc, - std::ostream &OS) { + std::ostream &OS) const { OS << "//===- TableGen'erated file -------------------------------------*-" " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" "d file, do not edit!\n//\n//===------------------------------------" "----------------------------------===//\n\n"; } +/// getQualifiedName - Return the name of the specified record, with a +/// namespace qualifier if the record contains one. +/// +std::string TableGenBackend::getQualifiedName(Record *R) const { + std::string Namespace = R->getValueAsString("Namespace"); + if (Namespace.empty()) return R->getName(); + return Namespace + "::" + R->getName(); +} + +/// getTarget - Return the current instance of the Target class. +/// +Record *TableGenBackend::getTarget(RecordKeeper &RC) const { + std::vector Targets = RC.getAllDerivedDefinitions("Target"); + + if (Targets.size() != 1) + throw std::string("ERROR: Multiple subclasses of Target defined!"); + return Targets[0]; +} From lattner at cs.uiuc.edu Tue Aug 5 23:33:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 23:33:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrInfoEmitter.cpp InstrInfoEmitter.h Message-ID: <200308060432.XAA02403@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrInfoEmitter.cpp updated: 1.2 -> 1.3 InstrInfoEmitter.h updated: 1.2 -> 1.3 --- Log message: Switch code over to being a TableGenBackend --- Diffs of the changes: Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.2 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.3 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.2 Sun Aug 3 16:57:51 2003 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Tue Aug 5 23:32:07 2003 @@ -8,27 +8,6 @@ #include "InstrInfoEmitter.h" #include "Record.h" -static void EmitSourceHeader(const std::string &Desc, std::ostream &o) { - o << "//===- TableGen'erated file -------------------------------------*-" - " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" - "d file, do not edit!\n//\n//===------------------------------------" - "----------------------------------===//\n\n"; -} - -static std::string getQualifiedName(Record *R) { - std::string Namespace = R->getValueAsString("Namespace"); - if (Namespace.empty()) return R->getName(); - return Namespace + "::" + R->getName(); -} - -static Record *getTarget(RecordKeeper &RC) { - std::vector Targets = RC.getAllDerivedDefinitions("Target"); - - if (Targets.size() != 1) - throw std::string("ERROR: Multiple subclasses of Target defined!"); - return Targets[0]; -} - // runEnums - Print out enum values for all of the instructions. void InstrInfoEmitter::runEnums(std::ostream &OS) { std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); @@ -38,7 +17,7 @@ std::string Namespace = Insts[0]->getValueAsString("Namespace"); - EmitSourceHeader("Target Instruction Enum Values", OS); + EmitSourceFileHeader("Target Instruction Enum Values", OS); if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; @@ -61,8 +40,8 @@ OS << "}\n"; } -static void printDefList(ListInit *LI, const std::string &Name, - std::ostream &OS) { +void InstrInfoEmitter::printDefList(ListInit *LI, const std::string &Name, + std::ostream &OS) const { OS << "static const unsigned " << Name << "[] = { "; for (unsigned j = 0, e = LI->getSize(); j != e; ++j) if (DefInit *DI = dynamic_cast(LI->getElement(j))) @@ -75,7 +54,7 @@ // run - Emit the main instruction description records for the target... void InstrInfoEmitter::run(std::ostream &OS) { - EmitSourceHeader("Target Instruction Descriptors", OS); + EmitSourceFileHeader("Target Instruction Descriptors", OS); Record *Target = getTarget(Records); const std::string &TargetName = Target->getName(); Record *InstrInfo = Target->getValueAsDef("InstructionSet"); Index: llvm/utils/TableGen/InstrInfoEmitter.h diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.2 llvm/utils/TableGen/InstrInfoEmitter.h:1.3 --- llvm/utils/TableGen/InstrInfoEmitter.h:1.2 Sun Aug 3 16:57:51 2003 +++ llvm/utils/TableGen/InstrInfoEmitter.h Tue Aug 5 23:32:07 2003 @@ -8,13 +8,12 @@ #ifndef INSTRINFO_EMITTER_H #define INSTRINFO_EMITTER_H -#include -class RecordKeeper; -class Record; +#include "TableGenBackend.h" class StringInit; class IntInit; +class ListInit; -class InstrInfoEmitter { +class InstrInfoEmitter : public TableGenBackend { RecordKeeper &Records; public: InstrInfoEmitter(RecordKeeper &R) : Records(R) {} @@ -25,6 +24,8 @@ // runEnums - Print out enum values for all of the instructions. void runEnums(std::ostream &OS); private: + void printDefList(ListInit *LI, const std::string &Name, + std::ostream &OS) const; void emitRecord(Record *R, unsigned Num, Record *InstrInfo, std::ostream &OS); void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift, std::ostream &OS); From lattner at cs.uiuc.edu Tue Aug 5 23:37:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 23:37:00 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.h RegisterInfoEmitter.cpp CodeEmitterGen.h CodeEmitterGen.cpp Message-ID: <200308060436.XAA03133@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.h updated: 1.3 -> 1.4 RegisterInfoEmitter.cpp updated: 1.7 -> 1.8 CodeEmitterGen.h updated: 1.7 -> 1.8 CodeEmitterGen.cpp updated: 1.24 -> 1.25 --- Log message: convert over to using TableGen backends --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.h diff -u llvm/utils/TableGen/RegisterInfoEmitter.h:1.3 llvm/utils/TableGen/RegisterInfoEmitter.h:1.4 --- llvm/utils/TableGen/RegisterInfoEmitter.h:1.3 Sun Aug 3 11:30:24 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.h Tue Aug 5 23:36:35 2003 @@ -9,10 +9,9 @@ #ifndef REGISTER_INFO_EMITTER_H #define REGISTER_INFO_EMITTER_H -#include -class RecordKeeper; +#include "TableGenBackend.h" -class RegisterInfoEmitter { +class RegisterInfoEmitter : public TableGenBackend { RecordKeeper &Records; public: RegisterInfoEmitter(RecordKeeper &R) : Records(R) {} Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.7 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.8 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.7 Sun Aug 3 17:14:50 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Tue Aug 5 23:36:35 2003 @@ -11,13 +11,6 @@ #include "Support/StringExtras.h" #include -static void EmitSourceHeader(const std::string &Desc, std::ostream &o) { - o << "//===- TableGen'erated file -------------------------------------*-" - " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" - "d file, do not edit!\n//\n//===------------------------------------" - "----------------------------------===//\n\n"; -} - // runEnums - Print out enum values for all of the registers. void RegisterInfoEmitter::runEnums(std::ostream &OS) { std::vector Registers = Records.getAllDerivedDefinitions("Register"); @@ -27,7 +20,7 @@ std::string Namespace = Registers[0]->getValueAsString("Namespace"); - EmitSourceHeader("Target Register Enum Values", OS); + EmitSourceFileHeader("Target Register Enum Values", OS); if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; @@ -41,22 +34,8 @@ OS << "}\n"; } -static Record *getTarget(RecordKeeper &RC) { - std::vector Targets = RC.getAllDerivedDefinitions("Target"); - - if (Targets.size() != 1) - throw std::string("ERROR: Multiple subclasses of Target defined!"); - return Targets[0]; -} - -static std::string getQualifiedName(Record *R) { - std::string Namespace = R->getValueAsString("Namespace"); - if (Namespace.empty()) return R->getName(); - return Namespace + "::" + R->getName(); -} - void RegisterInfoEmitter::runHeader(std::ostream &OS) { - EmitSourceHeader("Register Information Header Fragment", OS); + EmitSourceFileHeader("Register Information Header Fragment", OS); std::string ClassName = getTarget(Records)->getName() + "GenRegisterInfo"; @@ -72,7 +51,7 @@ // RegisterInfoEmitter::run - Main register file description emitter. // void RegisterInfoEmitter::run(std::ostream &OS) { - EmitSourceHeader("Register Information Source Fragment", OS); + EmitSourceFileHeader("Register Information Source Fragment", OS); // Start out by emitting each of the register classes... to do this, we build // a set of registers which belong to a register class, this is to ensure that Index: llvm/utils/TableGen/CodeEmitterGen.h diff -u llvm/utils/TableGen/CodeEmitterGen.h:1.7 llvm/utils/TableGen/CodeEmitterGen.h:1.8 --- llvm/utils/TableGen/CodeEmitterGen.h:1.7 Thu Jul 31 23:38:18 2003 +++ llvm/utils/TableGen/CodeEmitterGen.h Tue Aug 5 23:36:35 2003 @@ -7,11 +7,9 @@ #ifndef CODEMITTERGEN_H #define CODEMITTERGEN_H -#include -#include -class RecordKeeper; +#include "TableGenBackend.h" -class CodeEmitterGen { +class CodeEmitterGen : public TableGenBackend { RecordKeeper &Records; public: CodeEmitterGen(RecordKeeper &R) : Records(R) {} Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.24 llvm/utils/TableGen/CodeEmitterGen.cpp:1.25 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.24 Tue Aug 5 09:35:35 2003 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Tue Aug 5 23:36:35 2003 @@ -11,6 +11,8 @@ void CodeEmitterGen::run(std::ostream &o) { std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); + EmitSourceFileHeader("Machine Code Emitter", o); + std::string Namespace = "V9::"; std::string ClassName = "SparcV9CodeEmitter::"; From lattner at cs.uiuc.edu Tue Aug 5 23:49:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 5 23:49:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200308060448.XAA03672@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.17 -> 1.18 --- Log message: Add an instruction selector emitter skeleton --- Diffs of the changes: Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.17 llvm/utils/TableGen/TableGen.cpp:1.18 --- llvm/utils/TableGen/TableGen.cpp:1.17 Sun Aug 3 16:58:28 2003 +++ llvm/utils/TableGen/TableGen.cpp Tue Aug 5 23:47:56 2003 @@ -15,6 +15,7 @@ #include "CodeEmitterGen.h" #include "RegisterInfoEmitter.h" #include "InstrInfoEmitter.h" +#include "InstrSelectorEmitter.h" #include #include @@ -22,7 +23,7 @@ PrintRecords, GenEmitter, GenRegisterEnums, GenRegister, GenRegisterHeader, - GenInstrEnums, GenInstrs, + GenInstrEnums, GenInstrs, GenInstrSelector, PrintEnums, Parse, }; @@ -44,6 +45,8 @@ "Generate enum values for instructions"), clEnumValN(GenInstrs, "gen-instr-desc", "Generate instruction descriptions"), + clEnumValN(GenInstrSelector, "gen-instr-selector", + "Generate an instruction selector"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(Parse, "parse", @@ -440,7 +443,9 @@ case GenInstrs: InstrInfoEmitter(Records).run(*Out); break; - + case GenInstrSelector: + InstrSelectorEmitter(Records).run(*Out); + break; case PrintEnums: std::vector Recs = Records.getAllDerivedDefinitions(Class); for (unsigned i = 0, e = Recs.size(); i != e; ++i) From lattner at cs.uiuc.edu Wed Aug 6 00:40:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 00:40:03 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGenBackend.h Message-ID: <200308060539.AAA04718@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGenBackend.h updated: 1.2 -> 1.3 --- Log message: All good classes with virtual functions should have virtual dtors... --- Diffs of the changes: Index: llvm/utils/TableGen/TableGenBackend.h diff -u llvm/utils/TableGen/TableGenBackend.h:1.2 llvm/utils/TableGen/TableGenBackend.h:1.3 --- llvm/utils/TableGen/TableGenBackend.h:1.2 Tue Aug 5 23:31:26 2003 +++ llvm/utils/TableGen/TableGenBackend.h Wed Aug 6 00:39:03 2003 @@ -14,6 +14,7 @@ class RecordKeeper; struct TableGenBackend { + virtual ~TableGenBackend() {} // run - All TableGen backends should implement the run method, which should // be the main entry point. From lattner at cs.uiuc.edu Wed Aug 6 00:43:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 00:43:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308060542.AAA05787@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp added (r1.1) InstrSelectorEmitter.h added (r1.1) --- Log message: Initial support for an instruction selector emitter --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -c /dev/null llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.1 *** /dev/null Wed Aug 6 00:42:15 2003 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp Wed Aug 6 00:42:05 2003 *************** *** 0 **** --- 1,56 ---- + //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// + // + // This tablegen backend is responsible for emitting a description of the target + // instruction set for the code generator. + // + //===----------------------------------------------------------------------===// + + #include "InstrSelectorEmitter.h" + #include "Record.h" + + NodeType::ArgResultTypes NodeType::Translate(Record *R) { + const std::string &Name = R->getName(); + if (Name == "DNRT_void") return Void; + if (Name == "DNRT_val" || Name == "DNAT_val") return Val; + if (Name == "DNRT_arg0" || Name == "DNAT_arg0") return Arg0; + if (Name == "DNAT_ptr") return Ptr; + throw "Unknown DagNodeResult Type '" + Name + "'!"; + } + + + /// ProcessNodeTypes - Process all of the node types in the current + /// RecordKeeper, turning them into the more accessible NodeTypes data + /// structure. + /// + void InstrSelectorEmitter::ProcessNodeTypes() { + std::vector Nodes = Records.getAllDerivedDefinitions("DagNode"); + + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + Record *Node = Nodes[i]; + + // Translate the return type... + NodeType::ArgResultTypes RetTy = + NodeType::Translate(Node->getValueAsDef("RetType")); + + // Translate the arguments... + ListInit *Args = Node->getValueAsListInit("ArgTypes"); + std::vector ArgTypes; + + for (unsigned a = 0, e = Args->getSize(); a != e; ++a) + if (DefInit *DI = dynamic_cast(Args->getElement(a))) + ArgTypes.push_back(NodeType::Translate(DI->getDef())); + else + throw "In node " + Node->getName() + ", argument is not a Def!"; + + // Add the node type mapping now... + NodeTypes[Node] = NodeType(RetTy, ArgTypes); + } + } + + void InstrSelectorEmitter::run(std::ostream &OS) { + // Type-check all of the node types to ensure we "understand" them. + ProcessNodeTypes(); + + + + } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -c /dev/null llvm/utils/TableGen/InstrSelectorEmitter.h:1.1 *** /dev/null Wed Aug 6 00:42:15 2003 --- llvm/utils/TableGen/InstrSelectorEmitter.h Wed Aug 6 00:42:05 2003 *************** *** 0 **** --- 1,59 ---- + //===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===// + // + // This tablegen backend is responsible for emitting a description of the target + // instruction set for the code generator. + // + //===----------------------------------------------------------------------===// + + #ifndef INSTRSELECTOR_EMITTER_H + #define INSTRSELECTOR_EMITTER_H + + #include "TableGenBackend.h" + #include + #include + + struct NodeType { + enum ArgResultTypes { + // Both argument and return types... + Val, // A non-void type + Arg0, // Value matches the type of Arg0 + + // Return types + Void, // Tree node always returns void + + // Argument types + Ptr, // Tree node is the target argument type + }; + + ArgResultTypes ResultType; + std::vector ArgTypes; + + NodeType(ArgResultTypes RT, std::vector &AT) : ResultType(RT){ + AT.swap(ArgTypes); + } + + NodeType() : ResultType(Val) {} + NodeType(const NodeType &N) : ResultType(N.ResultType), ArgTypes(N.ArgTypes){} + + static ArgResultTypes Translate(Record *R); + + }; + + class InstrSelectorEmitter : public TableGenBackend { + RecordKeeper &Records; + + std::map NodeTypes; + public: + InstrSelectorEmitter(RecordKeeper &R) : Records(R) {} + + // run - Output the instruction set description, returning true on failure. + void run(std::ostream &OS); + + private: + // ProcessNodeTypes - Process all of the node types in the current + // RecordKeeper, turning them into the more accessible NodeTypes data + // structure. + void ProcessNodeTypes(); + }; + + #endif From lattner at cs.uiuc.edu Wed Aug 6 01:17:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 01:17:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308060616.BAA06518@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.1 -> 1.2 InstrSelectorEmitter.h updated: 1.1 -> 1.2 --- Log message: Add error checking code to the node type parser. Start the instruction pattern reader --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.1 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.2 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.1 Wed Aug 6 00:42:05 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Wed Aug 6 01:16:35 2003 @@ -24,7 +24,6 @@ /// void InstrSelectorEmitter::ProcessNodeTypes() { std::vector Nodes = Records.getAllDerivedDefinitions("DagNode"); - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { Record *Node = Nodes[i]; @@ -36,21 +35,48 @@ ListInit *Args = Node->getValueAsListInit("ArgTypes"); std::vector ArgTypes; - for (unsigned a = 0, e = Args->getSize(); a != e; ++a) + for (unsigned a = 0, e = Args->getSize(); a != e; ++a) { if (DefInit *DI = dynamic_cast(Args->getElement(a))) ArgTypes.push_back(NodeType::Translate(DI->getDef())); else throw "In node " + Node->getName() + ", argument is not a Def!"; + if (a == 0 && ArgTypes.back() == NodeType::Arg0) + throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!"; + if (ArgTypes.back() == NodeType::Void) + throw "In node " + Node->getName() + ", args cannot be void type!"; + } + if (RetTy == NodeType::Arg0 && Args->getSize() == 0) + throw "In node " + Node->getName() + + ", invalid return type for nullary node!"; + // Add the node type mapping now... NodeTypes[Node] = NodeType(RetTy, ArgTypes); } } +/// ProcessInstructionPatterns - Read in all subclasses of Instruction, and +/// process those with a useful Pattern field. +/// +void InstrSelectorEmitter::ProcessInstructionPatterns() { + std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); + for (unsigned i = 0, e = Insts.size(); i != e; ++i) { + Record *Inst = Insts[i]; + if (DagInit *PatternInit = + dynamic_cast(Inst->getValueInit("Pattern"))) { + + } + } +} + + void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. ProcessNodeTypes(); - + // Read all of the instruction patterns in... + ProcessInstructionPatterns(); + + // Read all of the Expander patterns in... } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.1 llvm/utils/TableGen/InstrSelectorEmitter.h:1.2 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.1 Wed Aug 6 00:42:05 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Wed Aug 6 01:16:35 2003 @@ -17,12 +17,10 @@ // Both argument and return types... Val, // A non-void type Arg0, // Value matches the type of Arg0 + Ptr, // Tree node is the type of the target pointer // Return types Void, // Tree node always returns void - - // Argument types - Ptr, // Tree node is the target argument type }; ArgResultTypes ResultType; @@ -36,7 +34,6 @@ NodeType(const NodeType &N) : ResultType(N.ResultType), ArgTypes(N.ArgTypes){} static ArgResultTypes Translate(Record *R); - }; class InstrSelectorEmitter : public TableGenBackend { @@ -54,6 +51,10 @@ // RecordKeeper, turning them into the more accessible NodeTypes data // structure. void ProcessNodeTypes(); + + // ProcessInstructionPatterns - Read in all subclasses of Instruction, and + // process those with a useful Pattern field. + void ProcessInstructionPatterns(); }; #endif From vadve at cs.uiuc.edu Wed Aug 6 01:58:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 01:58:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2003-08-05-CastFPToUint.c Message-ID: <200308060657.BAA15827@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2003-08-05-CastFPToUint.c added (r1.1) --- Log message: Test FP to small unsigned value conversions. --- Diffs of the changes: Index: llvm/test/Programs/SingleSource/UnitTests/2003-08-05-CastFPToUint.c diff -c /dev/null llvm/test/Programs/SingleSource/UnitTests/2003-08-05-CastFPToUint.c:1.1 *** /dev/null Wed Aug 6 01:57:51 2003 --- llvm/test/Programs/SingleSource/UnitTests/2003-08-05-CastFPToUint.c Wed Aug 6 01:57:40 2003 *************** *** 0 **** --- 1,27 ---- + /* + * This test checks conversions from floating point values to small + * unsigned integer values. Conversions to uint32_t need special handling + * on Sparc V9, which only has FP-to-int32_t and FP-to-int64_t instructions. + */ + + #include + #include + + static double getDC(), getDS(), getDI(); + + int + main(int argc, char** argv) { + double DC = getDC(); + double DS = getDS(); + double DI = getDI(); + unsigned char uc = (unsigned char ) DC; + unsigned short us = (unsigned short) DS; + unsigned int ui = (unsigned int ) DI; + printf("DC = %lf, DS = %lf, DI = %lf\n", DC, DS, DI); + printf("uc = %u, us = %u, ui = %u\n", uc, us, ui); + return 0; + } + + static double getDC() { return (double) ((1L << 8) - 16L ); } + static double getDS() { return (double) ((1LL << 16) - 16L ); } + static double getDI() { return (double) ((1LL << 32) - 16LL); } From lattner at cs.uiuc.edu Wed Aug 6 10:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 10:32:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308061531.KAA13734@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.14 -> 1.15 --- Log message: Start adding usefulness to the DAG node definitions, add a new Expander class --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.14 llvm/lib/Target/Target.td:1.15 --- llvm/lib/Target/Target.td:1.14 Mon Aug 4 16:07:37 2003 +++ llvm/lib/Target/Target.td Wed Aug 6 10:31:02 2003 @@ -18,12 +18,9 @@ def i16 : ValueType<16>; // 16-bit integer value def i32 : ValueType<32>; // 32-bit integer value def i64 : ValueType<64>; // 64-bit integer value -def i128 : ValueType<128>; // 128-bit integer value def f32 : ValueType<32>; // 32-bit floating point value def f64 : ValueType<64>; // 64-bit floating point value def f80 : ValueType<80>; // 80-bit floating point value -def f128 : ValueType<128>; // 128-bit floating point value - //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target @@ -109,6 +106,12 @@ dag Pattern; } +class Expander result> { + dag Pattern = pattern; + list Result = result; +} + + // InstrInfo - This class should only be instantiated once to provide parameters // which are global to the the target machine. // @@ -144,14 +147,48 @@ //===----------------------------------------------------------------------===// // DAG node definitions used by the instruction selector... // -def set; // FIXME: these are subject to substantial change -def plus; -def minus; -def mult; -def div; -def udiv; -def mod; -def umod; -def imm8; -def imm16; -def imm32; +class DagNodeResultType; +def DNRT_void : DagNodeResultType; // Tree node always returns void +def DNRT_val : DagNodeResultType; // A non-void type +def DNRT_arg0 : DagNodeResultType; // Tree node returns same type as Arg0 + +class DagNodeArgType; +def DNAT_val : DagNodeArgType; // Any value +def DNAT_arg0 : DagNodeArgType; // Same as for arg #0 +def DNAT_ptr : DagNodeArgType; // Returns the target pointer type + +class DagNode args> { + DagNodeResultType RetType = ret; + list ArgTypes = args; + string EnumName = ?; +} + +// BuiltinDagNodes are built into the instruction selector and correspond to +// enum values. +class BuiltinDagNode Args, + string Ename> : DagNode { + let EnumName = Ename; +} + +// Magic nodes... +def set : DagNode; + +// Terminals... +def imm : DagNode; + +// Arithmetic... +def plus : BuiltinDagNode; +def minus : BuiltinDagNode; +//def mult : DagNode<2, DNRT_arg0>; +//def div : DagNode<2, DNRT_arg0>; +//def udiv : DagNode<2, DNRT_arg0>; +//def mod : DagNode<2, DNRT_arg0>; +//def umod : DagNode<2, DNRT_arg0>; + +//def load : DagNode<1, DNRT_val>; +//def store : DagNode<2, DNRT_Void>; + +// Other... +def ret : BuiltinDagNode; +def retvoid : BuiltinDagNode; + From lattner at cs.uiuc.edu Wed Aug 6 10:32:12 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 10:32:12 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200308061531.KAA13753@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.5 -> 1.6 --- Log message: add a pattern for RET, immediates no longer need to be explicitly typed --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.5 llvm/lib/Target/X86/X86InstrInfo.td:1.6 --- llvm/lib/Target/X86/X86InstrInfo.td:1.5 Mon Aug 4 19:48:46 2003 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Aug 6 10:31:35 2003 @@ -115,7 +115,7 @@ // Return instruction... let isTerminator = 1, isReturn = 1 in - def RET : X86Inst<"ret", 0xC3, RawFrm, NoArg>; + def RET : X86Inst<"ret", 0xC3, RawFrm, NoArg>, Pattern<(retvoid)>; // All branches are RawFrm, Void, Branch, and Terminators let isBranch = 1, isTerminator = 1 in @@ -167,9 +167,9 @@ def MOVrr8 : X86Inst<"mov", 0x88, MRMDestReg, Arg8>, Pattern<(set R8 , R8 )>; def MOVrr16 : X86Inst<"mov", 0x89, MRMDestReg, Arg16>, OpSize, Pattern<(set R16, R16)>; def MOVrr32 : X86Inst<"mov", 0x89, MRMDestReg, Arg32>, Pattern<(set R32, R32)>; -def MOVir8 : X86Inst<"mov", 0xB0, AddRegFrm , Arg8>, Pattern<(set R8 , imm8 )>; -def MOVir16 : X86Inst<"mov", 0xB8, AddRegFrm , Arg16>, OpSize, Pattern<(set R16, imm16)>; -def MOVir32 : X86Inst<"mov", 0xB8, AddRegFrm , Arg32>, Pattern<(set R32, imm32)>; +def MOVir8 : X86Inst<"mov", 0xB0, AddRegFrm , Arg8>, Pattern<(set R8 , imm )>; +def MOVir16 : X86Inst<"mov", 0xB8, AddRegFrm , Arg16>, OpSize, Pattern<(set R16, imm)>; +def MOVir32 : X86Inst<"mov", 0xB8, AddRegFrm , Arg32>, Pattern<(set R32, imm)>; def MOVim8 : X86Inst<"mov", 0xC6, MRMS0m , Arg8>; // [mem] = imm8 def MOVim16 : X86Inst<"mov", 0xC7, MRMS0m , Arg16>, OpSize; // [mem] = imm16 def MOVim32 : X86Inst<"mov", 0xC7, MRMS0m , Arg32>; // [mem] = imm32 @@ -220,18 +220,18 @@ def ADDrr8 : I2A8 <"add", 0x00, MRMDestReg>, Pattern<(set R8 , (plus R8 , R8 ))>; def ADDrr16 : I2A16<"add", 0x01, MRMDestReg>, OpSize, Pattern<(set R16, (plus R16, R16))>; def ADDrr32 : I2A32<"add", 0x01, MRMDestReg>, Pattern<(set R32, (plus R32, R32))>; -def ADDri8 : I2A8 <"add", 0x80, MRMS0r >, Pattern<(set R8 , (plus R8 , imm8 ))>; -def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize, Pattern<(set R16, (plus R16, imm16))>; -def ADDri32 : I2A32<"add", 0x81, MRMS0r >, Pattern<(set R32, (plus R32, imm32))>; +def ADDri8 : I2A8 <"add", 0x80, MRMS0r >, Pattern<(set R8 , (plus R8 , imm))>; +def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize, Pattern<(set R16, (plus R16, imm))>; +def ADDri32 : I2A32<"add", 0x81, MRMS0r >, Pattern<(set R32, (plus R32, imm))>; def ADCrr32 : I2A32<"adc", 0x11, MRMDestReg>; // R32 += imm32+Carry def SUBrr8 : I2A8 <"sub", 0x28, MRMDestReg>, Pattern<(set R8 , (minus R8 , R8 ))>; def SUBrr16 : I2A16<"sub", 0x29, MRMDestReg>, OpSize, Pattern<(set R16, (minus R16, R16))>; def SUBrr32 : I2A32<"sub", 0x29, MRMDestReg>, Pattern<(set R32, (minus R32, R32))>; -def SUBri8 : I2A8 <"sub", 0x80, MRMS5r >, Pattern<(set R8 , (minus R8 , imm8 ))>; -def SUBri16 : I2A16<"sub", 0x81, MRMS5r >, OpSize, Pattern<(set R16, (minus R16, imm16))>; -def SUBri32 : I2A32<"sub", 0x81, MRMS5r >, Pattern<(set R32, (minus R32, imm32))>; +def SUBri8 : I2A8 <"sub", 0x80, MRMS5r >, Pattern<(set R8 , (minus R8 , imm))>; +def SUBri16 : I2A16<"sub", 0x81, MRMS5r >, OpSize, Pattern<(set R16, (minus R16, imm))>; +def SUBri32 : I2A32<"sub", 0x81, MRMS5r >, Pattern<(set R32, (minus R32, imm))>; def SBBrr32 : I2A32<"sbb", 0x19, MRMDestReg>; // R32 -= R32+Carry From lattner at cs.uiuc.edu Wed Aug 6 10:33:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 10:33:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.td X86InstrInfo.h Message-ID: <200308061532.KAA13779@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.td updated: 1.5 -> 1.6 X86InstrInfo.h updated: 1.25 -> 1.26 --- Log message: Completely eliminate the isVoid TSFlag, shifting over all other fields --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.5 llvm/lib/Target/X86/X86.td:1.6 --- llvm/lib/Target/X86/X86.td:1.5 Mon Aug 4 00:11:37 2003 +++ llvm/lib/Target/X86/X86.td Wed Aug 6 10:32:20 2003 @@ -26,10 +26,10 @@ // Define how we want to layout our TargetSpecific information field... This // should be kept up-to-date with the fields in the X86InstrInfo.h file. - let TSFlagsFields = ["FormBits", "hasOpSizePrefix", "Prefix", - "TypeBits", "FPFormBits", "printImplicitUses", "Opcode"]; - let TSFlagsShifts = [ 0, 6, 7, - 11, 14, 17, 18]; + let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "TypeBits", + "FPFormBits", "printImplicitUses", "Opcode"]; + let TSFlagsShifts = [ 0, 5, 6, 10, + 13, 16, 17]; } def X86 : Target { Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.25 llvm/lib/Target/X86/X86InstrInfo.h:1.26 --- llvm/lib/Target/X86/X86InstrInfo.h:1.25 Sun Aug 3 16:56:22 2003 +++ llvm/lib/Target/X86/X86InstrInfo.h Wed Aug 6 10:32:20 2003 @@ -71,74 +71,75 @@ //===------------------------------------------------------------------===// // Actual flags... - /// Void - Set if this instruction produces no value - Void = 1 << 5, - // OpSize - Set if this instruction requires an operand size prefix (0x66), // which most often indicates that the instruction operates on 16 bit data // instead of 32 bit data. - OpSize = 1 << 6, + OpSize = 1 << 5, // Op0Mask - There are several prefix bytes that are used to form two byte // opcodes. These are currently 0x0F, and 0xD8-0xDF. This mask is used to // obtain the setting of this field. If no bits in this field is set, there // is no prefix byte for obtaining a multibyte opcode. // - Op0Mask = 0xF << 7, - Op0Shift = 7, + Op0Shift = 6, + Op0Mask = 0xF << Op0Shift, // TB - TwoByte - Set if this instruction has a two byte opcode, which // starts with a 0x0F byte before the real opcode. - TB = 1 << 7, + TB = 1 << Op0Shift, // D8-DF - These escape opcodes are used by the floating point unit. These // values must remain sequential. - D8 = 2 << 7, D9 = 3 << 7, DA = 4 << 7, DB = 5 << 7, - DC = 6 << 7, DD = 7 << 7, DE = 8 << 7, DF = 9 << 7, + D8 = 2 << Op0Shift, D9 = 3 << Op0Shift, + DA = 4 << Op0Shift, DB = 5 << Op0Shift, + DC = 6 << Op0Shift, DD = 7 << Op0Shift, + DE = 8 << Op0Shift, DF = 9 << Op0Shift, //===------------------------------------------------------------------===// // This three-bit field describes the size of a memory operand. Zero is // unused so that we can tell if we forgot to set a value. - Arg8 = 1 << 11, - Arg16 = 2 << 11, - Arg32 = 3 << 11, - Arg64 = 4 << 11, // 64 bit int argument for FILD64 - ArgF32 = 5 << 11, - ArgF64 = 6 << 11, - ArgF80 = 7 << 11, - ArgMask = 7 << 11, + ArgShift = 10, + ArgMask = 7 << ArgShift, + Arg8 = 1 << ArgShift, + Arg16 = 2 << ArgShift, + Arg32 = 3 << ArgShift, + Arg64 = 4 << ArgShift, // 64 bit int argument for FILD64 + ArgF32 = 5 << ArgShift, + ArgF64 = 6 << ArgShift, + ArgF80 = 7 << ArgShift, //===------------------------------------------------------------------===// // FP Instruction Classification... Zero is non-fp instruction. + // FPTypeMask - Mask for all of the FP types... + FPTypeShift = 13, + FPTypeMask = 7 << FPTypeShift, + // ZeroArgFP - 0 arg FP instruction which implicitly pushes ST(0), f.e. fld0 - ZeroArgFP = 1 << 14, + ZeroArgFP = 1 << FPTypeShift, // OneArgFP - 1 arg FP instructions which implicitly read ST(0), such as fst - OneArgFP = 2 << 14, + OneArgFP = 2 << FPTypeShift, // OneArgFPRW - 1 arg FP instruction which implicitly read ST(0) and write a // result back to ST(0). For example, fcos, fsqrt, etc. // - OneArgFPRW = 3 << 14, + OneArgFPRW = 3 << FPTypeShift, // TwoArgFP - 2 arg FP instructions which implicitly read ST(0), and an // explicit argument, storing the result to either ST(0) or the implicit // argument. For example: fadd, fsub, fmul, etc... - TwoArgFP = 4 << 14, + TwoArgFP = 4 << FPTypeShift, // SpecialFP - Special instruction forms. Dispatch by opcode explicitly. - SpecialFP = 5 << 14, - - // FPTypeMask - Mask for all of the FP types... - FPTypeMask = 7 << 14, + SpecialFP = 5 << FPTypeShift, // PrintImplUses - Print out implicit uses in the assembly output. - PrintImplUses = 1 << 17, + PrintImplUses = 1 << 16, - OpcodeMask = 0xFF << 18, - OpcodeShift = 18, - // Bits 26 -> 31 are unused + OpcodeShift = 17, + OpcodeMask = 0xFF << OpcodeShift, + // Bits 25 -> 31 are unused }; } From lattner at cs.uiuc.edu Wed Aug 6 10:41:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 10:41:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/OpenProjects.html Message-ID: <200308061540.KAA19028@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: OpenProjects.html updated: 1.8 -> 1.9 --- Log message: Loop unroller doesn't necessarily need to be profile driven --- Diffs of the changes: Index: llvm/www/docs/OpenProjects.html diff -u llvm/www/docs/OpenProjects.html:1.8 llvm/www/docs/OpenProjects.html:1.9 --- llvm/www/docs/OpenProjects.html:1.8 Fri Jul 25 13:05:38 2003 +++ llvm/www/docs/OpenProjects.html Wed Aug 6 10:40:37 2003 @@ -242,6 +242,7 @@
    • Value range propagation pass
    • Implement a tail recursion elimination pass
    • Implement an unswitching pass +
    • Write a loop unroller, with a simple heuristic for when to unroll @@ -279,6 +280,6 @@
      Chris Lattner
      -Last modified: Fri Jul 25 13:04:03 CDT 2003 +Last modified: Wed Aug 6 10:40:05 CDT 2003 From lattner at cs.uiuc.edu Wed Aug 6 11:04:06 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 11:04:06 2003 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.pl Message-ID: <200308061603.LAA15313@apoc.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.pl updated: 1.17 -> 1.18 --- Log message: Sort the file lists --- Diffs of the changes: Index: llvm/utils/NightlyTest.pl diff -u llvm/utils/NightlyTest.pl:1.17 llvm/utils/NightlyTest.pl:1.18 --- llvm/utils/NightlyTest.pl:1.17 Thu Jul 31 11:05:11 2003 +++ llvm/utils/NightlyTest.pl Wed Aug 6 11:02:50 2003 @@ -248,9 +248,9 @@ my $UserCommitList = join "\n", keys %UsersCommitted; my $UserUpdateList = join "\n", keys %UsersUpdated; -my $AddedFilesList = AddPreTag join "\n", keys %AddedFiles; -my $ModifiedFilesList = AddPreTag join "\n", keys %ModifiedFiles; -my $RemovedFilesList = AddPreTag join "\n", keys %RemovedFiles; +my $AddedFilesList = AddPreTag join "\n", sort keys %AddedFiles; +my $ModifiedFilesList = AddPreTag join "\n", sort keys %ModifiedFiles; +my $RemovedFilesList = AddPreTag join "\n", sort keys %RemovedFiles; my $TestError = 1; my $ProgramsTable; From brukman at cs.uiuc.edu Wed Aug 6 11:21:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Aug 6 11:21:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp SparcV9CodeEmitter.h Message-ID: <200308061620.LAA10529@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcV9CodeEmitter.cpp updated: 1.24 -> 1.25 SparcV9CodeEmitter.h updated: 1.13 -> 1.14 --- Log message: SparcV9CodeEmitter.cpp: * Doxygen-ified comments * Added capability to make far calls (i.e., beyond 30 bits in CALL instr) which implies that we need to delete function references that were added by the call to addFunctionReference() because the actual call instruction is 10 instructions away (thanks to 64-bit address construction) * Cleaned up code that generates far jumps by using an array+loop SparcV9CodeEmitter.h: * Explained more of the side-effects of emitFarCall() --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.24 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.25 --- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.24 Fri Aug 1 17:19:03 2003 +++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Wed Aug 6 11:20:22 2003 @@ -34,18 +34,34 @@ SparcV9CodeEmitter &SparcV9; MachineCodeEmitter &MCE; - // LazyCodeGenMap - Keep track of call sites for functions that are to be - // lazily resolved. + /// LazyCodeGenMap - Keep track of call sites for functions that are to be + /// lazily resolved. + /// std::map LazyCodeGenMap; - // LazyResolverMap - Keep track of the lazy resolver created for a - // particular function so that we can reuse them if necessary. + /// LazyResolverMap - Keep track of the lazy resolver created for a + /// particular function so that we can reuse them if necessary. + /// std::map LazyResolverMap; + + public: + enum CallType { ShortCall, FarCall }; + + private: + /// We need to keep track of whether we used a simple call or a far call + /// (many instructions) in sequence. This means we need to keep track of + /// what type of stub we generate. + static std::map LazyCallFlavor; + public: JITResolver(SparcV9CodeEmitter &V9, MachineCodeEmitter &mce) : SparcV9(V9), MCE(mce) {} uint64_t getLazyResolver(Function *F); uint64_t addFunctionReference(uint64_t Address, Function *F); + void deleteFunctionReference(uint64_t Address); + void addCallFlavor(uint64_t Address, CallType Flavor) { + LazyCallFlavor[Address] = Flavor; + } // Utility functions for accessing data from static callback uint64_t getCurrentPCValue() { @@ -65,6 +81,7 @@ }; JITResolver *TheJITResolver; + std::map JITResolver::LazyCallFlavor; } /// addFunctionReference - This method is called when we need to emit the @@ -73,10 +90,21 @@ /// keep track of where we are. /// uint64_t JITResolver::addFunctionReference(uint64_t Address, Function *F) { - LazyCodeGenMap[Address] = F; + LazyCodeGenMap[Address] = F; return (intptr_t)&JITResolver::CompilationCallback; } +/// deleteFunctionReference - If we are emitting a far call, we already added a +/// reference to the function, but it is now incorrect, since the address to the +/// JIT resolver is too far away to be a simple call instruction. This is used +/// to remove the address from the map. +/// +void JITResolver::deleteFunctionReference(uint64_t Address) { + std::map::iterator I = LazyCodeGenMap.find(Address); + assert(I != LazyCodeGenMap.end() && "Not in map!"); + LazyCodeGenMap.erase(I); +} + uint64_t JITResolver::resolveFunctionReference(uint64_t RetAddr) { std::map::iterator I = LazyCodeGenMap.find(RetAddr); assert(I != LazyCodeGenMap.end() && "Not in map!"); @@ -102,80 +130,42 @@ i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0; - // - // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 - // - - // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp - MachineInstr *STX = BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*STX); - delete STX; - Addr += 4; - - // stx %i2, [%sp + 2127] ;; save %i2 to the stack - STX = BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*STX); - delete STX; - Addr += 4; - - // - // Get address to branch into %i2, using %i1 as a temporary - // + MachineInstr* BinaryCode[] = { + // + // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 + // + // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp + BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119), + // stx %i2, [%sp + 2127] ;; save %i2 to the stack + BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127), + // + // Get address to branch into %i2, using %i1 as a temporary + // + // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1 + BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1), + // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1 + BuildMI(V9::ORi, 3).addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1), + // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word + BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1), + // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg + BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2), + // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2 + BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2), + // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2 + BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2), + // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72 + BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1), + // jmpl %i2, %g0, %g0 ;; indirect branch on %i2 + BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(g0), + // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80 + BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2) + }; - // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1 - MachineInstr *SH = BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*SH); - delete SH; - Addr += 4; - - // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1 - MachineInstr *OR = BuildMI(V9::ORi, 3) - .addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*OR); - delete OR; - Addr += 4; - - // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word - MachineInstr *SL = BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*SL); - delete SL; - Addr += 4; - - // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg - SH = BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*SH); - delete SH; - Addr += 4; - - // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2 - OR = BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*OR); - delete OR; - Addr += 4; - - // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2 - OR = BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*OR); - delete OR; - Addr += 4; - - // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72 - MachineInstr *LDX = BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*LDX); - delete LDX; - Addr += 4; - - // jmpl %i2, %g0, %g0 ;; indirect branch on %i2 - MachineInstr *J = BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(g0); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*J); - delete J; - Addr += 4; - - // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80 - LDX = BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2); - *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*LDX); - delete LDX; - Addr += 4; + for (unsigned i=0, e=sizeof(BinaryCode)/sizeof(BinaryCode[0]); i!=e; ++i) { + *((unsigned*)(intptr_t)Addr) = getBinaryCodeForInstr(*BinaryCode[i]); + delete BinaryCode[i]; + Addr += 4; + } return Addr; } @@ -184,86 +174,57 @@ uint64_t CameFrom = (uint64_t)(intptr_t)__builtin_return_address(0); int64_t Target = (int64_t)TheJITResolver->resolveFunctionReference(CameFrom); DEBUG(std::cerr << "In callback! Addr=0x" << std::hex << CameFrom << "\n"); - - // Rewrite the call target... so that we don't fault every time we execute - // the call. -#if 0 - int64_t RealCallTarget = (int64_t) - ((NewVal - TheJITResolver->getCurrentPCValue()) >> 4); - if (RealCallTarget >= (1<<22) || RealCallTarget <= -(1<<22)) { - std::cerr << "Address out of bounds for 22bit BA: " << RealCallTarget<<"\n"; - abort(); - } +#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) + register int64_t returnAddr; + __asm__ __volatile__ ("add %%i7, %%g0, %0" : "=r" (returnAddr) : ); + DEBUG(std::cerr << "Read i7 (return addr) = " + << std::hex << returnAddr << ", value: " + << std::hex << *(unsigned*)returnAddr << "\n"); #endif - //uint64_t CurrPC = TheJITResolver->getCurrentPCValue(); - // we will insert 9 instructions before we do the actual jump - //int64_t NewTarget = (NewVal - 9*4 - InstAddr) >> 2; - - static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2, - i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6, - o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0; - - // Subtract 4 to overwrite the 'save' that's there now - uint64_t InstAddr = CameFrom-4; - - InstAddr = TheJITResolver->insertFarJumpAtAddr(Target, InstAddr); - - // CODE SHOULD NEVER GO PAST THIS LOAD!! The real function should return to - // the original caller, not here!! - - // FIXME: add call 0 to make sure?!? - - // =============== THE REAL STUB ENDS HERE ========================= - - // What follows below is one-time restore code, because this callback may be - // changing registers in unpredictible ways. However, since it is executed - // only once per function (after the function is resolved, the callback is no - // longer in the path), this has to be done only once. + // Rewrite the call target so that we don't fault every time we execute it. // - // Thus, it is after the regular stub code. The call back returns to THIS - // point, but every other call to the target function will execute the code - // above. Hence, this code is one-time use. - uint64_t OneTimeRestore = InstAddr; - - // restore %g0, 0, %g0 - //MachineInstr *R = BuildMI(V9::RESTOREi, 3).addMReg(g0).addSImm(0) - // .addMReg(g0, MOTy::Def); - //*((unsigned*)(intptr_t)InstAddr)=TheJITResolver->getBinaryCodeForInstr(*R); - //delete R; + static const unsigned o6 = SparcIntRegClass::o6; - // FIXME: BuildMI() above crashes. Encode the instruction directly. - // restore %g0, 0, %g0 - *((unsigned*)(intptr_t)InstAddr) = 0x81e82000U; - InstAddr += 4; - - InstAddr = TheJITResolver->insertFarJumpAtAddr(Target, InstAddr); + // Subtract enough to overwrite up to the 'save' instruction + // This depends on whether we made a short call (1 instruction) to the + // farCall (10 instructions) + uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 40; + uint64_t CodeBegin = CameFrom - Offset; + + // Make sure that what we're about to overwrite is indeed "save" + MachineInstr *SV = BuildMI(V9::SAVEi, 3).addReg(o6).addSImm(-192).addReg(o6); + unsigned SaveInst = TheJITResolver->getBinaryCodeForInstr(*SV); + delete SV; + unsigned CodeInMem = *(unsigned*)(intptr_t)CodeBegin; + assert(CodeInMem == SaveInst && "About to overwrite smthg not a save instr!"); + DEBUG(std::cerr << "Emitting a far jump to 0x" << std::hex << Target << "\n"); + TheJITResolver->insertFarJumpAtAddr(Target, CodeBegin); // FIXME: if the target function is close enough to fit into the 19bit disp of // BA, we should use this version, as its much cheaper to generate. - /* - MachineInstr *MI = BuildMI(V9::BA, 1).addSImm(RealCallTarget); - *((unsigned*)(intptr_t)InstAddr) = TheJITResolver->getBinaryCodeForInstr(*MI); - delete MI; - InstAddr += 4; - - // Add another NOP - MachineInstr *Nop = BuildMI(V9::NOP, 0); - *((unsigned*)(intptr_t)InstAddr)=TheJITResolver->getBinaryCodeForInstr(*Nop); - delete Nop; +#if 0 + uint64_t InstAddr = CodeBegin; + // ba + MachineInstr *MI = BuildMI(V9::BA, 1).addSImm(Target); + *((unsigned*)(intptr_t)InstAddr)=TheJITResolver->getBinaryCodeForInstr(*MI); InstAddr += 4; + delete MI; - MachineInstr *BA = BuildMI(V9::BA, 1).addSImm(RealCallTarget-2); - *((unsigned*)(intptr_t)InstAddr) = TheJITResolver->getBinaryCodeForInstr(*BA); - delete BA; - */ + // nop + MI = BuildMI(V9::NOP, 0); + *((unsigned*)(intptr_t))=TheJITResolver->getBinaryCodeForInstr(*Nop); + delete MI; +#endif - // Change the return address to reexecute the call instruction... + // Change the return address to reexecute the restore, then the jump // The return address is really %o7, but will disappear after this function // returns, and the register windows are rotated away. #if defined(sparc) || defined(__sparc__) || defined(__sparcv9) - __asm__ __volatile__ ("or %%g0, %0, %%i7" : : "r" (OneTimeRestore-8)); + __asm__ __volatile__ ("sub %%i7, %0, %%i7" : : "r" (Offset+12)); + DEBUG(std::cerr << "Callback setting return addr to " + << std::hex << (CameFrom-Offset-12) << "\n"); #endif } @@ -274,12 +235,19 @@ /// directly. /// uint64_t JITResolver::emitStubForFunction(Function *F) { - MCE.startFunctionStub(*F, 6); + MCE.startFunctionStub(*F, 20); DEBUG(std::cerr << "Emitting stub at addr: 0x" << std::hex << MCE.getCurrentPCValue() << "\n"); - unsigned o6 = SparcIntRegClass::o6; + unsigned o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0; + + // restore %g0, 0, %g0 + MachineInstr *R = BuildMI(V9::RESTOREi, 3).addMReg(g0).addSImm(0) + .addMReg(g0, MOTy::Def); + SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*R)); + delete R; + // save %sp, -192, %sp MachineInstr *SV = BuildMI(V9::SAVEi, 3).addReg(o6).addSImm(-192).addReg(o6); SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*SV)); @@ -288,8 +256,12 @@ int64_t CurrPC = MCE.getCurrentPCValue(); int64_t Addr = (int64_t)addFunctionReference(CurrPC, F); int64_t CallTarget = (Addr-CurrPC) >> 2; - if (CallTarget >= (1 << 30) || CallTarget <= -(1 << 30)) { - SparcV9.emitFarCall(Addr); + //if (CallTarget >= (1 << 29) || CallTarget <= -(1 << 29)) { + // Since this is a far call, the actual address of the call is shifted + // by the number of instructions it takes to calculate the exact address + deleteFunctionReference(CurrPC); + SparcV9.emitFarCall(Addr, F); +#if 0 } else { // call CallTarget ;; invoke the callback MachineInstr *Call = BuildMI(V9::CALL, 1).addSImm(CallTarget); @@ -300,10 +272,13 @@ MachineInstr *Nop = BuildMI(V9::NOP, 0); SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Nop)); delete Nop; + + addCallFlavor(CurrPC, ShortCall); } +#endif SparcV9.emitWord(0xDEADBEEF); // marker so that we know it's really a stub - return (intptr_t)MCE.finishFunctionStub(*F); + return (intptr_t)MCE.finishFunctionStub(*F)+4; /* 1 instr past the restore */ } @@ -391,74 +366,54 @@ // WARNING: if the call used the delay slot to do meaningful work, that's not // being accounted for, and the behavior will be incorrect!! -inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target) { +inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target, Function *F) { static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2, i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6, o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0; - // - // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 - // - - // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp - MachineInstr *STX = BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119); - emitWord(getBinaryCodeForInstr(*STX)); - delete STX; - - // stx %i2, [%sp + 2127] ;; save %i2 to the stack - STX = BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127); - emitWord(getBinaryCodeForInstr(*STX)); - delete STX; + MachineInstr* BinaryCode[] = { + // + // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 + // + // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp + BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119), + // stx %i2, [%sp + 2127] ;; save %i2 to the stack + BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127), + // + // Get address to branch into %i2, using %i1 as a temporary + // + // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1 + BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1), + // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1 + BuildMI(V9::ORi, 3).addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1), + // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word + BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1), + // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg + BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2), + // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2 + BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2), + // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2 + BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2), + // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72 + BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1), + // jmpl %i2, %g0, %o7 ;; indirect call on %i2 + BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(o7), + // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80 + BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2) + }; - // - // Get address to branch into %i2, using %i1 as a temporary - // + for (unsigned i=0, e=sizeof(BinaryCode)/sizeof(BinaryCode[0]); i!=e; ++i) { + // This is where we save the return address in the LazyResolverMap!! + if (i == 9 && F != 0) { // Do this right before the JMPL + uint64_t CurrPC = MCE.getCurrentPCValue(); + TheJITResolver->addFunctionReference(CurrPC, F); + // Remember that this is a far call, to subtract appropriate offset later + TheJITResolver->addCallFlavor(CurrPC, JITResolver::FarCall); + } - // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1 - MachineInstr *SH = BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1); - emitWord(getBinaryCodeForInstr(*SH)); - delete SH; - - // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1 - MachineInstr *OR = BuildMI(V9::ORi, 3) - .addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1); - emitWord(getBinaryCodeForInstr(*OR)); - delete OR; - - // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word - MachineInstr *SL = BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1); - emitWord(getBinaryCodeForInstr(*SL)); - delete SL; - - // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg - SH = BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2); - emitWord(getBinaryCodeForInstr(*SH)); - delete SH; - - // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2 - OR = BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2); - emitWord(getBinaryCodeForInstr(*OR)); - delete OR; - - // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2 - OR = BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2); - emitWord(getBinaryCodeForInstr(*OR)); - delete OR; - - // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72 - MachineInstr *LDX = BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1); - emitWord(getBinaryCodeForInstr(*LDX)); - delete LDX; - - // jmpl %i2, %g0, %o7 ;; indirect call on %i2 - MachineInstr *J = BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(o7); - emitWord(getBinaryCodeForInstr(*J)); - delete J; - - // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80 - LDX = BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2); - emitWord(getBinaryCodeForInstr(*LDX)); - delete LDX; + emitWord(getBinaryCodeForInstr(*BinaryCode[i])); + delete BinaryCode[i]; + } } Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.13 llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.14 --- llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.13 Tue Jul 29 15:52:56 2003 +++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.h Wed Aug 6 11:20:22 2003 @@ -50,8 +50,9 @@ /// emitFarCall - produces a code sequence to make a call to a destination /// that does not fit in the 30 bits that a call instruction allows. - /// - void emitFarCall(uint64_t Addr); + /// If the function F is non-null, this also saves the return address in + /// the LazyResolver map of the JITResolver. + void emitFarCall(uint64_t Addr, Function *F = 0); private: /// getMachineOpValue - From brukman at cs.uiuc.edu Wed Aug 6 11:29:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Aug 6 11:29:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp Message-ID: <200308061628.LAA10595@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeEmitterGen.cpp updated: 1.25 -> 1.26 --- Log message: Added asserts to prevent negative shift amounts from being generated. --- Diffs of the changes: Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.25 llvm/utils/TableGen/CodeEmitterGen.cpp:1.26 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.25 Tue Aug 5 23:36:35 2003 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Wed Aug 6 11:28:49 2003 @@ -131,6 +131,7 @@ // Mask off the right bits // Low mask (ie. shift, if necessary) + assert(endBitInVar >= 0 && "Negative shift amount in masking!"); if (endBitInVar != 0) { o << " op" << OpOrder[Vals[i].getName()] << " >>= " << endBitInVar << ";\n"; @@ -143,6 +144,7 @@ << " &= (1<<" << beginBitInVar+1 << ") - 1;\n"; // Shift the value to the correct place (according to place in inst) + assert(endBitInInst >= 0 && "Negative shift amount in inst position!"); if (endBitInInst != 0) o << " op" << OpOrder[Vals[i].getName()] << " <<= " << endBitInInst << ";\n"; From lattner at cs.uiuc.edu Wed Aug 6 12:17:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 12:17:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200308061716.MAA17920@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.1 -> 1.2 --- Log message: Remove unnecessary use of NonCopyable --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.1 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.2 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.1 Sun Dec 8 07:26:29 2002 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Wed Aug 6 12:16:19 2003 @@ -21,7 +21,6 @@ #include "llvm/Support/CFG.h" #include "Support/TarjanSCCIterator.h" #include "Support/Statistic.h" -#include "Support/NonCopyable.h" #include "Support/STLExtras.h" #include "Support/hash_map" #include "Support/hash_set" @@ -116,14 +115,14 @@ /// and all that use any node. ///-------------------------------------------------------------------------- -class ModRefInfoBuilder: public InstVisitor, - public NonCopyable -{ +class ModRefInfoBuilder : public InstVisitor { const DSGraph& funcGraph; const FunctionModRefInfo& funcModRef; ModRefTable& modRefTable; - ModRefInfoBuilder(); // do not implement + ModRefInfoBuilder(); // DO NOT IMPLEMENT + ModRefInfoBuilder(const ModRefInfoBuilder&); // DO NOT IMPLEMENT + void operator=(const ModRefInfoBuilder&); // DO NOT IMPLEMENT public: /*ctor*/ ModRefInfoBuilder(const DSGraph& _funcGraph, From lattner at cs.uiuc.edu Wed Aug 6 12:17:13 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 12:17:13 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Parallelize.cpp Message-ID: <200308061716.MAA17927@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Parallelize.cpp updated: 1.2 -> 1.3 --- Log message: Remove unnecessary use of NonCopyable --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/Parallelize.cpp diff -u llvm/lib/Transforms/IPO/Parallelize.cpp:1.2 llvm/lib/Transforms/IPO/Parallelize.cpp:1.3 --- llvm/lib/Transforms/IPO/Parallelize.cpp:1.2 Wed Apr 16 15:28:39 2003 +++ llvm/lib/Transforms/IPO/Parallelize.cpp Wed Aug 6 12:16:24 2003 @@ -45,7 +45,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/Cilkifier.h" -#include "Support/NonCopyable.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" #include "Support/hash_set" @@ -280,9 +279,7 @@ // useful parallelism. //---------------------------------------------------------------------------- -class FindParallelCalls: public InstVisitor, - public NonCopyable -{ +class FindParallelCalls : public InstVisitor { typedef hash_set DependentsSet; typedef DependentsSet::iterator Dependents_iterator; typedef DependentsSet::const_iterator Dependents_const_iterator; @@ -296,6 +293,8 @@ CallInst* root, DependentsSet& depsOfRoot); + FindParallelCalls(const FindParallelCalls &); // DO NOT IMPLEMENT + void operator=(const FindParallelCalls&); // DO NOT IMPLEMENT public: std::vector parallelCalls; From lattner at cs.uiuc.edu Wed Aug 6 13:05:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 13:05:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200308061804.NAA19533@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.113 -> 1.114 --- Log message: The HAVE_JUMP code is dead, these intrinsics should _never_ be expanded --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.113 llvm/lib/CWriter/Writer.cpp:1.114 --- llvm/lib/CWriter/Writer.cpp:1.113 Thu Jul 31 12:47:24 2003 +++ llvm/lib/CWriter/Writer.cpp Wed Aug 6 13:04:40 2003 @@ -1123,32 +1123,15 @@ return; case LLVMIntrinsic::setjmp: -#ifdef HAVE_JUMP - Out << "setjmp(*(jmp_buf*)"; - writeOperand(I.getOperand(1)); - Out << ")"; -#else - // - // For right now, we don't really support non-local jumps. So - // make setjmp() always evaluate to zero for now. - // - Out << "(0)"; -#endif + // This instrinsic should never exist in the program, but until we get + // setjmp/longjmp transformations going on, we should codegen it to + // something reasonable. This will allow code that never calls longjmp + // to work. + Out << "0"; return; case LLVMIntrinsic::longjmp: -#ifdef HAVE_JUMP - Out << "longjmp(*(jmp_buf*)"; - writeOperand(I.getOperand(1)); - Out << ", "; - writeOperand(I.getOperand(2)); - Out << ")"; -#else - // - // For right now, we don't really support non-local jumps. So - // make longjmp() abort the program. - // + // Treat longjmp the same as setjmp Out << "abort()"; -#endif return; } } From lattner at cs.uiuc.edu Wed Aug 6 13:27:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 13:27:03 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-06-BuiltinSetjmpLongjmp.c.tr Message-ID: <200308061826.NAA21088@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-06-BuiltinSetjmpLongjmp.c.tr added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-06-BuiltinSetjmpLongjmp.c.tr diff -c /dev/null llvm/test/Regression/CFrontend/2003-08-06-BuiltinSetjmpLongjmp.c.tr:1.1 *** /dev/null Wed Aug 6 13:26:30 2003 --- llvm/test/Regression/CFrontend/2003-08-06-BuiltinSetjmpLongjmp.c.tr Wed Aug 6 13:26:19 2003 *************** *** 0 **** --- 1,14 ---- + /* RUN: llvmgcc -xc %s -c -o - | dis | not grep __builtin_ + * + * __builtin_longjmp/setjmp should get transformed into llvm.setjmp/longjmp + * just like explicit setjmp/longjmp calls are. + */ + + void jumpaway(int *ptr) { + __builtin_longjmp(ptr,1); + } + + int main(void) { + __builtin_setjmp(0); + jumpaway(0); + } From vadve at cs.uiuc.edu Wed Aug 6 13:44:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 13:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PreOpts/PreSelection.cpp Message-ID: <200308061843.NAA25858@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/PreOpts: PreSelection.cpp updated: 1.14 -> 1.15 --- Log message: Remove conversion of fp-to-uint cast into a multi-step cast: this is not an optional transformation on SPARC and is now handled directly by instruction selection. --- Diffs of the changes: Index: llvm/lib/CodeGen/PreOpts/PreSelection.cpp diff -u llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.14 llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.15 --- llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.14 Tue Jul 1 20:23:15 2003 +++ llvm/lib/CodeGen/PreOpts/PreSelection.cpp Wed Aug 6 13:42:49 2003 @@ -144,7 +144,6 @@ // These methods do the actual work of specializing code void visitInstruction(Instruction &I); // common work for every instr. void visitGetElementPtrInst(GetElementPtrInst &I); - void visitCastInst(CastInst &I); void visitCallInst(CallInst &I); // Helper functions for visiting operands of every instruction @@ -340,34 +339,6 @@ visitInstruction(*curI); } - -// Cast instructions: -// -- make multi-step casts explicit: -// -- float/double to uint32_t: -// If target does not have a float-to-unsigned instruction, we -// need to convert to uint64_t and then to uint32_t, or we may -// overflow the signed int representation for legal uint32_t -// values. Expand this without checking target. -// -- other common transformations on operands -// -void -PreSelection::visitCastInst(CastInst &I) -{ - CastInst* castI = NULL; - - // Check for a global and put its address into a register before this instr - if (I.getType() == Type::UIntTy && - I.getOperand(0)->getType()->isFloatingPoint()) { - // insert a cast-fp-to-long before I, and then replace the operand of I - castI = new CastInst(I.getOperand(0), Type::LongTy, "fp2Long2Uint", &I); - I.setOperand(0, castI); // replace fp operand with long - } - - // Perform other transformations common to all instructions - visitInstruction(I); - if (castI) - visitInstruction(*castI); -} void PreSelection::visitCallInst(CallInst &I) From vadve at cs.uiuc.edu Wed Aug 6 13:49:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 13:49:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200308061848.NAA26048@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.111 -> 1.112 --- Log message: 1. Bug fix: was using SLL instead of SLLX for ULongTy. Chump. 2. Handle fp-to-uint conversions directly here instead of relying on a pre-transformation to replace them with the 2-step conversion. 3. Use size rather than explicitly checking types when deciding what opcodes to use, wherever possible. This is less error prone (the bug fix above was not the first time!). 4. Float-to-pointer casts shd now work though this hasn't been tested. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.111 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.112 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.111 Tue Aug 5 11:59:24 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Wed Aug 6 13:48:40 2003 @@ -493,64 +493,66 @@ static inline MachineOpCode -ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType) +ChooseConvertToFloatInstr(const TargetMachine& target, + OpLabel vopCode, const Type* opType) { assert((vopCode == ToFloatTy || vopCode == ToDoubleTy) && "Unrecognized convert-to-float opcode!"); + assert((opType->isIntegral() || opType->isFloatingPoint() || + isa(opType)) + && "Trying to convert a non-scalar type to FLOAT/DOUBLE?"); MachineOpCode opCode = V9::INVALID_OPCODE; - - if (opType == Type::SByteTy || opType == Type::UByteTy || - opType == Type::ShortTy || opType == Type::UShortTy || - opType == Type::IntTy || opType == Type::UIntTy) - opCode = (vopCode == ToFloatTy? V9::FITOS : V9::FITOD); - else if (opType == Type::LongTy || opType == Type::ULongTy || - isa(opType)) - opCode = (vopCode == ToFloatTy? V9::FXTOS : V9::FXTOD); - else if (opType == Type::FloatTy) - opCode = (vopCode == ToFloatTy? V9::INVALID_OPCODE : V9::FSTOD); + + unsigned opSize = target.getTargetData().getTypeSize(opType); + + if (opType == Type::FloatTy) + opCode = (vopCode == ToFloatTy? V9::NOP : V9::FSTOD); else if (opType == Type::DoubleTy) - opCode = (vopCode == ToFloatTy? V9::FDTOS : V9::INVALID_OPCODE); - else - assert(0 && "Trying to convert a non-scalar type to DOUBLE?"); + opCode = (vopCode == ToFloatTy? V9::FDTOS : V9::NOP); + else if (opSize <= 4) + opCode = (vopCode == ToFloatTy? V9::FITOS : V9::FITOD); + else { + assert(opSize == 8 && "Unrecognized type size > 4 and < 8!"); + opCode = (vopCode == ToFloatTy? V9::FXTOS : V9::FXTOD); + } return opCode; } static inline MachineOpCode -ChooseConvertFPToIntInstr(Type::PrimitiveID tid, const Type* opType) +ChooseConvertFPToIntInstr(const TargetMachine& target, + const Type* destType, const Type* opType) { - MachineOpCode opCode = V9::INVALID_OPCODE;; - assert((opType == Type::FloatTy || opType == Type::DoubleTy) && "This function should only be called for FLOAT or DOUBLE"); + assert((destType->isIntegral() || isa(destType)) + && "Trying to convert FLOAT/DOUBLE to a non-scalar type?"); - // SPARC does not have a float-to-uint conversion, only a float-to-int. - // For converting an FP value to uint32_t, we first need to convert to - // uint64_t and then to uint32_t, or we may overflow the signed int - // representation even for legal uint32_t values. This expansion is - // done by the Preselection pass. - // - if (tid == Type::UIntTyID) { - assert(tid != Type::UIntTyID && "FP-to-uint conversions must be expanded" - " into FP->long->uint for SPARC v9: SO RUN PRESELECTION PASS!"); - } else if (tid == Type::SByteTyID || tid == Type::ShortTyID || - tid == Type::IntTyID || tid == Type::UByteTyID || - tid == Type::UShortTyID) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + unsigned destSize = target.getTargetData().getTypeSize(destType); + + if (destType == Type::UIntTy) + assert(destType != Type::UIntTy && "Expand FP-to-uint beforehand."); + else if (destSize <= 4) opCode = (opType == Type::FloatTy)? V9::FSTOI : V9::FDTOI; - } else if (tid == Type::LongTyID || tid == Type::ULongTyID) { - opCode = (opType == Type::FloatTy)? V9::FSTOX : V9::FDTOX; - } else - assert(0 && "Should not get here, Mo!"); + else { + assert(destSize == 8 && "Unrecognized type size > 4 and < 8!"); + opCode = (opType == Type::FloatTy)? V9::FSTOX : V9::FDTOX; + } return opCode; } -MachineInstr* -CreateConvertFPToIntInstr(Type::PrimitiveID destTID, - Value* srcVal, Value* destVal) +static MachineInstr* +CreateConvertFPToIntInstr(const TargetMachine& target, + Value* srcVal, + Value* destVal, + const Type* destType) { - MachineOpCode opCode = ChooseConvertFPToIntInstr(destTID, srcVal->getType()); + MachineOpCode opCode = ChooseConvertFPToIntInstr(target, destType, + srcVal->getType()); assert(opCode != V9::INVALID_OPCODE && "Expected to need conversion!"); return BuildMI(opCode, 2).addReg(srcVal).addRegDef(destVal); } @@ -558,19 +560,11 @@ // CreateCodeToConvertFloatToInt: Convert FP value to signed or unsigned integer // The FP value must be converted to the dest type in an FP register, // and the result is then copied from FP to int register via memory. -// +// SPARC does not have a float-to-uint conversion, only a float-to-int (fdtoi). // Since fdtoi converts to signed integers, any FP value V between MAXINT+1 -// and MAXUNSIGNED (i.e., 2^31 <= V <= 2^32-1) would be converted incorrectly -// *only* when converting to an unsigned. (Unsigned byte, short or long -// don't have this problem.) -// For unsigned int, we therefore have to generate the code sequence: -// -// if (V > (float) MAXINT) { -// unsigned result = (unsigned) (V - (float) MAXINT); -// result = result + (unsigned) MAXINT; -// } -// else -// result = (unsigned) V; +// and MAXUNSIGNED (i.e., 2^31 <= V <= 2^32-1) would be converted incorrectly. +// Therefore, for converting an FP value to uint32_t, we first need to convert +// to uint64_t and then to uint32_t. // static void CreateCodeToConvertFloatToInt(const TargetMachine& target, @@ -579,24 +573,46 @@ std::vector& mvec, MachineCodeForInstruction& mcfi) { + Function* F = destI->getParent()->getParent(); + // Create a temporary to represent the FP register into which the // int value will placed after conversion. The type of this temporary // depends on the type of FP register to use: single-prec for a 32-bit // int or smaller; double-prec for a 64-bit int. // size_t destSize = target.getTargetData().getTypeSize(destI->getType()); - const Type* destTypeToUse = (destSize > 4)? Type::DoubleTy : Type::FloatTy; - TmpInstruction* destForCast = new TmpInstruction(mcfi, destTypeToUse, opVal); - // Create the fp-to-int conversion code - MachineInstr* M =CreateConvertFPToIntInstr(destI->getType()->getPrimitiveID(), - opVal, destForCast); - mvec.push_back(M); + const Type* castDestType = destI->getType(); // type for the cast instr result + const Type* castDestRegType; // type for cast instruction result reg + TmpInstruction* destForCast; // dest for cast instruction + Instruction* fpToIntCopyDest = destI; // dest for fp-reg-to-int-reg copy instr + + // For converting an FP value to uint32_t, we first need to convert to + // uint64_t and then to uint32_t, as explained above. + if (destI->getType() == Type::UIntTy) { + castDestType = Type::ULongTy; // use this instead of type of destI + castDestRegType = Type::DoubleTy; // uint64_t needs 64-bit FP register. + destForCast = new TmpInstruction(mcfi, castDestRegType, opVal); + fpToIntCopyDest = new TmpInstruction(mcfi, castDestType, destForCast); + } + else { + castDestRegType = (destSize > 4)? Type::DoubleTy : Type::FloatTy; + destForCast = new TmpInstruction(mcfi, castDestRegType, opVal); + } + + // Create the fp-to-int conversion instruction (src and dest regs are FP regs) + mvec.push_back(CreateConvertFPToIntInstr(target, opVal, destForCast, + castDestType)); // Create the fpreg-to-intreg copy code - target.getInstrInfo(). - CreateCodeToCopyFloatToInt(target, destI->getParent()->getParent(), - destForCast, destI, mvec, mcfi); + target.getInstrInfo().CreateCodeToCopyFloatToInt(target, F, destForCast, + fpToIntCopyDest, mvec, mcfi); + + // Create the uint64_t to uint32_t conversion, if needed + if (destI->getType() == Type::UIntTy) + target.getInstrInfo(). + CreateZeroExtensionInstructions(target, F, fpToIntCopyDest, destI, + /*numLowBits*/ 32, mvec, mcfi); } @@ -992,6 +1008,7 @@ } else if (isPowerOf2(C, pow)) { unsigned opCode; Value* shiftOperand; + unsigned opSize = target.getTargetData().getTypeSize(resultType); if (resultType->isSigned()) { // For N / 2^k, if the operand N is negative, @@ -1020,15 +1037,13 @@ addTmp = new TmpInstruction(mcfi, resultType, LHS, srlTmp,"incIfNeg"); // Create the SRA or SRAX instruction to get the sign bit - mvec.push_back(BuildMI((resultType==Type::LongTy) ? - V9::SRAXi6 : V9::SRAi5, 3) + mvec.push_back(BuildMI((opSize > 4)? V9::SRAXi6 : V9::SRAi5, 3) .addReg(LHS) .addSImm((resultType==Type::LongTy)? pow-1 : 31) .addRegDef(sraTmp)); // Create the SRL or SRLX instruction to get the sign bit - mvec.push_back(BuildMI((resultType==Type::LongTy) ? - V9::SRLXi6 : V9::SRLi5, 3) + mvec.push_back(BuildMI((opSize > 4)? V9::SRLXi6 : V9::SRLi5, 3) .addReg(sraTmp) .addSImm((resultType==Type::LongTy)? 64-pow : 32-pow) .addRegDef(srlTmp)); @@ -1039,11 +1054,11 @@ // Get the shift operand and "right-shift" opcode to do the divide shiftOperand = addTmp; - opCode = (resultType==Type::LongTy) ? V9::SRAXi6 : V9::SRAi5; + opCode = (opSize > 4)? V9::SRAXi6 : V9::SRAi5; } else { // Get the shift operand and "right-shift" opcode to do the divide shiftOperand = LHS; - opCode = (resultType==Type::LongTy) ? V9::SRLXi6 : V9::SRLi5; + opCode = (opSize > 4)? V9::SRLXi6 : V9::SRLi5; } // Now do the actual shift! @@ -1860,7 +1875,7 @@ } else if (opType->isFloatingPoint()) { CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, mcfi); - if (destI->getType()->isUnsigned()) + if (destI->getType()->isUnsigned() && destI->getType() !=Type::UIntTy) maskUnsignedResult = true; // not handled by fp->int code } else if (isIntegral) { @@ -1928,9 +1943,9 @@ if (forwardOperandNum != 0) { // we do need the cast Value* leftVal = subtreeRoot->leftChild()->getValue(); const Type* opType = leftVal->getType(); - MachineOpCode opCode=ChooseConvertToFloatInstr( + MachineOpCode opCode=ChooseConvertToFloatInstr(target, subtreeRoot->getOpLabel(), opType); - if (opCode == V9::INVALID_OPCODE) { // no conversion needed + if (opCode == V9::NOP) { // no conversion needed forwardOperandNum = 0; // forward first operand to user } else { // If the source operand is a non-FP type it must be @@ -2753,9 +2768,10 @@ const Type* opType = argVal1->getType(); assert((opType->isInteger() || isa(opType)) && "Shl unsupported for other types"); + unsigned opSize = target.getTargetData().getTypeSize(opType); CreateShiftInstructions(target, shlInstr->getParent()->getParent(), - (opType == Type::LongTy)? V9::SLLXr6:V9::SLLr5, + (opSize > 4)? V9::SLLXr6:V9::SLLr5, argVal1, argVal2, 0, shlInstr, mvec, MachineCodeForInstruction::get(shlInstr)); break; @@ -2766,9 +2782,10 @@ const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); assert((opType->isInteger() || isa(opType)) && "Shr unsupported for other types"); + unsigned opSize = target.getTargetData().getTypeSize(opType); Add3OperandInstr(opType->isSigned() - ? (opType == Type::LongTy ? V9::SRAXr6 : V9::SRAr5) - : (opType == Type::ULongTy ? V9::SRLXr6 : V9::SRLr5), + ? (opSize > 4? V9::SRAXr6 : V9::SRAr5) + : (opSize > 4? V9::SRLXr6 : V9::SRLr5), subtreeRoot, mvec); break; } From lattner at cs.uiuc.edu Wed Aug 6 15:09:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 15:09:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200308062008.PAA17559@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.40 -> 1.41 Verifier.cpp updated: 1.52 -> 1.53 --- Log message: Add a bunch of new Alpha Intrinsics for Rahul Joshi --- Diffs of the changes: Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.40 llvm/lib/VMCore/Function.cpp:1.41 --- llvm/lib/VMCore/Function.cpp:1.40 Mon Jul 28 16:20:57 2003 +++ llvm/lib/VMCore/Function.cpp Wed Aug 6 15:08:23 2003 @@ -163,12 +163,36 @@ getName()[1] != 'l' || getName()[2] != 'v' || getName()[3] != 'm') return 0; // All intrinsics start with 'llvm.' + // a table of all Alpha intrinsic functions + struct { + std::string name; // The name of the intrinsic + unsigned id; // Its ID number + } alpha_intrinsics[] = { + { "llvm.alpha.ctlz", LLVMIntrinsic::alpha_ctlz }, + { "llvm.alpha.cttz", LLVMIntrinsic::alpha_cttz }, + { "llvm.alpha.ctpop", LLVMIntrinsic::alpha_ctpop }, + { "llvm.alpha.umulh", LLVMIntrinsic::alpha_umulh }, + { "llvm.alpha.vecop", LLVMIntrinsic::alpha_vecop }, + { "llvm.alpha.pup", LLVMIntrinsic::alpha_pup }, + { "llvm.alpha.bytezap", LLVMIntrinsic::alpha_bytezap }, + { "llvm.alpha.bytemanip", LLVMIntrinsic::alpha_bytemanip }, + { "llvm.alpha.dfp_bop", LLVMIntrinsic::alpha_dfpbop }, + { "llvm.alpha.dfp_uop", LLVMIntrinsic::alpha_dfpuop }, + { "llvm.alpha.unordered", LLVMIntrinsic::alpha_unordered }, + { "llvm.alpha.uqtodfp", LLVMIntrinsic::alpha_uqtodfp }, + { "llvm.alpha.uqtosfp", LLVMIntrinsic::alpha_uqtosfp }, + { "llvm.alpha.dfptosq", LLVMIntrinsic::alpha_dfptosq }, + { "llvm.alpha.sfptosq", LLVMIntrinsic::alpha_sfptosq }, + }; + const unsigned num_alpha_intrinsics = + sizeof(alpha_intrinsics) / sizeof(*alpha_intrinsics); + switch (getName()[5]) { case 'a': - if (getName() == "llvm.alpha.ctlz") return LLVMIntrinsic::alpha_ctlz; - if (getName() == "llvm.alpha.cttz") return LLVMIntrinsic::alpha_cttz; - if (getName() == "llvm.alpha.ctpop") return LLVMIntrinsic::alpha_ctpop; - if (getName() == "llvm.alpha.umulh") return LLVMIntrinsic::alpha_umulh; + for (unsigned i = 0; i < num_alpha_intrinsics; ++i) { + if (getName() == alpha_intrinsics[i].name) + return alpha_intrinsics[i].id; + } break; case 'l': if (getName() == "llvm.longjmp") return LLVMIntrinsic::longjmp; Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.52 llvm/lib/VMCore/Verifier.cpp:1.53 --- llvm/lib/VMCore/Verifier.cpp:1.52 Mon Jul 28 16:20:57 2003 +++ llvm/lib/VMCore/Verifier.cpp Wed Aug 6 15:08:23 2003 @@ -522,10 +522,21 @@ case LLVMIntrinsic::setjmp: NumArgs = 1; break; case LLVMIntrinsic::longjmp: NumArgs = 2; break; - case LLVMIntrinsic::alpha_ctlz: NumArgs = 1; break; - case LLVMIntrinsic::alpha_cttz: NumArgs = 1; break; - case LLVMIntrinsic::alpha_ctpop: NumArgs = 1; break; - case LLVMIntrinsic::alpha_umulh: NumArgs = 2; break; + case LLVMIntrinsic::alpha_ctlz: NumArgs = 1; break; + case LLVMIntrinsic::alpha_cttz: NumArgs = 1; break; + case LLVMIntrinsic::alpha_ctpop: NumArgs = 1; break; + case LLVMIntrinsic::alpha_umulh: NumArgs = 2; break; + case LLVMIntrinsic::alpha_vecop: NumArgs = 4; break; + case LLVMIntrinsic::alpha_pup: NumArgs = 3; break; + case LLVMIntrinsic::alpha_bytezap: NumArgs = 2; break; + case LLVMIntrinsic::alpha_bytemanip: NumArgs = 3; break; + case LLVMIntrinsic::alpha_dfpbop: NumArgs = 3; break; + case LLVMIntrinsic::alpha_dfpuop: NumArgs = 2; break; + case LLVMIntrinsic::alpha_unordered: NumArgs = 2; break; + case LLVMIntrinsic::alpha_uqtodfp: NumArgs = 2; break; + case LLVMIntrinsic::alpha_uqtosfp: NumArgs = 2; break; + case LLVMIntrinsic::alpha_dfptosq: NumArgs = 2; break; + case LLVMIntrinsic::alpha_sfptosq: NumArgs = 2; break; case LLVMIntrinsic::not_intrinsic: assert(0 && "Invalid intrinsic!"); NumArgs = 0; break; From lattner at cs.uiuc.edu Wed Aug 6 15:09:16 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 15:09:16 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.h Message-ID: <200308062008.PAA17564@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.h updated: 1.4 -> 1.5 --- Log message: Add a bunch of new Alpha Intrinsics for Rahul Joshi --- Diffs of the changes: Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.4 llvm/include/llvm/Intrinsics.h:1.5 --- llvm/include/llvm/Intrinsics.h:1.4 Mon Jul 28 16:18:21 2003 +++ llvm/include/llvm/Intrinsics.h Wed Aug 6 15:08:25 2003 @@ -30,13 +30,89 @@ // alpha_ctlz, // CTLZ (count leading zero): counts the number of leading // zeros in the given ulong value + alpha_cttz, // CTTZ (count trailing zero): counts the number of trailing // zeros in the given ulong value + alpha_ctpop, // CTPOP (count population): counts the number of ones in // the given ulong value + alpha_umulh, // UMULH (unsigned multiply quadword high): Takes two 64-bit // (ulong) values, and returns the upper 64 bits of their // 128 bit product as a ulong + + alpha_vecop, // A generic vector operation. This function is used to + // represent various Alpha vector/multimedia instructions. + // It takes 4 parameters: + // - the first two are 2 ulong vectors + // - the third (uint) is the size (in bytes) of each + // vector element. Thus a value of 1 means that the two + // input vectors consist of 8 bytes + // - the fourth (uint) is the operation to be performed on + // the vectors. Its possible values are defined in the + // enumeration AlphaVecOps. + + alpha_pup, // A pack/unpack operation. This function is used to + // represent Alpha pack/unpack operations. + // It takes 3 parameters: + // - the first is an ulong to pack/unpack + // - the second (uint) is the size of each component + // Valid values are 2 (word) or 4 (longword) + // - the third (uint) is the operation to be performed. + // Possible values defined in the enumeration + // AlphaPupOps + + alpha_bytezap, // This intrinsic function takes two parameters: a ulong + // (64-bit) value and a ubyte value, and returns a ulong. + // Each bit in the ubyte corresponds to a byte in the + // ulong. If the bit is 0, the byte in the output equals + // the corresponding byte in the input, else the byte in + // the output is zero. + + alpha_bytemanip,// This intrinsic function represents all Alpha byte + // manipulation instructions. It takes 3 parameters: + // - The first two are ulong inputs to operate on + // - The third (uint) is the operation to perform. + // Possible values defined in the enumeration + // AlphaByteManipOps + + alpha_dfpbop, // This intrinsic function represents Alpha instructions + // that operate on two doubles and return a double. The + // first two parameters are the two double values to + // operate on, and the third is a uint that specifies the + // operation to perform. Its possible values are defined in + // the enumeration AlphaFloatingBinaryOps + + alpha_dfpuop, // This intrinsic function represents operation on a single + // double precision floating point value. The first + // paramters is the value and the second is the operation. + // The possible values for the operations are defined in the + // enumeration AlphaFloatingUnaryOps + + alpha_unordered,// This intrinsic function tests if two double precision + // floating point values are unordered. It has two + // parameters: the two values to be tested. It return a + // boolean true if the two are unordered, else false. + + alpha_uqtodfp, // A generic function that converts a ulong to a double. + // How the conversion is performed is specified by the + // second parameter, the possible values for which are + // defined in the AlphaUqToDfpOps enumeration + + alpha_uqtosfp, // A generic function that converts a ulong to a float. + // How the conversion is performed is specified by the + // second parameter, the possible values for which are + // defined in the AlphaUqToSfpOps enumeration + + alpha_dfptosq, // A generic function that converts double to a long. + // How the conversion is performed is specified by the + // second parameter, the possible values for which are + // defined in the AlphaDfpToSqOps enumeration + + alpha_sfptosq, // A generic function that converts a float to a long. + // How the conversion is performed is specified by the + // second parameter, the possible values for which are + // defined in the AlphaSfpToSq enumeration }; } From vadve at cs.uiuc.edu Wed Aug 6 15:41:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:41:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200308062040.PAA19753@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.80 -> 1.81 --- Log message: Use a common (and higher) time limit for all architectures. Individual makefiles were overriding this incorrectly otherwise (i.e,. decreasing it instead of increasing it). This only matters on hanging failures anyway. --- Diffs of the changes: Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.80 llvm/test/Programs/Makefile.programs:1.81 --- llvm/test/Programs/Makefile.programs:1.80 Wed Jul 30 12:57:14 2003 +++ llvm/test/Programs/Makefile.programs Wed Aug 6 15:40:41 2003 @@ -65,11 +65,7 @@ # timeout. This is overridable on the commandline or in tests makefiles. # ifndef RUNTIMELIMIT - ifeq ($(ARCH),Sparc) - RUNTIMELIMIT := 500 - else - RUNTIMELIMIT := 40 - endif + RUNTIMELIMIT := 500 endif # RUNSAFELY - This program simply runs another program. If the program works @@ -232,6 +228,10 @@ $(LGCCLD) $(STATS) $< -lgcc -lc $(LIBS) crtend.o -o Output/$*.llvm ifneq ($(OPTPASSES),) $(LOPT) -q $(OPTPASSES) < $@ > $@.tmp +ifneq ($(TRACE)$(TRACEM),) + $(LLINK) -f $@.tmp $(LEVEL)/test/Libraries/Output/libinstr.bc > $@.tmp2 + $(MV) -f $@.tmp2 $@.tmp +endif $(MV) -f $@.tmp $@ endif From vadve at cs.uiuc.edu Wed Aug 6 15:43:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:43:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/sim/Makefile Message-ID: <200308062042.PAA19852@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/sim: Makefile updated: 1.2 -> 1.3 --- Log message: These makefiles were overriding this incorrectly otherwise (i.e,. decreasing it instead of increasing it). This only matters on hanging failures anyway so let's just use a common (and higher) time limit for all architectures. Programs with that need a much higher limit can still override it. --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/sim/Makefile diff -u llvm/test/Programs/MultiSource/sim/Makefile:1.2 llvm/test/Programs/MultiSource/sim/Makefile:1.3 --- llvm/test/Programs/MultiSource/sim/Makefile:1.2 Sun May 11 17:41:06 2003 +++ llvm/test/Programs/MultiSource/sim/Makefile Wed Aug 6 15:42:34 2003 @@ -3,6 +3,5 @@ PROG = sim CPPFLAGS = -DUNIX LDFLAGS = -RUNTIMELIMIT = 60 include ../Makefile.multisrc From vadve at cs.uiuc.edu Wed Aug 6 15:43:11 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:43:11 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/aha/Makefile Message-ID: <200308062042.PAA19844@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/aha: Makefile updated: 1.3 -> 1.4 --- Log message: These makefiles were overriding this incorrectly otherwise (i.e,. decreasing it instead of increasing it). This only matters on hanging failures anyway so let's just use a common (and higher) time limit for all architectures. Programs with that need a much higher limit can still override it. --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/aha/Makefile diff -u llvm/test/Programs/MultiSource/aha/Makefile:1.3 llvm/test/Programs/MultiSource/aha/Makefile:1.4 --- llvm/test/Programs/MultiSource/aha/Makefile:1.3 Tue May 27 17:36:34 2003 +++ llvm/test/Programs/MultiSource/aha/Makefile Wed Aug 6 15:42:32 2003 @@ -2,5 +2,4 @@ PROG = aha CPPFLAGS = LDFLAGS = -RUNTIMELIMIT = 300 include ../Makefile.multisrc From vadve at cs.uiuc.edu Wed Aug 6 15:43:21 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:43:21 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Ptrdist-ks/Makefile Message-ID: <200308062042.PAA19836@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Ptrdist-ks: Makefile updated: 1.4 -> 1.5 --- Log message: These makefiles were overriding this incorrectly otherwise (i.e,. decreasing it instead of increasing it). This only matters on hanging failures anyway so let's just use a common (and higher) time limit for all architectures. Programs with that need a much higher limit can still override it. --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/Ptrdist-ks/Makefile diff -u llvm/test/Programs/MultiSource/Ptrdist-ks/Makefile:1.4 llvm/test/Programs/MultiSource/Ptrdist-ks/Makefile:1.5 --- llvm/test/Programs/MultiSource/Ptrdist-ks/Makefile:1.4 Mon Jul 21 18:05:24 2003 +++ llvm/test/Programs/MultiSource/Ptrdist-ks/Makefile Wed Aug 6 15:42:31 2003 @@ -2,7 +2,6 @@ PROG = ks #OBJS = KS-1.o KS-2.o RUN_OPTIONS += KL-4.in -RUNTIMELIMIT = 120 include ../Makefile.multisrc From vadve at cs.uiuc.edu Wed Aug 6 15:43:31 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:43:31 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Fhourstones/Makefile Message-ID: <200308062042.PAA19818@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Fhourstones: Makefile updated: 1.5 -> 1.6 --- Log message: These makefiles were overriding this incorrectly otherwise (i.e,. decreasing it instead of increasing it). This only matters on hanging failures anyway so let's just use a common (and higher) time limit for all architectures. Programs with that need a much higher limit can still override it. --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/Fhourstones/Makefile diff -u llvm/test/Programs/MultiSource/Fhourstones/Makefile:1.5 llvm/test/Programs/MultiSource/Fhourstones/Makefile:1.6 --- llvm/test/Programs/MultiSource/Fhourstones/Makefile:1.5 Tue Jun 3 14:01:11 2003 +++ llvm/test/Programs/MultiSource/Fhourstones/Makefile Wed Aug 6 15:42:25 2003 @@ -6,6 +6,4 @@ # Specify which file provides the contents of stdin for the test run STDIN_FILENAME = input -RUNTIMELIMIT = 300 - include ../Makefile.multisrc From vadve at cs.uiuc.edu Wed Aug 6 15:43:41 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:43:41 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/McCat-08-main/Makefile Message-ID: <200308062042.PAA19827@tank.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/McCat-08-main: Makefile updated: 1.2 -> 1.3 --- Log message: These makefiles were overriding this incorrectly otherwise (i.e,. decreasing it instead of increasing it). This only matters on hanging failures anyway so let's just use a common (and higher) time limit for all architectures. Programs with that need a much higher limit can still override it. --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/McCat-08-main/Makefile diff -u llvm/test/Programs/MultiSource/McCat-08-main/Makefile:1.2 llvm/test/Programs/MultiSource/McCat-08-main/Makefile:1.3 --- llvm/test/Programs/MultiSource/McCat-08-main/Makefile:1.2 Tue Jun 3 14:01:12 2003 +++ llvm/test/Programs/MultiSource/McCat-08-main/Makefile Wed Aug 6 15:42:28 2003 @@ -1,7 +1,6 @@ LEVEL = ../../../.. PROG = main LDFLAGS = -lm -RUNTIMELIMIT = 300 include ../Makefile.multisrc From vadve at cs.uiuc.edu Wed Aug 6 15:54:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Aug 6 15:54:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200308062053.PAA20029@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.81 -> 1.82 --- Log message: Eliminate change that got checked in unintentionally as part of the last checkin. --- Diffs of the changes: Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.81 llvm/test/Programs/Makefile.programs:1.82 --- llvm/test/Programs/Makefile.programs:1.81 Wed Aug 6 15:40:41 2003 +++ llvm/test/Programs/Makefile.programs Wed Aug 6 15:52:59 2003 @@ -228,10 +228,6 @@ $(LGCCLD) $(STATS) $< -lgcc -lc $(LIBS) crtend.o -o Output/$*.llvm ifneq ($(OPTPASSES),) $(LOPT) -q $(OPTPASSES) < $@ > $@.tmp -ifneq ($(TRACE)$(TRACEM),) - $(LLINK) -f $@.tmp $(LEVEL)/test/Libraries/Output/libinstr.bc > $@.tmp2 - $(MV) -f $@.tmp2 $@.tmp -endif $(MV) -f $@.tmp $@ endif From gaeke at niobe.cs.uiuc.edu Wed Aug 6 16:45:01 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 6 16:45:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308062144.h76LiX027623@niobe.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.108 -> 1.109 --- Log message: Makefile.common: Remove commented-out and duplicate rules. --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.108 llvm/Makefile.common:1.109 --- llvm/Makefile.common:1.108 Tue Aug 5 16:38:28 2003 +++ llvm/Makefile.common Wed Aug 6 16:44:22 2003 @@ -677,29 +677,6 @@ .PRECIOUS: $(BUILD_OBJ_DIR)/Depend/.dir .PRECIOUS: $(BUILD_OBJ_DIR)/Debug/.dir $(BUILD_OBJ_DIR)/Release/.dir -# Create .o files in the ObjectFiles directory from the .cpp and .c files... -#$(BUILD_OBJ_DIR)/Release/%.o: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Release/.dir - #@echo "Compiling $<" - #$(VERB) $(CompileO) $< -o $@ - -#$(BUILD_OBJ_DIR)/Release/%.o: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Release/.dir - #$(VERB) $(CompileCO) $< -o $@ - -#$(BUILD_OBJ_DIR)/Profile/%.o: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Profile/.dir - #@echo "Compiling $<" - #$(VERB) $(CompileP) $< -o $@ - -#$(BUILD_OBJ_DIR)/Profile/%.o: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Profile/.dir - #@echo "Compiling $<" - #$(VERB) $(CompileCP) $< -o $@ - -#$(BUILD_OBJ_DIR)/Debug/%.o: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Debug/.dir - #@echo "Compiling $<" - #$(VERB) $(CompileG) $< -o $@ - -#$(BUILD_OBJ_DIR)/Debug/%.o: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Debug/.dir - #$(VERB) $(CompileCG) $< -o $@ - # Create .lo files in the ObjectFiles directory from the .cpp and .c files... $(BUILD_OBJ_DIR)/Release/%.lo: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Release/.dir @echo "Compiling $<" @@ -723,29 +700,6 @@ $(BUILD_OBJ_DIR)/Debug/%.lo: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Debug/.dir @echo "Compiling $<" - $(VERB) $(CompileCG) $< -o $@ - -# Create .lo files in the ObjectFiles directory from the .cpp and .c files... -$(BUILD_OBJ_DIR)/Release/%.lo: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Release/.dir - @echo "Compiling $<" - $(VERB) $(CompileO) $< -o $@ - -$(BUILD_OBJ_DIR)/Release/%.lo: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Release/.dir - $(VERB) $(CompileCO) $< -o $@ - -$(BUILD_OBJ_DIR)/Profile/%.lo: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Profile/.dir - @echo "Compiling $<" - $(VERB) $(CompileP) $< -o $@ - -$(BUILD_OBJ_DIR)/Profile/%.lo: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Profile/.dir - @echo "Compiling $<" - $(VERB) $(CompileCP) $< -o $@ - -$(BUILD_OBJ_DIR)/Debug/%.lo: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Debug/.dir - @echo "Compiling $<" - $(VERB) $(CompileG) $< -o $@ - -$(BUILD_OBJ_DIR)/Debug/%.lo: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Debug/.dir $(VERB) $(CompileCG) $< -o $@ # From gaeke at niobe.cs.uiuc.edu Wed Aug 6 16:46:00 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 6 16:46:00 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/MemoryManager.h TraceCache.h Message-ID: <200308062145.h76Ljpp27653@niobe.cs.uiuc.edu> Changes in directory llvm/include/llvm/Reoptimizer: MemoryManager.h updated: 1.3 -> 1.4 TraceCache.h updated: 1.12 -> 1.13 --- Log message: No need to have the dummy function take parameters or return a value. include/llvm/Reoptimizer/MemoryManager.h: Change type of dummy function used for trace cache. lib/Reoptimizer/TraceCache/TraceCache.cpp: Likewise. lib/Reoptimizer/TraceCache/MemoryManager.cpp: Likewise. Also change decl. include/llvm/Reoptimizer/TraceCache.h: Likewise. Also remove commented-out forward decl of TraceCache2. --- Diffs of the changes: Index: llvm/include/llvm/Reoptimizer/MemoryManager.h diff -u llvm/include/llvm/Reoptimizer/MemoryManager.h:1.3 llvm/include/llvm/Reoptimizer/MemoryManager.h:1.4 --- llvm/include/llvm/Reoptimizer/MemoryManager.h:1.3 Thu Jul 10 14:00:39 2003 +++ llvm/include/llvm/Reoptimizer/MemoryManager.h Wed Aug 6 16:45:41 2003 @@ -46,7 +46,7 @@ //Ctor: Using user provided function for space. The size of memory //is assumed as memSize. Must ensure the provided function >= memSize bytes - MemoryManager(int (*dfunc)(int), unsigned int memSize); + MemoryManager(void (*dfunc)(), unsigned int memSize); int getMemSize(){ return memorySize; } uint64_t getMemory(int sz); //return a pointer to memory of size sz Index: llvm/include/llvm/Reoptimizer/TraceCache.h diff -u llvm/include/llvm/Reoptimizer/TraceCache.h:1.12 llvm/include/llvm/Reoptimizer/TraceCache.h:1.13 --- llvm/include/llvm/Reoptimizer/TraceCache.h:1.12 Thu Jul 10 14:00:47 2003 +++ llvm/include/llvm/Reoptimizer/TraceCache.h Wed Aug 6 16:45:41 2003 @@ -15,8 +15,6 @@ class VirtualMem; class MemoryManager; -//class TraceCache2; - class TraceCache{ private: std::map traces; //map from addr to addr @@ -104,7 +102,7 @@ TraceCache(); //the code region of dfunc is used for memory allocation //instead of default memory allocation space used by memory manager - TraceCache(int (*dfunc)(int), unsigned int memSize, VirtualMem *vmem); + TraceCache(void (*dfunc)(), unsigned int memSize, VirtualMem *vmem); //remove the branch from the original code into the trace void patchTrace(uint64_t n); From gaeke at niobe.cs.uiuc.edu Wed Aug 6 16:46:11 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 6 16:46:11 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp MemoryManager.cpp Message-ID: <200308062145.h76Ljs427663@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: TraceCache.cpp updated: 1.16 -> 1.17 MemoryManager.cpp updated: 1.9 -> 1.10 --- Log message: No need to have the dummy function take parameters or return a value. include/llvm/Reoptimizer/MemoryManager.h: Change type of dummy function used for trace cache. lib/Reoptimizer/TraceCache/TraceCache.cpp: Likewise. lib/Reoptimizer/TraceCache/MemoryManager.cpp: Likewise. Also change decl. include/llvm/Reoptimizer/TraceCache.h: Likewise. Also remove commented-out forward decl of TraceCache2. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp diff -u llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp:1.16 llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp:1.17 --- llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp:1.16 Fri Jul 25 12:33:21 2003 +++ llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp Wed Aug 6 16:45:44 2003 @@ -65,7 +65,7 @@ } -TraceCache::TraceCache(int (*dfunc)(int), unsigned int memSize, +TraceCache::TraceCache(void (*dfunc)(), unsigned int memSize, VirtualMem *vmem){ mm = new MemoryManager(dfunc, memSize); Index: llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp diff -u llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp:1.9 llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp:1.10 --- llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp:1.9 Fri Jul 25 12:33:21 2003 +++ llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp Wed Aug 6 16:45:44 2003 @@ -29,7 +29,7 @@ using std::cerr; -int FirstTraceFunction(int i); //the function that provides memory! +extern "C" void FirstTraceFunction (); //the function that provides memory! MemoryManager::MemoryManager(){ uint64_t memAlign = (uint64_t)(intptr_t)&FirstTraceFunction; @@ -63,7 +63,7 @@ freeMemList.push_back(std::make_pair(memStart, memEnd)); } -MemoryManager::MemoryManager(int (*dfunc)(int), unsigned int memSize){ +MemoryManager::MemoryManager(void (*dfunc)(), unsigned int memSize){ uint64_t memAlign = (uint64_t)(intptr_t)dfunc; if(memAlign % 32){ memAlign -= (memAlign % 32); From lattner at cs.uiuc.edu Wed Aug 6 16:48:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 16:48:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp RegisterInfoEmitter.cpp Message-ID: <200308062147.QAA22705@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.2 -> 1.3 RegisterInfoEmitter.cpp updated: 1.8 -> 1.9 --- Log message: Export the register classes so that the instruction selector can get at them as needed --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.2 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.3 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.2 Wed Aug 6 01:16:35 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Wed Aug 6 16:47:14 2003 @@ -10,11 +10,11 @@ NodeType::ArgResultTypes NodeType::Translate(Record *R) { const std::string &Name = R->getName(); - if (Name == "DNRT_void") return Void; - if (Name == "DNRT_val" || Name == "DNAT_val") return Val; - if (Name == "DNRT_arg0" || Name == "DNAT_arg0") return Arg0; - if (Name == "DNAT_ptr") return Ptr; - throw "Unknown DagNodeResult Type '" + Name + "'!"; + if (Name == "DNVT_void") return Void; + if (Name == "DNVT_val" ) return Val; + if (Name == "DNVT_arg0") return Arg0; + if (Name == "DNVT_ptr" ) return Ptr; + throw "Unknown DagNodeValType '" + Name + "'!"; } Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.8 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.9 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.8 Tue Aug 5 23:36:35 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Wed Aug 6 16:47:14 2003 @@ -36,8 +36,8 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) { EmitSourceFileHeader("Register Information Header Fragment", OS); - - std::string ClassName = getTarget(Records)->getName() + "GenRegisterInfo"; + const std::string &TargetName = getTarget(Records)->getName(); + std::string ClassName = TargetName + "GenRegisterInfo"; OS << "#include \"llvm/Target/MRegisterInfo.h\"\n\n"; @@ -46,6 +46,17 @@ << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n" << " const unsigned* getCalleeSaveRegs() const;\n" << "};\n\n"; + + std::vector RegisterClasses = + Records.getAllDerivedDefinitions("RegisterClass"); + + OS << "namespace " << TargetName << " { // Register classes\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + const std::string &Name = RegisterClasses[i]->getName(); + if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes + OS << " extern TargetRegisterClass *" << Name << "RegisterClass;\n"; + } + OS << "} // end of namespace " << TargetName << "\n\n"; } // RegisterInfoEmitter::run - Main register file description emitter. @@ -183,6 +194,18 @@ OS << "}\n\n"; // End of anonymous namespace... Record *Target = getTarget(Records); + + OS << "namespace " << Target->getName() << " { // Register classes\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + const std::string &Name = RegisterClasses[i]->getName(); + if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes + OS << " TargetRegisterClass *" << Name << "RegisterClass = &" + << Name << "Instance;\n"; + } + OS << "} // end of namespace " << Target->getName() << "\n\n"; + + + std::string ClassName = Target->getName() + "GenRegisterInfo"; // Emit the constructor of the class... From gaeke at niobe.cs.uiuc.edu Wed Aug 6 16:48:12 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 6 16:48:12 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/ScratchMemory/ScratchMemory.cpp DummyFile.cpp DummyFile2.cpp Message-ID: <200308062147.h76LlTS27719@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/ScratchMemory: ScratchMemory.cpp added (r1.1) DummyFile.cpp (r1.1) removed DummyFile2.cpp (r1.1) removed --- Log message: Brand new scratch memory file; no need for lots of bogus "for" loops, because we use asm ".skip" instead. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/ScratchMemory/ScratchMemory.cpp diff -c /dev/null llvm/lib/Reoptimizer/ScratchMemory/ScratchMemory.cpp:1.1 *** /dev/null Wed Aug 6 16:47:29 2003 --- llvm/lib/Reoptimizer/ScratchMemory/ScratchMemory.cpp Wed Aug 6 16:47:19 2003 *************** *** 0 **** --- 1,15 ---- + //===-- Reoptimizer/ScratchMemory/ScratchMemory.cpp ------------*- C++ -*--=//// + // + // This file consists of functions that contain only skip directives. The + // effect is to clear out a bunch of empty space in the .text segment, in which + // the reoptimizer shall lay out traces. + // + //===----------------------------------------------------------------------===// + + extern "C" void FirstTraceFunction () { + asm (".skip 17*8192"); // 17 empty 8KB pages + } + + extern "C" void dummyFunction2 () { + asm (".skip 17*8192"); // 17 more empty 8KB pages + } From gaeke at niobe.cs.uiuc.edu Wed Aug 6 16:49:01 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 6 16:49:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.h Timer.h scheduler.h Message-ID: <200308062148.h76Lmeo27751@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: SLI.h added (r1.1) Timer.h added (r1.1) scheduler.h added (r1.1) --- Log message: New header files giving declarations of methods that are used externally to the corresponding .cpp files. I'll add file-header comments once I have something useful to put in them. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.h diff -c /dev/null llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.h:1.1 *** /dev/null Wed Aug 6 16:48:40 2003 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.h Wed Aug 6 16:48:30 2003 *************** *** 0 **** --- 1,9 ---- + #ifndef SLI_H + #define SLI_H + + #include "Support/DataTypes.h" + class VirtualMem; + + void doInstrumentation(uint64_t addr1, uint64_t addr2, VirtualMem *vm); + + #endif // SLI_H Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.h diff -c /dev/null llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.h:1.1 *** /dev/null Wed Aug 6 16:48:40 2003 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/Timer.h Wed Aug 6 16:48:30 2003 *************** *** 0 **** --- 1,9 ---- + #ifndef TIMER_H + #define TIMER_H + + #include "Support/DataTypes.h" + + extern int initialize_timer (); + extern uint64_t llvm_interval_counter; + + #endif // TIMER_H Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/scheduler.h diff -c /dev/null llvm/lib/Reoptimizer/LightWtProfiling/Trigger/scheduler.h:1.1 *** /dev/null Wed Aug 6 16:48:40 2003 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/scheduler.h Wed Aug 6 16:48:30 2003 *************** *** 0 **** --- 1,8 ---- + + #ifndef SCHEDULER_H + #define SCHEDULER_H + #include "Support/DataTypes.h" + + int insert_address_at(uint64_t time, uint64_t addr); + + #endif // SCHEDULER_H From criswell at cs.uiuc.edu Wed Aug 6 16:51:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Aug 6 16:51:01 2003 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200308062150.QAA09110@psmith.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.34 -> 1.35 --- Log message: Removed Makefile.common. Since we are including Makefile.test, we automatically get Makefile.common. Furthermore, the double inclusion of Makefile.common causes the test suite to be executed twice per invocation of the top level make. --- Diffs of the changes: Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.34 llvm/test/Makefile:1.35 --- llvm/test/Makefile:1.34 Wed Nov 6 14:36:52 2002 +++ llvm/test/Makefile Wed Aug 6 16:50:36 2003 @@ -1,5 +1,4 @@ LEVEL = .. DIRS = Feature Regression Programs -include ../Makefile.common include Makefile.tests From gaeke at niobe.cs.uiuc.edu Wed Aug 6 16:53:01 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 6 16:53:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp SecondTrigger.cpp Message-ID: <200308062152.h76LqF327783@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: FirstTrigger.cpp updated: 1.8 -> 1.9 SecondTrigger.cpp updated: 1.6 -> 1.7 --- Log message: Move private includes to top of files. Add many more meaningful comments. Remove global map iterationCounter, which is incremented but never tested. Instead of manually extracting return address from %i7, use GCC's __builtin_return_address(0). Refactor scanning-for-branch functionality which is shared between FirstTrigger.cpp and SecondTrigger.cpp. Also: FirstTrigger.cpp: Include scheduler.h, SLI.h and Timer.h for access to functions from those files, instead of copying the extern decls here. Change declaration of dummy function used for trace cache. Remove seenOccur, which is never used. Remove getFirstTrace, which is just a wrapper around doInstrumentation. Switch to using `pcAddr' for the name of the return address, to correspond more closely to SecondTrigger. SecondTrigger.cpp: Include Timer.h for access to functions from that file, instead of copying the extern decls here. Add a bit of debugging output to triggerBB (not yet used). --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.8 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.9 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.8 Tue Aug 5 14:34:19 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp Wed Aug 6 16:52:04 2003 @@ -8,6 +8,11 @@ // //===----------------------------------------------------------------------===// +#include "GetTimer.h" +#include "RegSaveRestore.h" +#include "scheduler.h" +#include "SLI.h" +#include "Timer.h" #include "llvm/Reoptimizer/VirtualMem.h" #include "llvm/Reoptimizer/InstrUtils.h" #include "llvm/Reoptimizer/TraceCache.h" @@ -16,32 +21,26 @@ #include #include #include -#include "GetTimer.h" #ifdef __sparc #include #endif -#include "RegSaveRestore.h" using namespace std; extern long THRESHOLD_LEVEL_2; extern long LEVEL_TWO_EXITS; -// Function used as space for the trace cache: -extern int dummyFunction2(int); +// Function used as space for the second-level instrumentation trace cache. +extern "C" void dummyFunction2 (); + +// From SecondTrigger.cpp: +extern uint32_t scanForBranch (const uint64_t startAddr, uint64_t &foundAddr); // Global counters for diagnostics: -int initialize_timer(); -extern uint64_t llvm_interval_counter; extern std::map exitCounter; -extern std::map iterationCounter; extern std::map firstTriggerAddr; //tracestart addr extern std::map > backOffCounters; -// Good, bad backoff -void insert_address_at(uint64_t n, uint64_t m); -void doInstrumentation(uint64_t addr1, uint64_t addr2, VirtualMem *vm); - int reopt_threshold = DEFAULT_THRESHOLD_LEVEL_1; int exit_count=0; @@ -49,19 +48,15 @@ TraceCache *tr2; VirtualMem *vm; -void getFirstTrace(uint64_t addr1, uint64_t addr2, int depth, VirtualMem *vm, - TraceCache *tr){ - //addr1: the "target" of backward branch - //addr2: the PC of branch instruction - //to read any instruction at address addr1 do the following - // unsigned int instr = vm->readInstrFrmVm(addr); - doInstrumentation(addr1, addr2, vm); -} - +// Initialization method for the reoptimizer. A call to this function +// from main() is inserted by the opt -instloops pass +// (Transforms/Instrumentation/ProfilePaths/InstLoops.cpp). +// reoptimizerInitialize is passed a pointer to reopt_threshold in t +// (why?) extern "C" void reoptimizerInitialize(int *t){ vm = new VirtualMem(); tr = new TraceCache(30000, vm); - tr2 = new TraceCache(&dummyFunction2, 30000, vm); + tr2 = new TraceCache(dummyFunction2, 30000, vm); if(getenv("THRESHOLD_LEVEL_2")!=NULL) THRESHOLD_LEVEL_2 = atoi(getenv("THRESHOLD_LEVEL_2")); @@ -75,6 +70,10 @@ else reopt_threshold = DEFAULT_THRESHOLD_LEVEL_1; + // FIXME: This should not be necessary if we are already setting + // reopt_threshold above. Remove the junk from InstLoops.cpp that + // makes reopt_threshold visible to the called program, and remove + // this, later. *t=30; //initialize_timer(); @@ -102,45 +101,38 @@ SAVE_FPRS_REG(fprs_reg); SAVE_CCR_REG(ccr_reg); - // Maps of counters we use: + // This is where we keep the counter for each first-level + // instrumented branch. static map counterMap; - static map seenOccur; - // FIXME: What is brAddr? - uint64_t brAddr; -#ifdef __sparc - asm("add %%i7, %1, %0":"=r"(brAddr):"i" (0)); -#else - assert(false && "Case not handled for this processor architecture!"); -#endif + // Get return address of this invocation (on SPARC, this is in %i7). + uint64_t pcAddr = (uint64_t) __builtin_return_address(0); // Increment the counter for this branch, and check it against // THRESHOLD_LEVEL_1. If it exceeds the threshold, we may have to // generate second-level instrumentation (SLI). - if(++counterMap[brAddr] > reopt_threshold){ - counterMap.erase(brAddr); - //std::cerr<<"Originally Removed from addr: "<<(void *)brAddr<<"\n"; - - // Scan forward through memory starting from brAddr, looking for a branch - // instruction. - char offst = 8; - unsigned int brInst = vm->readInstrFrmVm(brAddr + offst, tr, tr2); - while(!isBranchInstr(brInst)){ - offst += 4; - brInst = vm->readInstrFrmVm(brAddr + offst, tr, tr2); - } - assert(isBranchInstr(brInst) && "Not a branch!"); - uint64_t brTarget = getBranchTarget(brInst, brAddr+offst); - firstTriggerAddr[brTarget] = brAddr; + if(++counterMap[pcAddr] > reopt_threshold){ + counterMap.erase(pcAddr); + //std::cerr<<"Originally Removed from addr: "<<(void *)pcAddr<<"\n"; + + // Scan forward through memory starting from pcAddr+8 looking for + // a branch instruction. The first one we find should be the + // backward branch that was instrumented. + uint64_t branchAddr; + uint32_t brInst = scanForBranch (pcAddr + 8, branchAddr); + + // Get the target of the (assumed backward) branch we found. + uint64_t brTarget = getBranchTarget (brInst, branchAddr); + firstTriggerAddr[brTarget] = pcAddr; // Check if trace cache already has optimized code. If it does, // we do not generate SLI. - if(!tr->hasTraceAddr(brTarget, brAddr+offst)) { + if(!tr->hasTraceAddr(brTarget, branchAddr)) { // No optimized code in trace cache; generate SLI now. - getFirstTrace(brTarget, brAddr+offst, 100, vm, tr); + doInstrumentation(brTarget, branchAddr, vm); } else { #ifdef GET_ALL_INFO - std::cerr<<"SLI-exists\t"<<(void *)brTarget<<"\t"<<(void *)(brTarget+offst)<<"\n"; + std::cerr<<"SLI-exists\t"<<(void *)brTarget<<"\t"<<(void *)branchAddr<<"\n"; #endif // Write a branch going to the top of the trace in tr. uint64_t traceAddrInTC = tr->getStartAddr(brTarget); @@ -150,12 +142,17 @@ doFlush(brTarget-16, brTarget+16); doFlush(traceAddrInTC-16, traceAddrInTC+16); } - - assert(isCallInstr(vm->readInstrFrmVm(brAddr, tr, tr2)) && "not call"); - vm->writeInstToVM(brAddr, NOP); - doFlush(brAddr-8, brAddr+16); + + // Overwrite the call instruction that called llvm_first_trigger + // with a NOP, thus turning off first-level instrumentation for + // this branch. + assert(isCallInstr(vm->readInstrFrmVm(pcAddr, tr, tr2)) && + "Couldn't find call instruction that called llvm_first_trigger"); + vm->writeInstToVM(pcAddr, NOP); + doFlush(pcAddr-8, pcAddr+16); } - + + // FIXME: Why are these here? fprs_reg ^= 0; ccr_reg ^= 0; Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.6 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.7 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.6 Tue Aug 5 15:00:18 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Wed Aug 6 16:52:05 2003 @@ -8,6 +8,9 @@ // //===----------------------------------------------------------------------===// +#include "GetTimer.h" +#include "RegSaveRestore.h" +#include "Timer.h" #include "llvm/Reoptimizer/Mapping/LLVMinfo.h" #include "llvm/Reoptimizer/VirtualMem.h" #include "llvm/Reoptimizer/InstrUtils.h" @@ -16,12 +19,9 @@ #include "llvm/iTerminators.h" #include "llvm/Support/CFG.h" #include "llvm/Module.h" -#include "GetTimer.h" -#include "RegSaveRestore.h" #include #include #include - #ifdef __sparc #include #endif @@ -30,12 +30,13 @@ using std::vector; using std::pair; -extern "C" void llvm_time_end2(); -extern "C" void llvm_time_start(); - #define CALL 0x40000000 long THRESHOLD_LEVEL_2; + +// If a trace selected as "hot" is exited more than a certain number +// of times, then it will be rejected; this certain number is set to +// 1/3 of the THRESHOLD_LEVEL_2 value. long LEVEL_TWO_EXITS; extern TraceCache *tr; @@ -48,22 +49,23 @@ extern "C" void llvm_first_trigger(int *cnt); -//global counters for diagonistcs void insert_address_at(uint64_t n, uint64_t m); + +// Forward declarations void generateTraces(uint64_t start, uint64_t end, std::vector &paths, uint64_t firstLevelTraceStartAddr); void getReturnCode(vector &traces, int &index, uint64_t ret); -extern uint64_t llvm_interval_counter; std::map exitCounter; -//std::map iterationCounter; std::map firstTriggerAddr; //tracestart addr std::map > backOffCounters; void triggerBB(vector &vBB, VirtualMem *vm, TraceCache *tr, - TraceCache *tr2, uint64_t a); + TraceCache *tr2, uint64_t a) { + std::cerr << "We made it to triggerBB\n"; +} extern "C" void llvm_time_start(){ #ifdef __sparc @@ -101,13 +103,15 @@ SAVE_FPRS_REG(fprs_reg); SAVE_CCR_REG(ccr_reg); - uint64_t brAddr; -#ifdef __sparc - asm("add %%i7, %1, %0":"=r"(brAddr):"i" (0)); -#endif + // Get return address of this invocation (on SPARC, this is in %i7). + uint64_t brAddr = (uint64_t) __builtin_return_address(0); + uint64_t reverseAddr = tr->getOriginalAddress(tr->getAddrLessThan(brAddr)); + + // Increment the number of times we have exited the trace. int accumulate = exitCounter[reverseAddr]++; - + + // If we've exited the trace more than LEVEL_TWO_EXITS times, then... if(accumulate > LEVEL_TWO_EXITS){ #ifdef GET_ALL_INFO @@ -121,7 +125,6 @@ delete pathCounter[reverseAddr]; pathCounter.erase(reverseAddr); totalCount[reverseAddr] = 0; - // iterationCounter[reverseAddr] = 0; tr->patchTrace(tr->getAddrLessThan(brAddr)); if(!backOffCounters[reverseAddr].second) @@ -187,6 +190,23 @@ } } +/// Scan forward through memory starting from startAddr looking for a +/// branch instruction. When one is found, foundAddr is set to its +/// address, and the instruction word itself is returned. +/// +uint32_t scanForBranch (const uint64_t startAddr, uint64_t &foundAddr) +{ + uint64_t addr = startAddr; + uint32_t instr = vm->readInstrFrmVm (addr, tr, tr2); + while (!isBranchInstr (instr)) { + addr += 4; + instr = vm->readInstrFrmVm (addr, tr, tr2); + } + foundAddr = addr; + assert (isBranchInstr (instr) && "scanForBranch: Found instr not a branch!"); + return instr; +} + void countPath () { uint64_t branchHist; uint64_t i_reg_save[6]; @@ -197,6 +217,7 @@ uint64_t fsr_reg; uint64_t g1_reg; + // Save registers on the stack in variables declared above. SAVE_I_REGS(i_reg_save); SAVE_G1_REG(branchHist); SAVE_G1_REG(g1_reg); @@ -207,27 +228,19 @@ SAVE_FPRS_REG(fprs_reg); SAVE_CCR_REG(ccr_reg); - uint64_t pcAddr, startAddr, endAddr; - - //get the PC address for call to trigger -#ifdef __sparc - asm volatile("add %%i7, %1, %0":"=r"(pcAddr):"i" (0)); -#else - assert(false && "Case not handled for this processor architecture!"); -#endif - - unsigned int offst = 4; - unsigned int branchInstr; - do{ - offst += 4; - branchInstr = vm->readInstrFrmVm(pcAddr+offst, tr, tr2); - }while(!isBranchInstr(branchInstr)); - - endAddr = pcAddr + offst+4; //until delay slot! + // Get return address -- that is, the PC where this call to countPath + // was made (on SPARC, this is in %i7). + uint64_t pcAddr = (uint64_t) __builtin_return_address(0); + + // Scan forward through memory starting from pcAddr+8 looking for a + // branch instruction. + uint64_t branchAddr; + uint32_t branchInstr = scanForBranch (pcAddr + 8, branchAddr); + uint64_t endAddr = branchAddr + 4; // Address of branch delay slot. - startAddr = getBranchTarget(branchInstr, pcAddr+offst); + // Get the target of the branch we found. + uint64_t startAddr = getBranchTarget(branchInstr, branchAddr); uint64_t reverseAddr = tr->getOriginalAddress(startAddr); - //++iterationCounter[reverseAddr]; pcAddr = reverseAddr; @@ -254,7 +267,6 @@ delete pathCounter[pcAddr]; pathCounter.erase(pcAddr); totalCount[pcAddr] = 0; - //iterationCounter[reverseAddr] = 0; exitCounter[reverseAddr] = 0; tr->patchTrace(startAddr); @@ -280,7 +292,6 @@ int total = totalCount[pcAddr]; - // iterationCounter[reverseAddr] = 0; exitCounter[reverseAddr] = 0; if(!backOffCounters[reverseAddr].first) backOffCounters[reverseAddr].first = 1; @@ -336,7 +347,6 @@ delete pathCounter[pcAddr]; pathCounter.erase(pcAddr); totalCount[pcAddr] = 0; - // iterationCounter[reverseAddr] = 0; exitCounter[reverseAddr] = 0; tr->patchTrace(startAddr); From brukman at cs.uiuc.edu Wed Aug 6 17:20:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Aug 6 17:20:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Message-ID: <200308062219.RAA27739@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcV9CodeEmitter.cpp updated: 1.25 -> 1.26 --- Log message: Use the registers g1 and g5 as temporaries for making far jumps and far calls, because saving i1 and i2 to their ``designated'' stack slots corrupts unknown memory in other functions, standard libraries, and worse. In addition, this has the benefit of improving JIT performance because we eliminate writing out 4 instructions in CompilationCallback() and 2 loads and 2 stores. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.25 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.26 --- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.25 Wed Aug 6 11:20:22 2003 +++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Wed Aug 6 17:19:18 2003 @@ -128,37 +128,29 @@ static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2, i7 = SparcIntRegClass::i7, - o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0; + o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0, + g1 = SparcIntRegClass::g1, g5 = SparcIntRegClass::g5; MachineInstr* BinaryCode[] = { // - // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 + // Get address to branch into %g1, using %g5 as a temporary // - // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp - BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119), - // stx %i2, [%sp + 2127] ;; save %i2 to the stack - BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127), - // - // Get address to branch into %i2, using %i1 as a temporary - // - // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1 - BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1), - // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1 - BuildMI(V9::ORi, 3).addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1), - // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word - BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1), - // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg - BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2), - // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2 - BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2), - // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2 - BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2), - // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72 - BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1), - // jmpl %i2, %g0, %g0 ;; indirect branch on %i2 - BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(g0), - // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80 - BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2) + // sethi %uhi(Target), %g5 ;; get upper 22 bits of Target into %g5 + BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(g5), + // or %g5, %ulo(Target), %g5 ;; get 10 lower bits of upper word into %g5 + BuildMI(V9::ORi, 3).addReg(g5).addSImm((Target >> 32) & 0x03ff).addReg(g5), + // sllx %g5, 32, %g5 ;; shift those 10 bits to the upper word + BuildMI(V9::SLLXi6, 3).addReg(g5).addSImm(32).addReg(g5), + // sethi %hi(Target), %g1 ;; extract bits 10-31 into the dest reg + BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(g1), + // or %g5, %g1, %g1 ;; get upper word (in %i1) into %g1 + BuildMI(V9::ORr, 3).addReg(g5).addReg(g1).addReg(g1), + // or %g1, %lo(Target), %g1 ;; get lowest 10 bits of Target into %g1 + BuildMI(V9::ORi, 3).addReg(g1).addSImm(Target & 0x03ff).addReg(g1), + // jmpl %g1, %g0, %g0 ;; indirect branch on %g1 + BuildMI(V9::JMPLRETr, 3).addReg(g1).addReg(g0).addReg(g0), + // nop ;; delay slot + BuildMI(V9::NOP, 0) }; for (unsigned i=0, e=sizeof(BinaryCode)/sizeof(BinaryCode[0]); i!=e; ++i) { @@ -188,9 +180,9 @@ static const unsigned o6 = SparcIntRegClass::o6; // Subtract enough to overwrite up to the 'save' instruction - // This depends on whether we made a short call (1 instruction) to the - // farCall (10 instructions) - uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 40; + // This depends on whether we made a short call (1 instruction) or the + // farCall (long form: 10 instructions, short form: 7 instructions) + uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 28; uint64_t CodeBegin = CameFrom - Offset; // Make sure that what we're about to overwrite is indeed "save" @@ -257,12 +249,12 @@ int64_t Addr = (int64_t)addFunctionReference(CurrPC, F); int64_t CallTarget = (Addr-CurrPC) >> 2; //if (CallTarget >= (1 << 29) || CallTarget <= -(1 << 29)) { - // Since this is a far call, the actual address of the call is shifted - // by the number of instructions it takes to calculate the exact address + // Since this is a far call, the actual address of the call is shifted + // by the number of instructions it takes to calculate the exact address deleteFunctionReference(CurrPC); SparcV9.emitFarCall(Addr, F); #if 0 - } else { + else { // call CallTarget ;; invoke the callback MachineInstr *Call = BuildMI(V9::CALL, 1).addSImm(CallTarget); SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Call)); @@ -368,43 +360,35 @@ // being accounted for, and the behavior will be incorrect!! inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target, Function *F) { static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2, - i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6, - o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0; + i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6, + o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0, + g1 = SparcIntRegClass::g1, g5 = SparcIntRegClass::g5; MachineInstr* BinaryCode[] = { - // - // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 - // - // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp - BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119), - // stx %i2, [%sp + 2127] ;; save %i2 to the stack - BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127), // - // Get address to branch into %i2, using %i1 as a temporary + // Get address to branch into %g1, using %g5 as a temporary // - // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1 - BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1), - // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1 - BuildMI(V9::ORi, 3).addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1), - // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word - BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1), - // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg - BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2), - // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2 - BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2), - // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2 - BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2), - // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72 - BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1), - // jmpl %i2, %g0, %o7 ;; indirect call on %i2 - BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(o7), - // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80 - BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2) + // sethi %uhi(Target), %g5 ;; get upper 22 bits of Target into %g5 + BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(g5), + // or %g5, %ulo(Target), %g5 ;; get 10 lower bits of upper word into %1 + BuildMI(V9::ORi, 3).addReg(g5).addSImm((Target >> 32) & 0x03ff).addReg(g5), + // sllx %g5, 32, %g5 ;; shift those 10 bits to the upper word + BuildMI(V9::SLLXi6, 3).addReg(g5).addSImm(32).addReg(g5), + // sethi %hi(Target), %g1 ;; extract bits 10-31 into the dest reg + BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(g1), + // or %g5, %g1, %g1 ;; get upper word (in %g5) into %g1 + BuildMI(V9::ORr, 3).addReg(g5).addReg(g1).addReg(g1), + // or %g1, %lo(Target), %g1 ;; get lowest 10 bits of Target into %g1 + BuildMI(V9::ORi, 3).addReg(g1).addSImm(Target & 0x03ff).addReg(g1), + // jmpl %g1, %g0, %o7 ;; indirect call on %g1 + BuildMI(V9::JMPLRETr, 3).addReg(g1).addReg(g0).addReg(o7), + // nop ;; delay slot + BuildMI(V9::NOP, 0) }; for (unsigned i=0, e=sizeof(BinaryCode)/sizeof(BinaryCode[0]); i!=e; ++i) { // This is where we save the return address in the LazyResolverMap!! - if (i == 9 && F != 0) { // Do this right before the JMPL + if (i == 6 && F != 0) { // Do this right before the JMPL uint64_t CurrPC = MCE.getCurrentPCValue(); TheJITResolver->addFunctionReference(CurrPC, F); // Remember that this is a far call, to subtract appropriate offset later @@ -474,14 +458,14 @@ } } } - DEBUG(std::cerr << "Global addr: " << rv << "\n"); + DEBUG(std::cerr << "Global addr: 0x" << std::hex << rv << "\n"); } // The real target of the call is Addr = PC + (rv * 4) // So undo that: give the instruction (Addr - PC) / 4 if (MI.getOpcode() == V9::CALL) { int64_t CurrPC = MCE.getCurrentPCValue(); DEBUG(std::cerr << "rv addr: 0x" << std::hex << rv << "\n" - << "curr PC: 0x" << CurrPC << "\n"); + << "curr PC: 0x" << std::hex << CurrPC << "\n"); int64_t CallInstTarget = (rv - CurrPC) >> 2; if (CallInstTarget >= (1<<29) || CallInstTarget <= -(1<<29)) { DEBUG(std::cerr << "Making far call!\n"); From lattner at cs.uiuc.edu Wed Aug 6 17:30:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 17:30:02 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Message-ID: <200308062229.RAA27003@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.25 -> 1.26 --- Log message: There is something wrong with code that looks like: if (R == 0 || ...) R->getName() --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.25 llvm/utils/TableGen/Record.cpp:1.26 --- llvm/utils/TableGen/Record.cpp:1.25 Mon Aug 4 15:44:17 2003 +++ llvm/utils/TableGen/Record.cpp Wed Aug 6 17:29:04 2003 @@ -517,7 +517,7 @@ Init *Record::getValueInit(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; return R->getValue(); } @@ -530,12 +530,12 @@ std::string Record::getValueAsString(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; if (const StringInit *SI = dynamic_cast(R->getValue())) return SI->getValue(); - throw "Record '" + R->getName() + "', field '" + FieldName + + throw "Record '" + getName() + "', field '" + FieldName + "' does not have a string initializer!"; } @@ -546,12 +546,12 @@ BitsInit *Record::getValueAsBitsInit(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; if (BitsInit *BI = dynamic_cast(R->getValue())) return BI; - throw "Record '" + R->getName() + "', field '" + FieldName + + throw "Record '" + getName() + "', field '" + FieldName + "' does not have a BitsInit initializer!"; } @@ -562,12 +562,12 @@ ListInit *Record::getValueAsListInit(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; if (ListInit *LI = dynamic_cast(R->getValue())) return LI; - throw "Record '" + R->getName() + "', field '" + FieldName + + throw "Record '" + getName() + "', field '" + FieldName + "' does not have a list initializer!"; } @@ -578,12 +578,12 @@ int Record::getValueAsInt(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; if (IntInit *II = dynamic_cast(R->getValue())) return II->getValue(); - throw "Record '" + R->getName() + "', field '" + FieldName + + throw "Record '" + getName() + "', field '" + FieldName + "' does not have a list initializer!"; } @@ -594,12 +594,12 @@ Record *Record::getValueAsDef(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; if (DefInit *DI = dynamic_cast(R->getValue())) return DI->getDef(); - throw "Record '" + R->getName() + "', field '" + FieldName + + throw "Record '" + getName() + "', field '" + FieldName + "' does not have a list initializer!"; } @@ -610,12 +610,12 @@ bool Record::getValueAsBit(const std::string &FieldName) const { const RecordVal *R = getValue(FieldName); if (R == 0 || R->getValue() == 0) - throw "Record '" + R->getName() + "' does not have a field named '" + + throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; if (BitInit *DI = dynamic_cast(R->getValue())) return DI->getValue(); - throw "Record '" + R->getName() + "', field '" + FieldName + + throw "Record '" + getName() + "', field '" + FieldName + "' does not have a list initializer!"; } From lattner at cs.uiuc.edu Wed Aug 6 18:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 18:01:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200308062300.SAA28278@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.30 -> 1.31 --- Log message: Add accessor --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.30 llvm/utils/TableGen/Record.h:1.31 --- llvm/utils/TableGen/Record.h:1.30 Mon Aug 4 15:44:17 2003 +++ llvm/utils/TableGen/Record.h Wed Aug 6 18:00:31 2003 @@ -601,6 +601,7 @@ } Record *getNodeType() const { return NodeTypeDef; } + const std::vector getArgs() const { return Args; } virtual void print(std::ostream &OS) const; }; From lattner at cs.uiuc.edu Wed Aug 6 18:02:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 18:02:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200308062301.SAA28297@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.31 -> 1.32 --- Log message: Ick, add the RIGHT accessor --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.31 llvm/utils/TableGen/Record.h:1.32 --- llvm/utils/TableGen/Record.h:1.31 Wed Aug 6 18:00:31 2003 +++ llvm/utils/TableGen/Record.h Wed Aug 6 18:01:18 2003 @@ -601,7 +601,7 @@ } Record *getNodeType() const { return NodeTypeDef; } - const std::vector getArgs() const { return Args; } + const std::vector &getArgs() const { return Args; } virtual void print(std::ostream &OS) const; }; From brukman at cs.uiuc.edu Wed Aug 6 18:07:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Aug 6 18:07:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.cpp Message-ID: <200308062306.SAA27909@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: Sparc.cpp updated: 1.71 -> 1.72 --- Log message: * Renamed option from `nopreselect' to `nopreopt' since it disables more than just PreSelection * Wrapped code at 80 columns * Added the DecomposeMultiDimRefs Pass to the JIT compilation path --- Diffs of the changes: Index: llvm/lib/Target/Sparc/Sparc.cpp diff -u llvm/lib/Target/Sparc/Sparc.cpp:1.71 llvm/lib/Target/Sparc/Sparc.cpp:1.72 --- llvm/lib/Target/Sparc/Sparc.cpp:1.71 Fri Aug 1 10:53:24 2003 +++ llvm/lib/Target/Sparc/Sparc.cpp Wed Aug 6 18:06:21 2003 @@ -38,8 +38,8 @@ // Command line options to control choice of code generation passes. //--------------------------------------------------------------------------- -static cl::opt DisablePreSelect("nopreselect", - cl::desc("Disable preselection pass")); +static cl::opt DisablePreOpt("nopreopt", + cl::desc("Disable optimizations prior to instruction selection")); static cl::opt DisableSched("nosched", cl::desc("Disable local scheduling pass")); @@ -171,10 +171,10 @@ //so %fp+offset-8 and %fp+offset-16 are empty slots now! PM.add(createStackSlotsPass(*this)); - // Specialize LLVM code for this target machine and then - // run basic dataflow optimizations on LLVM code. - if (!DisablePreSelect) { + if (!DisablePreOpt) { + // Specialize LLVM code for this target machine PM.add(createPreSelectionPass(*this)); + // Run basic dataflow optimizations on LLVM code PM.add(createReassociatePass()); PM.add(createLICMPass()); PM.add(createGCSEPass()); @@ -182,7 +182,8 @@ // If LLVM dumping after transformations is requested, add it to the pipeline if (DumpInput) - PM.add(new PrintFunctionPass("Input code to instr. selection: \n", &std::cerr)); + PM.add(new PrintFunctionPass("Input code to instsr. selection:\n", + &std::cerr)); PM.add(createInstructionSelectionPass(*this)); @@ -233,6 +234,9 @@ // FIXME: implement the switch instruction in the instruction selector. PM.add(createLowerSwitchPass()); + // decompose multi-dimensional array references into single-dim refs + PM.add(createDecomposeMultiDimRefsPass()); + // Construct and initialize the MachineFunction object for this fn. PM.add(createMachineCodeConstructionPass(*this)); From brukman at cs.uiuc.edu Wed Aug 6 18:26:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Aug 6 18:26:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.cpp Message-ID: <200308062325.SAA28001@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: Sparc.cpp updated: 1.72 -> 1.73 --- Log message: Changing command-line option formats to be more consistent with LLVM style. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/Sparc.cpp diff -u llvm/lib/Target/Sparc/Sparc.cpp:1.72 llvm/lib/Target/Sparc/Sparc.cpp:1.73 --- llvm/lib/Target/Sparc/Sparc.cpp:1.72 Wed Aug 6 18:06:21 2003 +++ llvm/lib/Target/Sparc/Sparc.cpp Wed Aug 6 18:25:25 2003 @@ -38,13 +38,13 @@ // Command line options to control choice of code generation passes. //--------------------------------------------------------------------------- -static cl::opt DisablePreOpt("nopreopt", +static cl::opt DisablePreOpt("disable-preopt", cl::desc("Disable optimizations prior to instruction selection")); -static cl::opt DisableSched("nosched", +static cl::opt DisableSched("disable-sched", cl::desc("Disable local scheduling pass")); -static cl::opt DisablePeephole("nopeephole", +static cl::opt DisablePeephole("disable-peephole", cl::desc("Disable peephole optimization pass")); static cl::opt From lattner at cs.uiuc.edu Wed Aug 6 19:18:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 19:18:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200308070017.TAA10129@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.2 -> 1.3 --- Log message: There was no reason for these to be bit-fields, they just need to be unique. Also, add an isVoid item --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.2 llvm/include/llvm/CodeGen/ValueTypes.h:1.3 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.2 Tue Jul 29 00:15:44 2003 +++ llvm/include/llvm/CodeGen/ValueTypes.h Wed Aug 6 19:17:00 2003 @@ -14,18 +14,22 @@ /// namespace MVT { // MVT = Machine Value Types enum ValueType { - Other = 0 << 0, // This is a non-standard value - i1 = 1 << 0, // This is a 1 bit integer value - i8 = 1 << 1, // This is an 8 bit integer value - i16 = 1 << 2, // This is a 16 bit integer value - i32 = 1 << 3, // This is a 32 bit integer value - i64 = 1 << 4, // This is a 64 bit integer value - i128 = 1 << 5, // This is a 128 bit integer value + // If you change this numbering, you must change the values in Target.td as + // well! + Other = 0, // This is a non-standard value + i1 = 1, // This is a 1 bit integer value + i8 = 2, // This is an 8 bit integer value + i16 = 3, // This is a 16 bit integer value + i32 = 4, // This is a 32 bit integer value + i64 = 5, // This is a 64 bit integer value + i128 = 6, // This is a 128 bit integer value - f32 = 1 << 6, // This is a 32 bit floating point value - f64 = 1 << 7, // This is a 64 bit floating point value - f80 = 1 << 8, // This is a 80 bit floating point value - f128 = 1 << 9, // This is a 128 bit floating point value + f32 = 7, // This is a 32 bit floating point value + f64 = 8, // This is a 64 bit floating point value + f80 = 9, // This is a 80 bit floating point value + f128 = 10, // This is a 128 bit floating point value + + isVoid = 11, // This has no value }; }; From kowshik at cs.uiuc.edu Wed Aug 6 23:39:01 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Wed Aug 6 23:39:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/PoolAllocate.h Message-ID: <200308070438.XAA15403@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: PoolAllocate.h updated: 1.5 -> 1.6 --- Log message: Added a flag which is set when all data structures are not pool allocated --- Diffs of the changes: Index: llvm/include/llvm/Transforms/PoolAllocate.h diff -u llvm/include/llvm/Transforms/PoolAllocate.h:1.5 llvm/include/llvm/Transforms/PoolAllocate.h:1.6 --- llvm/include/llvm/Transforms/PoolAllocate.h:1.5 Tue Aug 5 11:56:59 2003 +++ llvm/include/llvm/Transforms/PoolAllocate.h Wed Aug 6 23:37:52 2003 @@ -100,6 +100,11 @@ // If an equivalence class does not require pool arguments, it is not // on this map. std::map EqClass2LastPoolArg; + + // Exception flags + // CollapseFlag set if all data structures are not pool allocated, due to + // collapsing of nodes in the DS graph + unsigned CollapseFlag; public: bool run(Module &M); From lattner at cs.uiuc.edu Wed Aug 6 23:50:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 6 23:50:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.td Message-ID: <200308070449.XAA16435@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.td updated: 1.5 -> 1.6 --- Log message: This register is never used, disable it. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.5 llvm/lib/Target/X86/X86RegisterInfo.td:1.6 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.5 Mon Aug 4 15:58:29 2003 +++ llvm/lib/Target/X86/X86RegisterInfo.td Wed Aug 6 23:49:16 2003 @@ -45,7 +45,7 @@ // This is a slimy hack to make it possible to say that flags are clobbered... // Ideally we'd model instructions based on which particular flag(s) they // could clobber. - def EFLAGS : Register; + //def EFLAGS : Register; } //===----------------------------------------------------------------------===// @@ -96,5 +96,5 @@ // Registers which cannot be allocated... and are thus left unnamed. def : RegisterClass; -def : RegisterClass; +//def : RegisterClass; From kowshik at cs.uiuc.edu Thu Aug 7 00:30:02 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Thu Aug 7 00:30:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200308070529.AAA18325@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.14 -> 1.15 --- Log message: Added code for pool allocating only the pool-allocatable data structures in the presence of collapsed nodes + a couple of bug fixes --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.14 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.15 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.14 Tue Aug 5 13:44:12 2003 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Thu Aug 7 00:29:28 2003 @@ -163,6 +163,9 @@ ProcessFunctionBody(*I, FI != FuncMap.end() ? *FI->second : *I); } + if (CollapseFlag) + std::cerr << "Pool Allocation successful! However all data structures may not be pool allocated\n"; + return true; } @@ -392,6 +395,8 @@ assert ((FI.ArgNodes.size() == (unsigned) (FI.PoolArgLast - FI.PoolArgFirst)) && "Number of ArgNodes equal to the number of pool arguments used by this function"); + + if (FI.ArgNodes.empty()) return 0; } @@ -412,6 +417,7 @@ Function::aiterator NI = New->abegin(); if (FuncECs.findClass(&F)) { + // If the function belongs to an equivalence class for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i, ++NI) NI->setName("PDa"); @@ -421,15 +427,15 @@ for (int i = 0; i < FI.PoolArgFirst; ++NI, ++i) ; - if (FI.ArgNodes.size() > 0) - for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) - PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI)); + for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) + PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI)); NI = New->abegin(); if (EqClass2LastPoolArg.count(FuncECs.findClass(&F))) for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i, ++NI) ; } else { + // If the function does not belong to an equivalence class if (FI.ArgNodes.size()) for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) { NI->setName("PDa"); // Add pd entry @@ -536,7 +542,8 @@ if (Node->getType() != Type::VoidTy) ElSize = ConstantUInt::get(Type::UIntTy, TD.getTypeSize(Node->getType())); else { - std::cerr << "Potential node collapsing in " << F.getName() << "\n"; + DEBUG(std::cerr << "Potential node collapsing in " << F.getName() + << ". All Data Structures may not be pool allocated\n"); ElSize = ConstantUInt::get(Type::UIntTy, 0); } @@ -604,12 +611,37 @@ return G.getScalarMap()[V]; } - + + DSNodeHandle& getTDDSNodeHFor(Value *V) { + if (!FI.NewToOldValueMap.empty()) { + // If the NewToOldValueMap is in effect, use it. + std::map::iterator I = FI.NewToOldValueMap.find(V); + if (I != FI.NewToOldValueMap.end()) + V = (Value*)I->second; + } + + return TDG.getScalarMap()[V]; + } + Value *getPoolHandle(Value *V) { DSNode *Node = getDSNodeHFor(V).getNode(); // Get the pool handle for this DSNode... std::map::iterator I = FI.PoolDescriptors.find(Node); - return I != FI.PoolDescriptors.end() ? I->second : 0; + + if (I != FI.PoolDescriptors.end()) { + // Check that the node pointed to by V in the TD DS graph is not + // collapsed + DSNode *TDNode = getTDDSNodeHFor(V).getNode(); + if (TDNode->getType() != Type::VoidTy) + return I->second; + else { + PAInfo.CollapseFlag = 1; + return 0; + } + } + else + return 0; + } bool isFuncPtr(Value *V); @@ -765,8 +797,10 @@ void FuncTransform::visitMallocInst(MallocInst &MI) { // Get the pool handle for the node that this contributes to... Value *PH = getPoolHandle(&MI); - if (PH == 0) return; + // NB: PH is zero even if the node is collapsed + if (PH == 0) return; + // Insert a call to poolalloc Value *V; if (MI.isArrayAllocation()) @@ -878,7 +912,7 @@ if (numCallerLinks > 0) { if (numCallerLinks < numCalleeLinks) { - std::cerr << "Potential node collapsing in caller\n"; + DEBUG(std::cerr << "Potential node collapsing in caller\n"); for (unsigned i = 0, e = numCalleeLinks; i != e; ++i) CalcNodeMapping(CallerNode->getLink(((i%numCallerLinks) << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping); } else { @@ -886,8 +920,8 @@ CalcNodeMapping(CallerNode->getLink((i << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping); } } else if (numCalleeLinks > 0) { - std::cerr << - "Caller has unexpanded node, due to indirect call perhaps!\n"; + DEBUG(std::cerr << + "Caller has unexpanded node, due to indirect call perhaps!\n"); } } } @@ -1112,8 +1146,8 @@ Function *FuncClass = PAInfo.FuncECs.findClass(CF); if (PAInfo.EqClass2LastPoolArg.count(FuncClass)) - for (unsigned i = CFI->PoolArgLast; - i <= PAInfo.EqClass2LastPoolArg.count(FuncClass); ++i) + for (int i = CFI->PoolArgLast; + i <= PAInfo.EqClass2LastPoolArg[FuncClass]; ++i) Args.push_back(Constant::getNullValue(PoolDescPtr)); // Add the rest of the arguments... From kowshik at cs.uiuc.edu Thu Aug 7 00:32:02 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Thu Aug 7 00:32:02 2003 Subject: [llvm-commits] CVS: llvm/test/Libraries/libpoolalloc/PoolAllocatorChained.c Message-ID: <200308070531.AAA18352@apoc.cs.uiuc.edu> Changes in directory llvm/test/Libraries/libpoolalloc: PoolAllocatorChained.c updated: 1.2 -> 1.3 --- Log message: Change implementation so that variable sized slabs are used to allow arbitrary sized array allocations --- Diffs of the changes: Index: llvm/test/Libraries/libpoolalloc/PoolAllocatorChained.c diff -u llvm/test/Libraries/libpoolalloc/PoolAllocatorChained.c:1.2 llvm/test/Libraries/libpoolalloc/PoolAllocatorChained.c:1.3 --- llvm/test/Libraries/libpoolalloc/PoolAllocatorChained.c:1.2 Thu Jul 3 12:55:47 2003 +++ llvm/test/Libraries/libpoolalloc/PoolAllocatorChained.c Thu Aug 7 00:31:04 2003 @@ -1,11 +1,17 @@ #include +#include #include #undef assert #define assert(X) -#define NODES_PER_SLAB 65536 +/* In the current implementation, each slab in the pool has NODES_PER_SLAB + * nodes unless the isSingleArray flag is set in which case it contains a + * single array of size ArraySize. Small arrays (size <= NODES_PER_SLAB) are + * still allocated in the slabs of size NODES_PER_SLAB + */ +#define NODES_PER_SLAB 512 typedef struct PoolTy { void *Data; @@ -24,6 +30,11 @@ struct PoolSlab *Next; unsigned char AllocatedBitVector[NODES_PER_SLAB/8]; unsigned char StartOfAllocation[NODES_PER_SLAB/8]; + + unsigned isSingleArray; /* If this slab is used for exactly one array */ + /* The array is allocated from the start to the end of the slab */ + unsigned ArraySize; /* The size of the array allocated */ + char Data[1]; /* Buffer to hold data in this slab... variable sized */ } PoolSlab; @@ -45,7 +56,10 @@ /* poolinit - Initialize a pool descriptor to empty */ void poolinit(PoolTy *Pool, unsigned NodeSize) { - assert(Pool && "Null pool pointer passed into poolinit!"); + if (!Pool) { + printf("Null pool pointer passed into poolinit!\n"); + exit(1); + } Pool->NodeSize = NodeSize; Pool->Data = 0; @@ -55,7 +69,11 @@ } void poolmakeunfreeable(PoolTy *Pool) { - assert(Pool && "Null pool pointer passed in to poolmakeunfreeable!"); + if (!Pool) { + printf("Null pool pointer passed in to poolmakeunfreeable!\n"); + exit(1); + } + Pool->FreeablePool = 0; } @@ -63,7 +81,11 @@ */ void pooldestroy(PoolTy *Pool) { PoolSlab *PS; - assert(Pool && "Null pool pointer passed in to pooldestroy!"); + if (!Pool) { + printf("Null pool pointer passed in to pooldestroy!\n"); + exit(1); + } + PS = (PoolSlab*)Pool->Data; while (PS) { PoolSlab *Next = PS->Next; @@ -75,6 +97,12 @@ static void *FindSlabEntry(PoolSlab *PS, unsigned NodeSize) { /* Loop through all of the slabs looking for one with an opening */ for (; PS; PS = PS->Next) { + + /* If the slab is a single array, go on to the next slab */ + /* Don't allocate single nodes in a SingleArray slab */ + if (PS->isSingleArray) + continue; + /* Check to see if there are empty entries at the end of the slab... */ if (PS->LastUsed < NODES_PER_SLAB-1) { /* Mark the returned entry used */ @@ -118,8 +146,16 @@ PoolSlab *PS; void *Result; - assert(Pool && "Null pool pointer passed in to poolalloc!"); + if (!Pool) { + printf("Null pool pointer passed in to poolalloc!\n"); + exit(1); + } + NodeSize = Pool->NodeSize; + // Return if this pool has size 0 + if (NodeSize == 0) + return 0; + PS = (PoolSlab*)Pool->Data; if ((Result = FindSlabEntry(PS, NodeSize))) @@ -128,11 +164,17 @@ /* Otherwise we must allocate a new slab and add it to the list */ PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); - assert (PS && "Could not allocate memory!"); + if (!PS) { + printf("poolalloc: Could not allocate memory!"); + exit(1); + } /* Initialize the slab to indicate that the first element is allocated */ PS->FirstUnused = 1; PS->LastUsed = 0; + /* This is not a single array */ + PS->isSingleArray = 0; + PS->ArraySize = 0; MARK_NODE_ALLOCATED(PS, 0); SET_START_BIT(PS, 0); @@ -149,56 +191,97 @@ PoolSlab **PPS; unsigned idxiter; - assert(Pool && "Null pool pointer passed in to poolfree!"); + if (!Pool) { + printf("Null pool pointer passed in to poolfree!\n"); + exit(1); + } + NodeSize = Pool->NodeSize; + + // Return if this pool has size 0 + if (NodeSize == 0) + return; + PS = (PoolSlab*)Pool->Data; PPS = (PoolSlab**)&Pool->Data; - /* Seach for the slab that contains this node... */ - while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB] < Node) { - assert(PS && "free'd node not found in allocation pool specified!"); + /* Search for the slab that contains this node... */ + while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB-1] < Node) { + if (!PS) { + printf("poolfree: node being free'd not found in allocation pool specified!\n"); + exit(1); + } + PPS = &PS->Next; PS = PS->Next; } + /* PS now points to the slab where Node is */ + Idx = (Node-&PS->Data[0])/NodeSize; assert(Idx < NODES_PER_SLAB && "Pool slab searching loop broken!"); - assert(ALLOCATION_BEGINS(PS, Idx) && - "Attempt to free middle of allocated array"); + if (PS->isSingleArray) { - /* Free the first node */ - CLEAR_START_BIT(PS, Idx); - MARK_NODE_FREE(PS, Idx); - - // Free all nodes - idxiter = Idx + 1; - while (idxiter < NODES_PER_SLAB && (!ALLOCATION_BEGINS(PS,idxiter)) && - (NODE_ALLOCATED(PS, idxiter))) { - MARK_NODE_FREE(PS, idxiter); - } + /* If this slab is a SingleArray */ - /* Update the first free field if this node is below the free node line */ - if (Idx < PS->FirstUnused) PS->FirstUnused = Idx; - - /* If we are not freeing the last element in a slab... */ - if (idxiter - 1 != PS->LastUsed) { - return; - } + if (Idx != 0) { + printf("poolfree: Attempt to free middle of allocated array\n"); + exit(1); + } + if (!NODE_ALLOCATED(PS,0)) { + printf("poolfree: Attempt to free node that is already freed\n"); + exit(1); + } + /* Mark this SingleArray slab as being free by just marking the first + entry as free*/ + MARK_NODE_FREE(PS, 0); + } else { + + /* If this slab is not a SingleArray */ + + if (!ALLOCATION_BEGINS(PS, Idx)) { + printf("poolfree: Attempt to free middle of allocated array\n"); + } - /* Otherwise we are freeing the last element in a slab... shrink the - * LastUsed marker down to last used node. - */ - PS->LastUsed = Idx; - do { - --PS->LastUsed; - /* Fixme, this should scan the allocated array an entire byte at a time for - * performance! + /* Free the first node */ + if (!NODE_ALLOCATED(PS, Idx)) { + printf("poolfree: Attempt to free node that is already freed\n"); + exit(1); + } + CLEAR_START_BIT(PS, Idx); + MARK_NODE_FREE(PS, Idx); + + // Free all nodes + idxiter = Idx + 1; + while (idxiter < NODES_PER_SLAB && (!ALLOCATION_BEGINS(PS,idxiter)) && + (NODE_ALLOCATED(PS, idxiter))) { + MARK_NODE_FREE(PS, idxiter); + ++idxiter; + } + + /* Update the first free field if this node is below the free node line */ + if (Idx < PS->FirstUnused) PS->FirstUnused = Idx; + + /* If we are not freeing the last element in a slab... */ + if (idxiter - 1 != PS->LastUsed) { + return; + } + + /* Otherwise we are freeing the last element in a slab... shrink the + * LastUsed marker down to last used node. */ - } while (PS->LastUsed >= 0 && (!NODE_ALLOCATED(PS, PS->LastUsed))); - - assert(PS->FirstUnused <= PS->LastUsed+1 && - "FirstUnused field was out of date!"); + PS->LastUsed = Idx; + do { + --PS->LastUsed; + /* Fixme, this should scan the allocated array an entire byte at a time + * for performance! + */ + } while (PS->LastUsed >= 0 && (!NODE_ALLOCATED(PS, PS->LastUsed))); + + assert(PS->FirstUnused <= PS->LastUsed+1 && + "FirstUnused field was out of date!"); + } /* Ok, if this slab is empty, we unlink it from the of slabs and either move * it to the head of the list, or free it, depending on whether or not there @@ -206,33 +289,38 @@ */ /* Do this only if the pool is freeable */ if (Pool->FreeablePool) { - if (PS->LastUsed == -1) { /* Empty slab? */ + if (PS->isSingleArray) { + /* If it is a SingleArray, just free it */ + *PPS = PS->Next; + free(PS); + } else if (PS->LastUsed == -1) { /* Empty slab? */ PoolSlab *HeadSlab; *PPS = PS->Next; /* Unlink from the list of slabs... */ HeadSlab = (PoolSlab*)Pool->Data; - if (HeadSlab && HeadSlab->LastUsed == -1){/* List already has empty slab? */ - free(PS); /* Free memory for slab */ + if (HeadSlab && HeadSlab->LastUsed == -1){/*List already has empty slab?*/ + free(PS); /*Free memory for slab */ } else { - PS->Next = HeadSlab; /* No empty slab yet, add this */ - Pool->Data = PS; /* one to the head of the list */ + PS->Next = HeadSlab; /*No empty slab yet, add this*/ + Pool->Data = PS; /*one to the head of the list */ } } } else { /* Pool is not freeable for safety reasons */ /* Leave it in the list of PoolSlabs as an empty PoolSlab */ - if (PS->LastUsed == -1) { - PS->FirstUnused = 0; - - /* Do not free the pool, but move it to the head of the list if there is no - empty slab there already */ - PoolSlab *HeadSlab; - HeadSlab = (PoolSlab*)Pool->Data; - if (HeadSlab && HeadSlab->LastUsed != -1) { - PS->Next = HeadSlab; - Pool->Data = PS; + if (!PS->isSingleArray) + if (PS->LastUsed == -1) { + PS->FirstUnused = 0; + + /* Do not free the pool, but move it to the head of the list if there is + no empty slab there already */ + PoolSlab *HeadSlab; + HeadSlab = (PoolSlab*)Pool->Data; + if (HeadSlab && HeadSlab->LastUsed != -1) { + PS->Next = HeadSlab; + Pool->Data = PS; + } } - } } } @@ -243,6 +331,21 @@ /* Loop through all of the slabs looking for one with an opening */ for (; PS; PS = PS->Next) { + + /* For large array allocation */ + if (Size > NODES_PER_SLAB) { + /* If this slab is a SingleArray that is free with size > Size, use it */ + if (PS->isSingleArray && !NODE_ALLOCATED(PS,0) && PS->ArraySize >= Size) { + /* Allocate the array in this slab */ + MARK_NODE_ALLOCATED(PS,0); /* In a single array, only the first node + needs to be marked */ + return &PS->Data[0]; + } else + continue; + } else if (PS->isSingleArray) + continue; /* Do not allocate small arrays in SingleArray slabs */ + + /* For small array allocation */ /* Check to see if there are empty entries at the end of the slab... */ if (PS->LastUsed < NODES_PER_SLAB-Size) { /* Mark the returned entry used and set the start bit*/ @@ -277,7 +380,7 @@ foundArray = 0; if (foundArray) { - /* Successfully allocate out the first unused node */ + /* Successfully allocate starting from the first unused node */ SET_START_BIT(PS, Idx); for (i = Idx; i < Idx + Size; ++i) MARK_NODE_ALLOCATED(PS, i); @@ -303,28 +406,51 @@ void *Result; unsigned i; - assert(Pool && "Null pool pointer passed in to poolallocarray!"); + if (!Pool) { + printf("Null pool pointer passed to poolallocarray!\n"); + exit(1); + } + NodeSize = Pool->NodeSize; - PS = (PoolSlab*)Pool->Data; - assert(Size <= NODES_PER_SLAB && - "Exceeded the maximum size of an individual malloc"); + // Return if this pool has size 0 + if (NodeSize == 0) + return 0; + + PS = (PoolSlab*)Pool->Data; if ((Result = FindSlabEntryArray(PS, NodeSize,Size))) return Result; /* Otherwise we must allocate a new slab and add it to the list */ - PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); - - assert (PS && "Could not allocate memory!"); + if (Size > NODES_PER_SLAB) { + /* Allocate a new slab of size Size */ + PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*Size-1); + if (!PS) { + printf("poolallocarray: Could not allocate memory!\n"); + exit(1); + } + PS->isSingleArray = 1; + PS->ArraySize = Size; + MARK_NODE_ALLOCATED(PS, 0); + } else { + PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); + if (!PS) { + printf("poolallocarray: Could not allocate memory!\n"); + exit(1); + } - /* Initialize the slab to indicate that the first element is allocated */ - PS->FirstUnused = Size; - PS->LastUsed = Size - 1; + /* Initialize the slab to indicate that the first element is allocated */ + PS->FirstUnused = Size; + PS->LastUsed = Size - 1; + + PS->isSingleArray = 0; + PS->ArraySize = 0; - SET_START_BIT(PS, 0); - for (i = 0; i < Size; ++i) { - MARK_NODE_ALLOCATED(PS, i); + SET_START_BIT(PS, 0); + for (i = 0; i < Size; ++i) { + MARK_NODE_ALLOCATED(PS, i); + } } /* Add the slab to the list... */ From kowshik at cs.uiuc.edu Thu Aug 7 00:38:01 2003 From: kowshik at cs.uiuc.edu (Sumant Kowshik) Date: Thu Aug 7 00:38:01 2003 Subject: [llvm-commits] CVS: llvm/test/Makefile.tests Message-ID: <200308070537.AAA20062@apoc.cs.uiuc.edu> Changes in directory llvm/test: Makefile.tests updated: 1.72 -> 1.73 --- Log message: Removed the support for pool allocation testing. This will be in a separate TEST file --- Diffs of the changes: Index: llvm/test/Makefile.tests diff -u llvm/test/Makefile.tests:1.72 llvm/test/Makefile.tests:1.73 --- llvm/test/Makefile.tests:1.72 Tue Aug 5 20:03:28 2003 +++ llvm/test/Makefile.tests Thu Aug 7 00:36:53 2003 @@ -77,15 +77,6 @@ TRACELIBS := -L$(LEVEL)/test/Libraries/Output -linstr.$(ARCH) endif -POOLFLAGS = -DOPOOLALLOC = -## If POOLALLOC is "yes", set the opt flag and the POOLLIBS varoab;e -ifeq ($(POOLALLOC), yes) - POOLFLAGS += -poolalloc - DOPOOLALLOC = yes - POOLLIBS := -L$(LEVEL)/test/Libraries/Output -endif - LLCLIBS := $(LLCLIBS) -lm clean:: From lattner at cs.uiuc.edu Thu Aug 7 00:39:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 00:39:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenWrappers.h CodeGenWrappers.cpp Message-ID: <200308070538.AAA20085@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenWrappers.h added (r1.1) CodeGenWrappers.cpp added (r1.1) --- Log message: Initial checkin of useful wrappers around the Target classes, for now, only ValueType and Target are wrapped --- Diffs of the changes: Index: llvm/utils/TableGen/CodeGenWrappers.h diff -c /dev/null llvm/utils/TableGen/CodeGenWrappers.h:1.1 *** /dev/null Thu Aug 7 00:38:21 2003 --- llvm/utils/TableGen/CodeGenWrappers.h Thu Aug 7 00:38:11 2003 *************** *** 0 **** --- 1,52 ---- + //===- CodeGenWrappers.h - Code Generation Class Wrappers -------*- C++ -*-===// + // + // These classes wrap target description classes used by the various code + // generation TableGen backends. This makes it easier to access the data and + // provides a single place that needs to check it for validity. All of these + // classes throw exceptions on error conditions. + // + //===----------------------------------------------------------------------===// + + #ifndef CODEGENWRAPPERS_H + #define CODEGENWRAPPERS_H + + #include "llvm/CodeGen/ValueTypes.h" + #include + #include + class Record; + class RecordKeeper; + + /// getValueType - Return the MVT::ValueType that the specified TableGen record + /// corresponds to. + MVT::ValueType getValueType(Record *Rec); + + std::ostream &operator<<(std::ostream &OS, MVT::ValueType T); + + + + /// CodeGenTarget - This class corresponds to the Target class in the .td files. + /// + class CodeGenTarget { + Record *TargetRec; + std::vector CalleeSavedRegisters; + MVT::ValueType PointerType; + + public: + CodeGenTarget(); + + Record *getTargetRecord() const { return TargetRec; } + const std::string &getName() const; + + const std::vector &getCalleeSavedRegisters() const { + return CalleeSavedRegisters; + } + + // getInstructionSet - Return the InstructionSet object... + Record *getInstructionSet() const; + + // getInstructionSet - Return the CodeGenInstructionSet object for this + // target, lazily reading it from the record keeper as needed. + // CodeGenInstructionSet *getInstructionSet - + }; + + #endif Index: llvm/utils/TableGen/CodeGenWrappers.cpp diff -c /dev/null llvm/utils/TableGen/CodeGenWrappers.cpp:1.1 *** /dev/null Thu Aug 7 00:38:21 2003 --- llvm/utils/TableGen/CodeGenWrappers.cpp Thu Aug 7 00:38:11 2003 *************** *** 0 **** --- 1,66 ---- + //===- CodeGenWrappers.cpp - Code Generation Class Wrappers -----*- C++ -*-===// + // + // These classes wrap target description classes used by the various code + // generation TableGen backends. This makes it easier to access the data and + // provides a single place that needs to check it for validity. All of these + // classes throw exceptions on error conditions. + // + //===----------------------------------------------------------------------===// + + #include "CodeGenWrappers.h" + #include "Record.h" + + /// getValueType - Return the MCV::ValueType that the specified TableGen record + /// corresponds to. + MVT::ValueType getValueType(Record *Rec) { + return (MVT::ValueType)Rec->getValueAsInt("Value"); + } + + std::ostream &operator<<(std::ostream &OS, MVT::ValueType T) { + switch (T) { + case MVT::Other: return OS << "UNKNOWN"; + case MVT::i1: return OS << "i1"; + case MVT::i8: return OS << "i8"; + case MVT::i16: return OS << "i16"; + case MVT::i32: return OS << "i32"; + case MVT::i64: return OS << "i64"; + case MVT::i128: return OS << "i128"; + case MVT::f32: return OS << "f32"; + case MVT::f64: return OS << "f64"; + case MVT::f80: return OS << "f80"; + case MVT::f128: return OS << "f128"; + case MVT::isVoid:return OS << "void"; + } + return OS; + } + + + + /// getTarget - Return the current instance of the Target class. + /// + CodeGenTarget::CodeGenTarget() { + std::vector Targets = Records.getAllDerivedDefinitions("Target"); + if (Targets.size() != 1) + throw std::string("ERROR: Multiple subclasses of Target defined!"); + TargetRec = Targets[0]; + + // Read in all of the CalleeSavedRegisters... + ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters"); + for (unsigned i = 0, e = LI->getSize(); i != e; ++i) + if (DefInit *DI = dynamic_cast(LI->getElement(i))) + CalleeSavedRegisters.push_back(DI->getDef()); + else + throw "Target: " + TargetRec->getName() + + " expected register definition in CalleeSavedRegisters list!"; + + PointerType = getValueType(TargetRec->getValueAsDef("PointerType")); + } + + + const std::string &CodeGenTarget::getName() const { + return TargetRec->getName(); + } + + Record *CodeGenTarget::getInstructionSet() const { + return TargetRec->getValueAsDef("InstructionSet"); + } From lattner at cs.uiuc.edu Thu Aug 7 00:40:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 00:40:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp InstrInfoEmitter.cpp Message-ID: <200308070539.AAA20104@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.9 -> 1.10 InstrInfoEmitter.cpp updated: 1.3 -> 1.4 --- Log message: Start using the CodeGeneratorWrappers --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.9 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.10 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.9 Wed Aug 6 16:47:14 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Thu Aug 7 00:39:09 2003 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "RegisterInfoEmitter.h" +#include "CodeGenWrappers.h" #include "Record.h" #include "Support/StringExtras.h" #include @@ -36,7 +37,7 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) { EmitSourceFileHeader("Register Information Header Fragment", OS); - const std::string &TargetName = getTarget(Records)->getName(); + const std::string &TargetName = CodeGenTarget().getName(); std::string ClassName = TargetName + "GenRegisterInfo"; OS << "#include \"llvm/Target/MRegisterInfo.h\"\n\n"; @@ -193,20 +194,20 @@ OS << " };\n"; // End of register descriptors... OS << "}\n\n"; // End of anonymous namespace... - Record *Target = getTarget(Records); + CodeGenTarget Target; - OS << "namespace " << Target->getName() << " { // Register classes\n"; + OS << "namespace " << Target.getName() << " { // Register classes\n"; for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { const std::string &Name = RegisterClasses[i]->getName(); if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes OS << " TargetRegisterClass *" << Name << "RegisterClass = &" << Name << "Instance;\n"; } - OS << "} // end of namespace " << Target->getName() << "\n\n"; + OS << "} // end of namespace " << Target.getName() << "\n\n"; - std::string ClassName = Target->getName() + "GenRegisterInfo"; + std::string ClassName = Target.getName() + "GenRegisterInfo"; // Emit the constructor of the class... OS << ClassName << "::" << ClassName @@ -219,11 +220,8 @@ OS << "const unsigned* " << ClassName << "::getCalleeSaveRegs() const {\n" << " static const unsigned CalleeSaveRegs[] = {\n "; - ListInit *LI = Target->getValueAsListInit("CalleeSavedRegisters"); - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - if (DefInit *DI = dynamic_cast(LI->getElement(i))) - OS << getQualifiedName(DI->getDef()) << ", "; - else - throw "Expected register definition in CalleeSavedRegisters list!"; + const std::vector &CSR = Target.getCalleeSavedRegisters(); + for (unsigned i = 0, e = CSR.size(); i != e; ++i) + OS << getQualifiedName(CSR[i]) << ", "; OS << " 0\n };\n return CalleeSaveRegs;\n}\n\n"; } Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.3 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.4 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.3 Tue Aug 5 23:32:07 2003 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Thu Aug 7 00:39:09 2003 @@ -6,6 +6,7 @@ //===----------------------------------------------------------------------===// #include "InstrInfoEmitter.h" +#include "CodeGenWrappers.h" #include "Record.h" // runEnums - Print out enum values for all of the instructions. @@ -23,9 +24,10 @@ OS << "namespace " << Namespace << " {\n"; OS << " enum {\n"; + CodeGenTarget Target; + // We must emit the PHI opcode first... - Record *Target = getTarget(Records); - Record *InstrInfo = Target->getValueAsDef("InstructionSet"); + Record *InstrInfo = Target.getInstructionSet(); Record *PHI = InstrInfo->getValueAsDef("PHIInst"); OS << " " << PHI->getName() << ", \t// 0 (fixed for all targets)\n"; @@ -55,9 +57,9 @@ // run - Emit the main instruction description records for the target... void InstrInfoEmitter::run(std::ostream &OS) { EmitSourceFileHeader("Target Instruction Descriptors", OS); - Record *Target = getTarget(Records); - const std::string &TargetName = Target->getName(); - Record *InstrInfo = Target->getValueAsDef("InstructionSet"); + CodeGenTarget Target; + const std::string &TargetName = Target.getName(); + Record *InstrInfo = Target.getInstructionSet(); Record *PHI = InstrInfo->getValueAsDef("PHIInst"); std::vector Instructions = From lattner at cs.uiuc.edu Thu Aug 7 00:40:14 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 00:40:14 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGenBackend.cpp TableGenBackend.h Message-ID: <200308070539.AAA20123@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGenBackend.cpp updated: 1.2 -> 1.3 TableGenBackend.h updated: 1.3 -> 1.4 --- Log message: Eliminate now-dead method --- Diffs of the changes: Index: llvm/utils/TableGen/TableGenBackend.cpp diff -u llvm/utils/TableGen/TableGenBackend.cpp:1.2 llvm/utils/TableGen/TableGenBackend.cpp:1.3 --- llvm/utils/TableGen/TableGenBackend.cpp:1.2 Tue Aug 5 23:31:26 2003 +++ llvm/utils/TableGen/TableGenBackend.cpp Thu Aug 7 00:39:37 2003 @@ -25,12 +25,3 @@ return Namespace + "::" + R->getName(); } -/// getTarget - Return the current instance of the Target class. -/// -Record *TableGenBackend::getTarget(RecordKeeper &RC) const { - std::vector Targets = RC.getAllDerivedDefinitions("Target"); - - if (Targets.size() != 1) - throw std::string("ERROR: Multiple subclasses of Target defined!"); - return Targets[0]; -} Index: llvm/utils/TableGen/TableGenBackend.h diff -u llvm/utils/TableGen/TableGenBackend.h:1.3 llvm/utils/TableGen/TableGenBackend.h:1.4 --- llvm/utils/TableGen/TableGenBackend.h:1.3 Wed Aug 6 00:39:03 2003 +++ llvm/utils/TableGen/TableGenBackend.h Thu Aug 7 00:39:37 2003 @@ -29,9 +29,6 @@ /// getQualifiedName - Return the name of the specified record, with a /// namespace qualifier if the record contains one. std::string getQualifiedName(Record *R) const; - - /// getTarget - Return the current instance of the Target class. - Record *getTarget(RecordKeeper &RC) const; }; #endif From lattner at cs.uiuc.edu Thu Aug 7 00:41:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 00:41:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308070540.AAA20146@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.3 -> 1.4 InstrSelectorEmitter.h updated: 1.2 -> 1.3 --- Log message: Initial checkin of tree pattern parser and type inference engine (which still needs work). --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.3 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.4 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.3 Wed Aug 6 16:47:14 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 00:40:14 2003 @@ -6,7 +6,9 @@ //===----------------------------------------------------------------------===// #include "InstrSelectorEmitter.h" +#include "CodeGenWrappers.h" #include "Record.h" +#include "Support/Debug.h" NodeType::ArgResultTypes NodeType::Translate(Record *R) { const std::string &Name = R->getName(); @@ -17,6 +19,22 @@ throw "Unknown DagNodeValType '" + Name + "'!"; } +std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) { + if (N.isLeaf()) + return OS << N.getType() << ":" << *N.getValue(); + OS << "(" << N.getType() << ":"; + OS << N.getOperator()->getName(); + + const std::vector &Children = N.getChildren(); + if (!Children.empty()) { + OS << " " << *Children[0]; + for (unsigned i = 1, e = Children.size(); i != e; ++i) + OS << ", " << *Children[i]; + } + return OS << ")"; +} +void TreePatternNode::dump() const { std::cerr << *this; } + /// ProcessNodeTypes - Process all of the node types in the current /// RecordKeeper, turning them into the more accessible NodeTypes data @@ -52,9 +70,148 @@ // Add the node type mapping now... NodeTypes[Node] = NodeType(RetTy, ArgTypes); - } + DEBUG(std::cerr << "Got node type '" << Node->getName() << "'\n"); + } +} + +static MVT::ValueType getIntrinsicType(Record *R) { + // Check to see if this is a register or a register class... + const std::vector &SuperClasses = R->getSuperClasses(); + for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) + if (SuperClasses[i]->getName() == "RegisterClass") { + return getValueType(R->getValueAsDef("RegType")); + } else if (SuperClasses[i]->getName() == "Register") { + std::cerr << "WARNING: Explicit registers not handled yet!\n"; + } else if (SuperClasses[i]->getName() == "Nonterminal") { + } + //throw "Error: Unknown value used: " + R->getName(); + + return MVT::Other; } +// Parse the specified DagInit into a TreePattern which we can use. +// +TreePatternNode *InstrSelectorEmitter::ParseTreePattern(DagInit *DI, + const std::string &RecName) { + Record *Operator = DI->getNodeType(); + + if (!NodeTypes.count(Operator)) + throw "Illegal node for instruction pattern: '" + Operator->getName() +"'!"; + + const std::vector &Args = DI->getArgs(); + std::vector Children; + + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + Init *Arg = Args[i]; + if (DagInit *DI = dynamic_cast(Arg)) { + Children.push_back(ParseTreePattern(DI, RecName)); + } else if (DefInit *DI = dynamic_cast(Arg)) { + Children.push_back(new TreePatternNode(DI)); + // If it's a regclass or something else known, set the type. + Children.back()->setType(getIntrinsicType(DI->getDef())); + } else { + Arg->dump(); + throw "Unknown value for tree pattern in '" + RecName + "'!"; + } + } + + return new TreePatternNode(Operator, Children); +} + +// UpdateNodeType - Set the node type of N to VT if VT contains information. If +// N already contains a conflicting type, then throw an exception +// +static bool UpdateNodeType(TreePatternNode *N, MVT::ValueType VT, + const std::string &RecName) { + if (VT == MVT::Other || N->getType() == VT) return false; + + if (N->getType() == MVT::Other) { + N->setType(VT); + return true; + } + + throw "Type inferfence contradiction found for pattern " + RecName; +} + +// InferTypes - Perform type inference on the tree, returning true if there +// are any remaining untyped nodes and setting MadeChange if any changes were +// made. +bool InstrSelectorEmitter::InferTypes(TreePatternNode *N, + const std::string &RecName, + bool &MadeChange) { + if (N->isLeaf()) return N->getType() == MVT::Other; + + bool AnyUnset = false; + Record *Operator = N->getOperator(); + assert(NodeTypes.count(Operator) && "No node info for node!"); + const NodeType &NT = NodeTypes[Operator]; + + // Check to see if we can infer anything about the argument types from the + // return types... + const std::vector &Children = N->getChildren(); + if (Children.size() != NT.ArgTypes.size()) + throw "In record " + RecName + " incorrect number of children for " + + Operator->getName() + " node!"; + + for (unsigned i = 0, e = Children.size(); i != e; ++i) { + AnyUnset |= InferTypes(Children[i], RecName, MadeChange); + + + switch (NT.ArgTypes[i]) { + case NodeType::Arg0: + MadeChange |=UpdateNodeType(Children[i], Children[0]->getType(), RecName); + break; + case NodeType::Val: + if (Children[i]->getType() == MVT::isVoid) + throw "In pattern for " + RecName + " should not get a void node!"; + break; + case NodeType::Ptr: // FIXME + default: assert(0 && "Invalid argument ArgType!"); + } + } + + // See if we can infer anything about the return type now... + switch (NT.ResultType) { + case NodeType::Void: + MadeChange |= UpdateNodeType(N, MVT::isVoid, RecName); + break; + case NodeType::Arg0: + MadeChange |= UpdateNodeType(N, Children[0]->getType(), RecName); + break; + + case NodeType::Ptr: // FIXME: get from target + case NodeType::Val: + assert(0 && "Unhandled type constraint!"); + break; + } + + return AnyUnset | N->getType() == MVT::Other; +} + + +// ReadAndCheckPattern - Parse the specified DagInit into a pattern and then +// perform full type inference. +// +TreePatternNode *InstrSelectorEmitter::ReadAndCheckPattern(DagInit *DI, + const std::string &RecName) { + // First, parse the pattern... + TreePatternNode *Pattern = ParseTreePattern(DI, RecName); + + bool MadeChange, AnyUnset; + do { + MadeChange = false; + AnyUnset = InferTypes(Pattern, RecName, MadeChange); + if (AnyUnset && !MadeChange) { + std::cerr << "In pattern: " << *Pattern << "\n"; + throw "Cannot infer types for " + RecName; + } + } while (AnyUnset || MadeChange); + + return Pattern; +} + + + /// ProcessInstructionPatterns - Read in all subclasses of Instruction, and /// process those with a useful Pattern field. /// @@ -62,9 +219,12 @@ std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); for (unsigned i = 0, e = Insts.size(); i != e; ++i) { Record *Inst = Insts[i]; - if (DagInit *PatternInit = - dynamic_cast(Inst->getValueInit("Pattern"))) { + if (DagInit *DI = dynamic_cast(Inst->getValueInit("Pattern"))) { + TreePatternNode *Pattern = ReadAndCheckPattern(DI, Inst->getName()); + + DEBUG(std::cerr << "Parsed inst pattern " << Inst->getName() << "\t= " + << *Pattern << "\n"); } } } @@ -74,6 +234,8 @@ // Type-check all of the node types to ensure we "understand" them. ProcessNodeTypes(); + // Read in all of the nonterminals... + // Read all of the instruction patterns in... ProcessInstructionPatterns(); Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.2 llvm/utils/TableGen/InstrSelectorEmitter.h:1.3 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.2 Wed Aug 6 01:16:35 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 00:40:14 2003 @@ -9,8 +9,11 @@ #define INSTRSELECTOR_EMITTER_H #include "TableGenBackend.h" +#include "llvm/CodeGen/ValueTypes.h" #include #include +class DagInit; +class Init; struct NodeType { enum ArgResultTypes { @@ -36,6 +39,47 @@ static ArgResultTypes Translate(Record *R); }; +class TreePatternNode { + /// Operator - The operation that this node represents... this is null if this + /// is a leaf. + Record *Operator; + + /// Type - The inferred value type... + MVT::ValueType Type; + + /// Children - If this is not a leaf (Operator != 0), this is the subtrees + /// that we contain. + std::vector Children; + + /// Value - If this node is a leaf, this indicates what the thing is. + Init *Value; +public: + TreePatternNode(Record *o, const std::vector &c) + : Operator(o), Type(MVT::Other), Children(c), Value(0) {} + TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {} + + Record *getOperator() const { return Operator; } + MVT::ValueType getType() const { return Type; } + void setType(MVT::ValueType T) { Type = T; } + + bool isLeaf() const { return Operator == 0; } + + const std::vector &getChildren() const { + assert(Operator != 0 && "This is a leaf node!"); + return Children; + } + Init *getValue() const { + assert(Operator == 0 && "This is not a leaf node!"); + return Value; + } + + void dump() const; +}; + +std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N); + + + class InstrSelectorEmitter : public TableGenBackend { RecordKeeper &Records; @@ -55,6 +99,21 @@ // ProcessInstructionPatterns - Read in all subclasses of Instruction, and // process those with a useful Pattern field. void ProcessInstructionPatterns(); + + // ParseTreePattern - Parse the specified DagInit into a TreePattern which we + // can use. + // + TreePatternNode *ParseTreePattern(DagInit *DI, const std::string &RecName); + + // InferTypes - Perform type inference on the tree, returning true if there + // are any remaining untyped nodes and setting MadeChange if any changes were + // made. + bool InferTypes(TreePatternNode *N, const std::string &RecName, + bool &MadeChange); + + // ReadAndCheckPattern - Parse the specified DagInit into a pattern and then + // perform full type inference. + TreePatternNode *ReadAndCheckPattern(DagInit *DI, const std::string &RecName); }; #endif From lattner at cs.uiuc.edu Thu Aug 7 01:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 01:01:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Record.h Message-ID: <200308070600.BAA23960@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.26 -> 1.27 Record.h updated: 1.32 -> 1.33 --- Log message: Add new method getVAlueAsDag --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.26 llvm/utils/TableGen/Record.cpp:1.27 --- llvm/utils/TableGen/Record.cpp:1.26 Wed Aug 6 17:29:04 2003 +++ llvm/utils/TableGen/Record.cpp Thu Aug 7 01:00:43 2003 @@ -613,10 +613,26 @@ throw "Record '" + getName() + "' does not have a field named '" + FieldName + "!\n"; - if (BitInit *DI = dynamic_cast(R->getValue())) - return DI->getValue(); + if (BitInit *BI = dynamic_cast(R->getValue())) + return BI->getValue(); throw "Record '" + getName() + "', field '" + FieldName + - "' does not have a list initializer!"; + "' does not have a bit initializer!"; +} + +/// getValueAsDag - This method looks up the specified field and returns its +/// value as an Dag, throwing an exception if the field does not exist or if +/// the value is not the right type. +/// +DagInit *Record::getValueAsDag(const std::string &FieldName) const { + const RecordVal *R = getValue(FieldName); + if (R == 0 || R->getValue() == 0) + throw "Record '" + getName() + "' does not have a field named '" + + FieldName + "!\n"; + + if (DagInit *DI = dynamic_cast(R->getValue())) + return DI; + throw "Record '" + getName() + "', field '" + FieldName + + "' does not have a dag initializer!"; } Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.32 llvm/utils/TableGen/Record.h:1.33 --- llvm/utils/TableGen/Record.h:1.32 Wed Aug 6 18:01:18 2003 +++ llvm/utils/TableGen/Record.h Thu Aug 7 01:00:43 2003 @@ -759,6 +759,12 @@ /// the value is not the right type. /// int getValueAsInt(const std::string &FieldName) const; + + /// getValueAsDag - This method looks up the specified field and returns its + /// value as an Dag, throwing an exception if the field does not exist or if + /// the value is not the right type. + /// + DagInit *getValueAsDag(const std::string &FieldName) const; }; std::ostream &operator<<(std::ostream &OS, const Record &R); From lattner at cs.uiuc.edu Thu Aug 7 01:02:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 01:02:02 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenWrappers.h Message-ID: <200308070601.BAA24253@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenWrappers.h updated: 1.1 -> 1.2 --- Log message: Allow clients to get at the pointer type --- Diffs of the changes: Index: llvm/utils/TableGen/CodeGenWrappers.h diff -u llvm/utils/TableGen/CodeGenWrappers.h:1.1 llvm/utils/TableGen/CodeGenWrappers.h:1.2 --- llvm/utils/TableGen/CodeGenWrappers.h:1.1 Thu Aug 7 00:38:11 2003 +++ llvm/utils/TableGen/CodeGenWrappers.h Thu Aug 7 01:01:44 2003 @@ -41,6 +41,8 @@ return CalleeSavedRegisters; } + MVT::ValueType getPointerType() const { return PointerType; } + // getInstructionSet - Return the InstructionSet object... Record *getInstructionSet() const; From lattner at cs.uiuc.edu Thu Aug 7 01:03:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 01:03:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308070602.BAA24279@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.4 -> 1.5 InstrSelectorEmitter.h updated: 1.3 -> 1.4 --- Log message: Finish implementation of the type inference engine. Start working on reading in nonterminals --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.4 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.5 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.4 Thu Aug 7 00:40:14 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 01:02:15 2003 @@ -82,11 +82,13 @@ return getValueType(R->getValueAsDef("RegType")); } else if (SuperClasses[i]->getName() == "Register") { std::cerr << "WARNING: Explicit registers not handled yet!\n"; + return MVT::Other; } else if (SuperClasses[i]->getName() == "Nonterminal") { + //std::cerr << "Warning nonterminal type not handled yet:" << R->getName() + // << "\n"; + return MVT::Other; } - //throw "Error: Unknown value used: " + R->getName(); - - return MVT::Other; + throw "Error: Unknown value used: " + R->getName(); } // Parse the specified DagInit into a TreePattern which we can use. @@ -159,13 +161,15 @@ switch (NT.ArgTypes[i]) { case NodeType::Arg0: - MadeChange |=UpdateNodeType(Children[i], Children[0]->getType(), RecName); + MadeChange |= UpdateNodeType(Children[i], Children[0]->getType(),RecName); break; case NodeType::Val: if (Children[i]->getType() == MVT::isVoid) throw "In pattern for " + RecName + " should not get a void node!"; break; - case NodeType::Ptr: // FIXME + case NodeType::Ptr: + MadeChange |= UpdateNodeType(Children[i],Target.getPointerType(),RecName); + break; default: assert(0 && "Invalid argument ArgType!"); } } @@ -179,8 +183,14 @@ MadeChange |= UpdateNodeType(N, Children[0]->getType(), RecName); break; - case NodeType::Ptr: // FIXME: get from target + case NodeType::Ptr: + MadeChange |= UpdateNodeType(N, Target.getPointerType(), RecName); + break; case NodeType::Val: + if (N->getType() == MVT::isVoid) + throw "In pattern for " + RecName + " should not get a void node!"; + break; + default: assert(0 && "Unhandled type constraint!"); break; } @@ -210,6 +220,19 @@ return Pattern; } +// ProcessNonTerminals - Read in all nonterminals and incorporate them into +// our pattern database. +void InstrSelectorEmitter::ProcessNonTerminals() { + std::vector NTs = Records.getAllDerivedDefinitions("Nonterminal"); + for (unsigned i = 0, e = NTs.size(); i != e; ++i) { + DagInit *DI = NTs[i]->getValueAsDag("Pattern"); + + TreePatternNode *Pattern = ReadAndCheckPattern(DI, NTs[i]->getName()); + + DEBUG(std::cerr << "Parsed nonterm pattern " << NTs[i]->getName() << "\t= " + << *Pattern << "\n"); + } +} /// ProcessInstructionPatterns - Read in all subclasses of Instruction, and @@ -222,7 +245,6 @@ if (DagInit *DI = dynamic_cast(Inst->getValueInit("Pattern"))) { TreePatternNode *Pattern = ReadAndCheckPattern(DI, Inst->getName()); - DEBUG(std::cerr << "Parsed inst pattern " << Inst->getName() << "\t= " << *Pattern << "\n"); } @@ -235,6 +257,7 @@ ProcessNodeTypes(); // Read in all of the nonterminals... + //ProcessNonTerminals(); // Read all of the instruction patterns in... ProcessInstructionPatterns(); Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.3 llvm/utils/TableGen/InstrSelectorEmitter.h:1.4 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.3 Thu Aug 7 00:40:14 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 01:02:15 2003 @@ -9,7 +9,7 @@ #define INSTRSELECTOR_EMITTER_H #include "TableGenBackend.h" -#include "llvm/CodeGen/ValueTypes.h" +#include "CodeGenWrappers.h" #include #include class DagInit; @@ -82,6 +82,7 @@ class InstrSelectorEmitter : public TableGenBackend { RecordKeeper &Records; + CodeGenTarget Target; std::map NodeTypes; public: @@ -95,6 +96,10 @@ // RecordKeeper, turning them into the more accessible NodeTypes data // structure. void ProcessNodeTypes(); + + // ProcessNonTerminals - Read in all nonterminals and incorporate them into + // our pattern database. + void ProcessNonTerminals(); // ProcessInstructionPatterns - Read in all subclasses of Instruction, and // process those with a useful Pattern field. From lattner at cs.uiuc.edu Thu Aug 7 08:53:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 08:53:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308071352.IAA01247@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.15 -> 1.16 --- Log message: Update tablegen interfaces --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.15 llvm/lib/Target/Target.td:1.16 --- llvm/lib/Target/Target.td:1.15 Wed Aug 6 10:31:02 2003 +++ llvm/lib/Target/Target.td Thu Aug 7 08:52:22 2003 @@ -9,18 +9,26 @@ //===----------------------------------------------------------------------===// // // Value types - These values correspond to the register types defined in the -// ValueTypes.h file. +// ValueTypes.h file. If you update anything here, you must update it there as +// well! // -class ValueType { string Namespace = "MVT"; int Size = size; } - -def i1 : ValueType<1>; // One bit boolean value -def i8 : ValueType<8>; // 8-bit integer value -def i16 : ValueType<16>; // 16-bit integer value -def i32 : ValueType<32>; // 32-bit integer value -def i64 : ValueType<64>; // 64-bit integer value -def f32 : ValueType<32>; // 32-bit floating point value -def f64 : ValueType<64>; // 64-bit floating point value -def f80 : ValueType<80>; // 80-bit floating point value +class ValueType { + string Namespace = "MVT"; + int Size = size; + int Value = value; +} + +def i1 : ValueType<1 , 1>; // One bit boolean value +def i8 : ValueType<8 , 2>; // 8-bit integer value +def i16 : ValueType<16 , 3>; // 16-bit integer value +def i32 : ValueType<32 , 4>; // 32-bit integer value +def i64 : ValueType<64 , 5>; // 64-bit integer value +def i128 : ValueType<128, 5>; // 128-bit integer value +def f32 : ValueType<32 , 7>; // 32-bit floating point value +def f64 : ValueType<64 , 8>; // 64-bit floating point value +def f80 : ValueType<80 , 9>; // 80-bit floating point value +def f128 : ValueType<128, 9>; // 128-bit floating point value +def isVoid : ValueType<0 , 11>; // Produces no value //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target @@ -147,48 +155,56 @@ //===----------------------------------------------------------------------===// // DAG node definitions used by the instruction selector... // -class DagNodeResultType; -def DNRT_void : DagNodeResultType; // Tree node always returns void -def DNRT_val : DagNodeResultType; // A non-void type -def DNRT_arg0 : DagNodeResultType; // Tree node returns same type as Arg0 - -class DagNodeArgType; -def DNAT_val : DagNodeArgType; // Any value -def DNAT_arg0 : DagNodeArgType; // Same as for arg #0 -def DNAT_ptr : DagNodeArgType; // Returns the target pointer type - -class DagNode args> { - DagNodeResultType RetType = ret; - list ArgTypes = args; +class DagNodeValType; +def DNVT_void : DagNodeValType; // Tree node always returns void +def DNVT_val : DagNodeValType; // A non-void type +def DNVT_arg0 : DagNodeValType; // Tree node returns same type as Arg0 +def DNVT_ptr : DagNodeValType; // The target pointer type + +class DagNode args> { + DagNodeValType RetType = ret; + list ArgTypes = args; string EnumName = ?; } // BuiltinDagNodes are built into the instruction selector and correspond to // enum values. -class BuiltinDagNode Args, +class BuiltinDagNode Args, string Ename> : DagNode { let EnumName = Ename; } // Magic nodes... -def set : DagNode; +def set : DagNode; // Terminals... -def imm : DagNode; +def Constant : BuiltinDagNode; +// def frameidx : BuiltinDagNode; // Arithmetic... -def plus : BuiltinDagNode; -def minus : BuiltinDagNode; -//def mult : DagNode<2, DNRT_arg0>; -//def div : DagNode<2, DNRT_arg0>; -//def udiv : DagNode<2, DNRT_arg0>; -//def mod : DagNode<2, DNRT_arg0>; -//def umod : DagNode<2, DNRT_arg0>; +def plus : BuiltinDagNode; +def minus : BuiltinDagNode; +//def mult : DagNode<2, DNVT_arg0>; +//def div : DagNode<2, DNVT_arg0>; +//def udiv : DagNode<2, DNVT_arg0>; +//def mod : DagNode<2, DNVT_arg0>; +//def umod : DagNode<2, DNVT_arg0>; -//def load : DagNode<1, DNRT_val>; -//def store : DagNode<2, DNRT_Void>; +def load : DagNode; +//def store : DagNode<2, DNVT_Void>; // Other... -def ret : BuiltinDagNode; -def retvoid : BuiltinDagNode; +def ret : BuiltinDagNode; +def retvoid : BuiltinDagNode; + +//===----------------------------------------------------------------------===// +// DAG nonterminals definitions used by the instruction selector... +// +class Nonterminal { + dag Pattern = pattern; + bit BuiltIn = 0; +} + +// imm - Immediate value... +def imm : Nonterminal<(Constant)> { let BuiltIn = 1; } From criswell at cs.uiuc.edu Thu Aug 7 09:44:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 09:44:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalDCE.cpp Message-ID: <200308071443.JAA27071@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalDCE.cpp updated: 1.24 -> 1.25 --- Log message: Fixed a segfault in gccld. The original code does not work because the value from WorkList.end() is invalidated once WorkList.erase() is called. To ensure proper functionality, we must ensure that WorkList.erase() is always called before WorkList.end(). --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/GlobalDCE.cpp diff -u llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.24 llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.25 --- llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.24 Thu Jun 26 00:41:18 2003 +++ llvm/lib/Transforms/IPO/GlobalDCE.cpp Thu Aug 7 09:43:13 2003 @@ -123,8 +123,10 @@ // If the global variable is still on the worklist, remove it now. std::vector::iterator I = std::find(WorkList.begin(), WorkList.end(), GV); - while (I != WorkList.end()) - I = std::find(WorkList.erase(I), WorkList.end(), GV); + while (I != WorkList.end()) { + I = WorkList.erase(I); + I = std::find(I, WorkList.end(), GV); + } return true; } From vadve at cs.uiuc.edu Thu Aug 7 10:02:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Thu Aug 7 10:02:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200308071501.KAA30366@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.112 -> 1.113 --- Log message: Fix sanity-checking in 'maskUnsigned' code to be more precise: use or def-and-use operands can be substituted after one def-only operand has been substituted. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.112 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.113 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.112 Wed Aug 6 13:48:40 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Thu Aug 7 10:01:26 2003 @@ -2859,9 +2859,19 @@ unsigned numSubst = 0; for (unsigned i=0, N=mvec.size(); i < N; ++i) { + + // Make sure we substitute all occurrences of dest in these instrs. + // Otherwise, we will have bogus code. bool someArgsWereIgnored = false; - numSubst += mvec[i]->substituteValue(dest, tmpI, /*defsOnly*/ true, - /*defsAndUses*/ false, + + // Make sure not to substitute an upwards-exposed use -- that would + // introduce a use of `tmpI' with no preceding def. Therefore, + // substitute a use or def-and-use operand only if a previous def + // operand has already been substituted (i.e., numSusbt > 0). + // + numSubst += mvec[i]->substituteValue(dest, tmpI, + /*defsOnly*/ numSubst == 0, + /*notDefsAndUses*/ numSubst > 0, someArgsWereIgnored); assert(!someArgsWereIgnored && "Operand `dest' exists but not replaced: probably bogus!"); From vadve at cs.uiuc.edu Thu Aug 7 10:02:14 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Thu Aug 7 10:02:14 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstr.cpp Message-ID: <200308071501.KAA30382@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.77 -> 1.78 --- Log message: Fix assertion in MachineInstr::substituteValue(). --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.77 llvm/lib/CodeGen/MachineInstr.cpp:1.78 --- llvm/lib/CodeGen/MachineInstr.cpp:1.77 Tue Aug 5 16:55:20 2003 +++ llvm/lib/CodeGen/MachineInstr.cpp Thu Aug 7 10:01:48 2003 @@ -135,8 +135,8 @@ bool defsOnly, bool notDefsAndUses, bool& someArgsWereIgnored) { - assert((defsOnly || !notDefsAndUses) && - "notDefsAndUses is irrelevant if defsOnly == false."); + assert((!defsOnly || !notDefsAndUses) && + "notDefsAndUses is irrelevant if defsOnly == true."); unsigned numSubst = 0; From criswell at cs.uiuc.edu Thu Aug 7 10:14:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:14:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp GetTimer.h Makefile SLI.cpp SecondTrigger.cpp Timer.cpp scheduler.cpp Message-ID: <200308071513.KAA04685@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: FirstTrigger.cpp (r1.6) removed GetTimer.h (r1.2) removed Makefile (r1.3) removed SLI.cpp (r1.2) removed SecondTrigger.cpp (r1.3) removed Timer.cpp (r1.2) removed scheduler.cpp (r1.1) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:14:14 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:14:14 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Makefile Message-ID: <200308071513.KAA04664@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling: Makefile (r1.2) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:14:27 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:14:27 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Inst/rtl/Makefile pprtl.cpp pprtl.h Message-ID: <200308071513.KAA04659@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Inst/rtl: Makefile (r1.4) removed pprtl.cpp (r1.3) removed pprtl.h (r1.4) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:14:42 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:14:42 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Inst/mkexcl/Makefile mkexcl.cpp Message-ID: <200308071513.KAA04646@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Inst/mkexcl: Makefile (r1.2) removed mkexcl.cpp (r1.4) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:14:54 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:14:54 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Inst/lib/Phase1/Intraphase.h Makefile Phase1.cpp PrimInfo.cpp PrimInfo.h design.txt Message-ID: <200308071513.KAA04633@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Inst/lib/Phase1: Intraphase.h (r1.1) removed Makefile (r1.2) removed Phase1.cpp (r1.28) removed PrimInfo.cpp (r1.16) removed PrimInfo.h (r1.11) removed design.txt (r1.11) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:15:06 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:15:06 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Inst/lib/ElfReader.cpp InstManip.cpp InstManip.h Makefile PhaseInfo.h Phases.cpp SparcInstManip.cpp SparcInstManip.h design.txt Message-ID: <200308071513.KAA04620@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Inst/lib: ElfReader.cpp (r1.12) removed InstManip.cpp (r1.13) removed InstManip.h (r1.18) removed Makefile (r1.4) removed PhaseInfo.h (r1.10) removed Phases.cpp (r1.36) removed SparcInstManip.cpp (r1.17) removed SparcInstManip.h (r1.14) removed design.txt (r1.16) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:15:18 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:15:18 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Inst/Makefile Message-ID: <200308071513.KAA04607@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Inst: Makefile (r1.4) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:15:30 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:15:30 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Makefile Message-ID: <200308071513.KAA04573@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer: Makefile (r1.13) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:15:42 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:15:42 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/BinInterface/LLVMTrace.cpp Makefile analyze.cpp construct.cpp emit.cpp select.cpp sparc9.cpp sparcbin.cpp sparcdis.cpp Message-ID: <200308071513.KAA04594@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/BinInterface: LLVMTrace.cpp (r1.2) removed Makefile (r1.2) removed analyze.cpp (r1.11) removed construct.cpp (r1.6) removed emit.cpp (r1.6) removed select.cpp (r1.7) removed sparc9.cpp (r1.6) removed sparcbin.cpp (r1.10) removed sparcdis.cpp (r1.14) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:16:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:16:02 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp Makefile MemoryManager.cpp TraceCache.cpp VirtualMem.cpp Message-ID: <200308071514.KAA04729@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: InstrUtils.cpp (r1.12) removed Makefile (r1.3) removed MemoryManager.cpp (r1.9) removed TraceCache.cpp (r1.16) removed VirtualMem.cpp (r1.11) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:16:15 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:16:15 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/ScratchMemory/DummyFile.cpp DummyFile2.cpp Makefile Message-ID: <200308071514.KAA04716@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/ScratchMemory: DummyFile.cpp (r1.1) removed DummyFile2.cpp (r1.1) removed Makefile (r1.1) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:16:27 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:16:27 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp Makefile RuntimeOptimizations.cpp Trigger.cpp TriggerAuxillary.cpp TriggerAuxillary.h Message-ID: <200308071514.KAA04736@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Trigger: GetTraceTime.cpp (r1.2) removed Makefile (r1.1) removed RuntimeOptimizations.cpp (r1.1) removed Trigger.cpp (r1.19) removed TriggerAuxillary.cpp (r1.5) removed TriggerAuxillary.h (r1.3) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:16:39 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:16:39 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/SSAPRE/RuntimeLICM.cpp Message-ID: <200308071514.KAA04703@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/SSAPRE: RuntimeLICM.cpp (r1.1) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:16:51 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:16:51 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Reoptimizer/Mapping/Makefile getLLVMinfo.cpp Message-ID: <200308071514.KAA04698@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Mapping: Makefile (r1.4) removed getLLVMinfo.cpp (r1.11) removed --- Log message: Removing the Reoptimizer from the Pre-Release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:25:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:25:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Regression/Reoptimizer/ticm/.cvsignore Makefile ticm.c Message-ID: <200308071524.KAA04991@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/Reoptimizer/ticm: .cvsignore (r1.1) removed Makefile (r1.1) removed ticm.c (r1.2) removed --- Log message: Removed Reoptimizer tests from the pre-release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:25:14 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:25:14 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Regression/Reoptimizer/llub/.cvsignore Makefile llub.c Message-ID: <200308071524.KAA04985@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/Reoptimizer/llub: .cvsignore (r1.1) removed Makefile (r1.1) removed llub.c (r1.1) removed --- Log message: Removed Reoptimizer tests from the pre-release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:25:26 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:25:26 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Regression/Reoptimizer/inst/Makefile Test1.c Message-ID: <200308071524.KAA04977@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/Reoptimizer/inst: Makefile (r1.6) removed Test1.c (r1.5) removed --- Log message: Removed Reoptimizer tests from the pre-release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:25:38 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:25:38 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Regression/Reoptimizer/Makefile.mk Message-ID: <200308071524.KAA04952@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/Reoptimizer: Makefile.mk (r1.3) removed --- Log message: Removed Reoptimizer tests from the pre-release branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Thu Aug 7 10:25:49 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:25:49 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Regression/Reoptimizer/BinInterface/test.cpp Message-ID: <200308071524.KAA04965@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/Reoptimizer/BinInterface: test.cpp (r1.3) removed --- Log message: Removed Reoptimizer tests from the pre-release branch. --- Diffs of the changes: From brukman at cs.uiuc.edu Thu Aug 7 10:44:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 10:44:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200308071543.KAA09986@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.113 -> 1.114 --- Log message: Implement LLVM intrinsics `llvm.setjmp' and `llvm.longjmp' as follows: * setjmp() simply returns 0 * longjmp() simply calls abort() --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.113 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.114 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.113 Thu Aug 7 10:01:26 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Thu Aug 7 10:43:46 2003 @@ -16,10 +16,8 @@ #include "llvm/CodeGen/MachineFunctionInfo.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/DerivedTypes.h" -#include "llvm/iTerminators.h" -#include "llvm/iMemory.h" -#include "llvm/iOther.h" -#include "llvm/Function.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" #include "llvm/Constants.h" #include "llvm/ConstantHandling.h" #include "llvm/Intrinsics.h" @@ -1434,6 +1432,22 @@ addReg(callInstr.getOperand(2)). addReg(callInstr.getOperand(1))); return true; + + case LLVMIntrinsic::setjmp: { + // act as if we return 0 + unsigned g0 = target.getRegInfo().getZeroRegNum(); + mvec.push_back(BuildMI(V9::ORr,3).addMReg(g0).addMReg(g0) + .addReg(&callInstr, MOTy::Def)); + return true; + } + + case LLVMIntrinsic::longjmp: { + // call abort() + Module* M = callInstr.getParent()->getParent()->getParent(); + Function *F = M->getNamedFunction("abort"); + mvec.push_back(BuildMI(V9::CALL, 1).addReg(F)); + return true; + } default: return false; From criswell at cs.uiuc.edu Thu Aug 7 10:52:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 10:52:02 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/Makefile.common Message-ID: <200308071551.KAA09447@psmith.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.108 -> 1.108.2.1 --- Log message: Added the -s option to the cmp program. This will prevent spurious error output when the target file of the make rule doesn't exist (i.e. clean builds). --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.108 llvm/Makefile.common:1.108.2.1 --- llvm/Makefile.common:1.108 Tue Aug 5 16:38:28 2003 +++ llvm/Makefile.common Thu Aug 7 10:51:08 2003 @@ -773,7 +773,7 @@ $(SED) 's/void \*yy_flex_realloc/inline void *yy_flex_realloc/' | \ $(SED) 's/#define YY_BUF_SIZE 16384/#define YY_BUF_SIZE (16384*64)/' \ > $@.tmp - $(VERB) cmp $@ $@.tmp > /dev/null || ${MV} -f $@.tmp $@ + $(VERB) cmp -s $@ $@.tmp > /dev/null || ${MV} -f $@.tmp $@ @# remove the output of flex if it didn't get moved over... @rm -f $@.tmp @@ -783,8 +783,8 @@ %.cpp %.h : %.y @echo Bison\'ing $<... $(VERB) $(BISON) -v -d -p $(<:%Parser.y=%) $*.y - $(VERB) cmp $*.tab.c $*.cpp > /dev/null || ${MV} -f $*.tab.c $*.cpp - $(VERB) cmp $*.tab.h $*.h > /dev/null || ${MV} -f $*.tab.h $*.h + $(VERB) cmp -s $*.tab.c $*.cpp > /dev/null || ${MV} -f $*.tab.c $*.cpp + $(VERB) cmp -s $*.tab.h $*.h > /dev/null || ${MV} -f $*.tab.h $*.h @# If the files were not updated, don't leave them lying around... @rm -f $*.tab.c $*.tab.h From gaeke at cs.uiuc.edu Thu Aug 7 13:12:02 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 13:12:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Message-ID: <200308071811.NAA10672@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: SecondTrigger.cpp updated: 1.7 -> 1.8 --- Log message: Include scheduler.h to get its prototype(s). Give triggerBB and printBinary each a comment. Remove excess parameters that shadow globals from triggerBB. Replace uses of various `uint64_t one = 1' variables with constant 1ULL. Refactor find-first-bit-set in 64-bit int into a separate function. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.7 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.8 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.7 Wed Aug 6 16:52:05 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Thu Aug 7 13:11:44 2003 @@ -10,6 +10,7 @@ #include "GetTimer.h" #include "RegSaveRestore.h" +#include "scheduler.h" #include "Timer.h" #include "llvm/Reoptimizer/Mapping/LLVMinfo.h" #include "llvm/Reoptimizer/VirtualMem.h" @@ -49,8 +50,6 @@ extern "C" void llvm_first_trigger(int *cnt); -void insert_address_at(uint64_t n, uint64_t m); - // Forward declarations void generateTraces(uint64_t start, uint64_t end, std::vector &paths, @@ -62,8 +61,12 @@ std::map firstTriggerAddr; //tracestart addr std::map > backOffCounters; -void triggerBB(vector &vBB, VirtualMem *vm, TraceCache *tr, - TraceCache *tr2, uint64_t a) { +/// This method is called when we have finally constructed a +/// trace. The first parameter is the vector of basic blocks that form +/// the trace; the second parameter is presumably one of the starting +/// addresses for the trace. +/// +void triggerBB(vector &vBB, uint64_t a) { std::cerr << "We made it to triggerBB\n"; } @@ -173,17 +176,16 @@ for(int i=0, e = paths.size(); i-1; j--){ - if(temp & (one<>(j-x-1))<<(x)); + fin |= ((((1ULL << (j-x-1))&temp)>>(j-x-1))<<(x)); //std::cerr<<"Fin: "<<(void *)fin<<"\n"; paths[i] = fin; @@ -392,19 +394,28 @@ std::map &targetMap, std::map &callMap); +/// Find first set bit in the 64-bit number n. This should probably be +/// reworked to use libc's ffs(3), but note that the return values are +/// off by one and ffs() takes 32-bit ints. +/// +int firstBitSet (const uint64_t n) { + int x = 0; + for(x = 0; x<64; x++) + if(n & (1ULL << x)) + break; + return x; +} + void getIndexToStart(std::pair &prtoret, int pathNumber, std::vector &paths ){ - int toRet = 0; int pathChosen = 0; - uint64_t one = 1; for(int i=0; itoRet){ toRet = x; pathChosen = i; @@ -429,13 +440,9 @@ int getIndexToStart(int pathNumber, std::vector &paths ){ int toRet = 0; - uint64_t one = 1; for(int i=0; itoRet) toRet = x; } @@ -443,10 +450,12 @@ return toRet; } +/// Print the least-significant 32 bits of the number N, in binary, to +/// std::cerr, followed by a newline. +/// void printBinary(uint64_t n){ - uint64_t one = 1; for(int i=31; i>=0; i--) - std::cerr<<((n&(one<>i); + std::cerr<<((n&(1ULL <>i); std::cerr<<"\n"; } @@ -498,7 +507,7 @@ } } - triggerBB(vBB, vm, tr, tr2, firstLevelTraceStartAddr); + triggerBB(vBB, firstLevelTraceStartAddr); } #endif @@ -528,8 +537,6 @@ std::cerr<<"-----------\n"; #endif - uint64_t one = 1; //the constant 1 - //branch map and call map //map of call instructions std::map callMap; @@ -784,7 +791,7 @@ nextTrace = (*myIntersections)[pathIndex]; //is it taken? - if(firstPath & (one< Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.5 -> 1.6 InstrSelectorEmitter.h updated: 1.4 -> 1.5 --- Log message: Continued evolution of the selector emitter: Represent instruction patterns as first class objects --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.5 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.6 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.5 Thu Aug 7 01:02:15 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 14:12:24 2003 @@ -93,12 +93,60 @@ // Parse the specified DagInit into a TreePattern which we can use. // -TreePatternNode *InstrSelectorEmitter::ParseTreePattern(DagInit *DI, - const std::string &RecName) { +Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec, + InstrSelectorEmitter &ise) + : PTy(pty), TheRecord(TheRec), ISE(ise) { + + // First, parse the pattern... + Tree = ParseTreePattern(RawPat); + + bool MadeChange, AnyUnset; + do { + MadeChange = false; + AnyUnset = InferTypes(Tree, MadeChange); + } while ((AnyUnset || MadeChange) && !(AnyUnset && !MadeChange)); + + if (PTy == Instruction) { + // Check to make sure there is not any unset types in the tree pattern... + if (AnyUnset) { + std::cerr << "In instruction pattern: " << *Tree << "\n"; + error("Could not infer all types!"); + } + + // Check to see if we have a top-level (set) of a register. + if (Tree->getOperator()->getName() == "set") { + assert(Tree->getChildren().size() == 2 && "Set with != 2 arguments?"); + if (!Tree->getChild(0)->isLeaf()) + error("Arg #0 of set should be a register or register class!"); + DefInit *RegInit = dynamic_cast(Tree->getChild(0)->getValue()); + if (RegInit == 0) + error("LHS of 'set' expected to be a register or register class!"); + + Result = RegInit->getDef(); + Tree = Tree->getChild(1); + + } + } + + Resolved = !AnyUnset; +} + +void Pattern::error(const std::string &Msg) { + std::string M = "In "; + switch (PTy) { + case Nonterminal: M += "nonterminal "; break; + case Instruction: M += "instruction "; break; + case Expander : M += "expander "; break; + } + throw M + TheRecord->getName() + ": " + Msg; +} + + +TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) { Record *Operator = DI->getNodeType(); - if (!NodeTypes.count(Operator)) - throw "Illegal node for instruction pattern: '" + Operator->getName() +"'!"; + if (!ISE.getNodeTypes().count(Operator)) + error("Unrecognized node '" + Operator->getName() + "'!"); const std::vector &Args = DI->getArgs(); std::vector Children; @@ -106,14 +154,14 @@ for (unsigned i = 0, e = Args.size(); i != e; ++i) { Init *Arg = Args[i]; if (DagInit *DI = dynamic_cast(Arg)) { - Children.push_back(ParseTreePattern(DI, RecName)); + Children.push_back(ParseTreePattern(DI)); } else if (DefInit *DI = dynamic_cast(Arg)) { Children.push_back(new TreePatternNode(DI)); // If it's a regclass or something else known, set the type. Children.back()->setType(getIntrinsicType(DI->getDef())); } else { Arg->dump(); - throw "Unknown value for tree pattern in '" + RecName + "'!"; + error("Unknown leaf value for tree pattern!"); } } @@ -138,37 +186,36 @@ // InferTypes - Perform type inference on the tree, returning true if there // are any remaining untyped nodes and setting MadeChange if any changes were // made. -bool InstrSelectorEmitter::InferTypes(TreePatternNode *N, - const std::string &RecName, - bool &MadeChange) { +bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) { if (N->isLeaf()) return N->getType() == MVT::Other; bool AnyUnset = false; Record *Operator = N->getOperator(); - assert(NodeTypes.count(Operator) && "No node info for node!"); - const NodeType &NT = NodeTypes[Operator]; + assert(ISE.getNodeTypes().count(Operator) && "No node info for node!"); + const NodeType &NT = ISE.getNodeTypes()[Operator]; // Check to see if we can infer anything about the argument types from the // return types... const std::vector &Children = N->getChildren(); if (Children.size() != NT.ArgTypes.size()) - throw "In record " + RecName + " incorrect number of children for " + - Operator->getName() + " node!"; + error("Incorrect number of children for " + Operator->getName() + " node!"); for (unsigned i = 0, e = Children.size(); i != e; ++i) { - AnyUnset |= InferTypes(Children[i], RecName, MadeChange); - + AnyUnset |= InferTypes(Children[i], MadeChange); switch (NT.ArgTypes[i]) { case NodeType::Arg0: - MadeChange |= UpdateNodeType(Children[i], Children[0]->getType(),RecName); + MadeChange |= UpdateNodeType(Children[i], Children[0]->getType(), + TheRecord->getName()); break; case NodeType::Val: if (Children[i]->getType() == MVT::isVoid) - throw "In pattern for " + RecName + " should not get a void node!"; + error("Inferred a void node in an illegal place!"); break; case NodeType::Ptr: - MadeChange |= UpdateNodeType(Children[i],Target.getPointerType(),RecName); + MadeChange |= UpdateNodeType(Children[i], + ISE.getTarget().getPointerType(), + TheRecord->getName()); break; default: assert(0 && "Invalid argument ArgType!"); } @@ -177,18 +224,20 @@ // See if we can infer anything about the return type now... switch (NT.ResultType) { case NodeType::Void: - MadeChange |= UpdateNodeType(N, MVT::isVoid, RecName); + MadeChange |= UpdateNodeType(N, MVT::isVoid, TheRecord->getName()); break; case NodeType::Arg0: - MadeChange |= UpdateNodeType(N, Children[0]->getType(), RecName); + MadeChange |= UpdateNodeType(N, Children[0]->getType(), + TheRecord->getName()); break; case NodeType::Ptr: - MadeChange |= UpdateNodeType(N, Target.getPointerType(), RecName); + MadeChange |= UpdateNodeType(N, ISE.getTarget().getPointerType(), + TheRecord->getName()); break; case NodeType::Val: if (N->getType() == MVT::isVoid) - throw "In pattern for " + RecName + " should not get a void node!"; + error("Inferred a void node in an illegal place!"); break; default: assert(0 && "Unhandled type constraint!"); @@ -198,39 +247,36 @@ return AnyUnset | N->getType() == MVT::Other; } - -// ReadAndCheckPattern - Parse the specified DagInit into a pattern and then -// perform full type inference. -// -TreePatternNode *InstrSelectorEmitter::ReadAndCheckPattern(DagInit *DI, - const std::string &RecName) { - // First, parse the pattern... - TreePatternNode *Pattern = ParseTreePattern(DI, RecName); - - bool MadeChange, AnyUnset; - do { - MadeChange = false; - AnyUnset = InferTypes(Pattern, RecName, MadeChange); - if (AnyUnset && !MadeChange) { - std::cerr << "In pattern: " << *Pattern << "\n"; - throw "Cannot infer types for " + RecName; - } - } while (AnyUnset || MadeChange); - - return Pattern; +std::ostream &operator<<(std::ostream &OS, const Pattern &P) { + switch (P.getPatternType()) { + case Pattern::Nonterminal: OS << "Nonterminal pattern "; break; + case Pattern::Instruction: OS << "Instruction pattern "; break; + case Pattern::Expander: OS << "Expander pattern "; break; + } + + OS << P.getRecord()->getName() << ":\t"; + + if (Record *Result = P.getResult()) + OS << Result->getName() << " = "; + OS << *P.getTree(); + + if (!P.isResolved()) + OS << " [not completely resolved]"; + return OS; } + // ProcessNonTerminals - Read in all nonterminals and incorporate them into // our pattern database. -void InstrSelectorEmitter::ProcessNonTerminals() { +void InstrSelectorEmitter::ProcessNonterminals() { std::vector NTs = Records.getAllDerivedDefinitions("Nonterminal"); for (unsigned i = 0, e = NTs.size(); i != e; ++i) { DagInit *DI = NTs[i]->getValueAsDag("Pattern"); - TreePatternNode *Pattern = ReadAndCheckPattern(DI, NTs[i]->getName()); + Pattern *P = new Pattern(Pattern::Nonterminal, DI, NTs[i], *this); + - DEBUG(std::cerr << "Parsed nonterm pattern " << NTs[i]->getName() << "\t= " - << *Pattern << "\n"); + DEBUG(std::cerr << "Parsed " << *P << "\n"); } } @@ -243,10 +289,9 @@ for (unsigned i = 0, e = Insts.size(); i != e; ++i) { Record *Inst = Insts[i]; if (DagInit *DI = dynamic_cast(Inst->getValueInit("Pattern"))) { - TreePatternNode *Pattern = ReadAndCheckPattern(DI, Inst->getName()); + Pattern *P = new Pattern(Pattern::Instruction, DI, Inst, *this); - DEBUG(std::cerr << "Parsed inst pattern " << Inst->getName() << "\t= " - << *Pattern << "\n"); + DEBUG(std::cerr << "Parsed " << *P << "\n"); } } } @@ -257,7 +302,7 @@ ProcessNodeTypes(); // Read in all of the nonterminals... - //ProcessNonTerminals(); + ProcessNonterminals(); // Read all of the instruction patterns in... ProcessInstructionPatterns(); Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.4 llvm/utils/TableGen/InstrSelectorEmitter.h:1.5 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.4 Thu Aug 7 01:02:15 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 14:12:24 2003 @@ -14,7 +14,10 @@ #include class DagInit; class Init; +class InstrSelectorEmitter; +/// NodeType - Represents Information parsed from the DagNode entries. +/// struct NodeType { enum ArgResultTypes { // Both argument and return types... @@ -39,12 +42,17 @@ static ArgResultTypes Translate(Record *R); }; + + +/// TreePatternNode - Represent a node of the tree patterns. +/// class TreePatternNode { /// Operator - The operation that this node represents... this is null if this /// is a leaf. Record *Operator; /// Type - The inferred value type... + /// MVT::ValueType Type; /// Children - If this is not a leaf (Operator != 0), this is the subtrees @@ -52,6 +60,7 @@ std::vector Children; /// Value - If this node is a leaf, this indicates what the thing is. + /// Init *Value; public: TreePatternNode(Record *o, const std::vector &c) @@ -68,6 +77,11 @@ assert(Operator != 0 && "This is a leaf node!"); return Children; } + TreePatternNode *getChild(unsigned c) const { + assert(c < Children.size() && "Child access out of range!"); + return getChildren()[c]; + } + Init *getValue() const { assert(Operator == 0 && "This is not a leaf node!"); return Value; @@ -80,17 +94,98 @@ +/// Pattern - Represent a pattern of one form or another. Currently, three +/// types of patterns are possible: Instruction's, Nonterminals, and Expanders. +/// +struct Pattern { + enum PatternType { + Nonterminal, Instruction, Expander + }; +private: + /// PTy - The type of pattern this is. + /// + PatternType PTy; + + /// Tree - The tree pattern which corresponds to this pattern. Note that if + /// there was a (set) node on the outside level that it has been stripped off. + /// + TreePatternNode *Tree; + + /// Result - If this is an instruction or expander pattern, this is the + /// register result, specified with a (set) in the pattern. + /// + Record *Result; + + /// TheRecord - The actual TableGen record corresponding to this pattern. + /// + Record *TheRecord; + + /// Resolved - This is true of the pattern is useful in practice. In + /// particular, some non-terminals will have non-resolvable types. When a + /// user of the non-terminal is later found, they will have inferred a type + /// for the result of the non-terminal, which cause a clone of an unresolved + /// nonterminal to be made which is "resolved". + /// + bool Resolved; + + /// ISE - the instruction selector emitter coordinating this madness. + /// + InstrSelectorEmitter &ISE; +public: + + /// Pattern constructor - Parse the specified DagInitializer into the current + /// record. + Pattern(PatternType pty, DagInit *RawPat, Record *TheRec, + InstrSelectorEmitter &ise); + + /// getPatternType - Return what flavor of Record this pattern originated from + /// + PatternType getPatternType() const { return PTy; } + + /// getTree - Return the tree pattern which corresponds to this pattern. + /// + TreePatternNode *getTree() const { return Tree; } + + Record *getResult() const { return Result; } + + /// getRecord - Return the actual TableGen record corresponding to this + /// pattern. + /// + Record *getRecord() const { return TheRecord; } + + bool isResolved() const { return Resolved; } + +private: + TreePatternNode *ParseTreePattern(DagInit *DI); + bool InferTypes(TreePatternNode *N, bool &MadeChange); + void error(const std::string &Msg); +}; + +std::ostream &operator<<(std::ostream &OS, const Pattern &P); + + + +/// InstrSelectorEmitter - The top-level class which coordinates construction +/// and emission of the instruction selector. +/// class InstrSelectorEmitter : public TableGenBackend { RecordKeeper &Records; CodeGenTarget Target; std::map NodeTypes; + + /// Patterns - a list of all of the patterns defined by the target description + /// + std::map Patterns; public: InstrSelectorEmitter(RecordKeeper &R) : Records(R) {} // run - Output the instruction set description, returning true on failure. void run(std::ostream &OS); + const CodeGenTarget &getTarget() const { return Target; } + std::map &getNodeTypes() { return NodeTypes; } + private: // ProcessNodeTypes - Process all of the node types in the current // RecordKeeper, turning them into the more accessible NodeTypes data @@ -99,26 +194,11 @@ // ProcessNonTerminals - Read in all nonterminals and incorporate them into // our pattern database. - void ProcessNonTerminals(); + void ProcessNonterminals(); // ProcessInstructionPatterns - Read in all subclasses of Instruction, and // process those with a useful Pattern field. void ProcessInstructionPatterns(); - - // ParseTreePattern - Parse the specified DagInit into a TreePattern which we - // can use. - // - TreePatternNode *ParseTreePattern(DagInit *DI, const std::string &RecName); - - // InferTypes - Perform type inference on the tree, returning true if there - // are any remaining untyped nodes and setting MadeChange if any changes were - // made. - bool InferTypes(TreePatternNode *N, const std::string &RecName, - bool &MadeChange); - - // ReadAndCheckPattern - Parse the specified DagInit into a pattern and then - // perform full type inference. - TreePatternNode *ReadAndCheckPattern(DagInit *DI, const std::string &RecName); }; #endif From lattner at cs.uiuc.edu Thu Aug 7 14:22:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 14:22:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308071921.OAA17984@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.6 -> 1.7 InstrSelectorEmitter.h updated: 1.5 -> 1.6 --- Log message: Read in expanders too --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.6 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.7 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.6 Thu Aug 7 14:12:24 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 14:21:10 2003 @@ -42,6 +42,7 @@ /// void InstrSelectorEmitter::ProcessNodeTypes() { std::vector Nodes = Records.getAllDerivedDefinitions("DagNode"); + DEBUG(std::cerr << "Getting node types: "); for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { Record *Node = Nodes[i]; @@ -70,8 +71,9 @@ // Add the node type mapping now... NodeTypes[Node] = NodeType(RetTy, ArgTypes); - DEBUG(std::cerr << "Got node type '" << Node->getName() << "'\n"); + DEBUG(std::cerr << Node->getName() << ", "); } + DEBUG(std::cerr << "DONE!\n"); } static MVT::ValueType getIntrinsicType(Record *R) { @@ -106,10 +108,10 @@ AnyUnset = InferTypes(Tree, MadeChange); } while ((AnyUnset || MadeChange) && !(AnyUnset && !MadeChange)); - if (PTy == Instruction) { + if (PTy == Instruction || PTy == Expander) { // Check to make sure there is not any unset types in the tree pattern... if (AnyUnset) { - std::cerr << "In instruction pattern: " << *Tree << "\n"; + std::cerr << "In pattern: " << *Tree << "\n"; error("Could not infer all types!"); } @@ -296,6 +298,20 @@ } } +/// ProcessExpanderPatterns - Read in all expander patterns... +/// +void InstrSelectorEmitter::ProcessExpanderPatterns() { + std::vector Expanders = Records.getAllDerivedDefinitions("Expander"); + for (unsigned i = 0, e = Expanders.size(); i != e; ++i) { + Record *Expander = Expanders[i]; + DagInit *DI = Expanders[i]->getValueAsDag("Pattern"); + + Pattern *P = new Pattern(Pattern::Expander, DI, Expanders[i], *this); + + DEBUG(std::cerr << "Parsed " << *P << "\n"); + } +} + void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. @@ -308,5 +324,5 @@ ProcessInstructionPatterns(); // Read all of the Expander patterns in... - + ProcessExpanderPatterns(); } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.5 llvm/utils/TableGen/InstrSelectorEmitter.h:1.6 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.5 Thu Aug 7 14:12:24 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 14:21:10 2003 @@ -199,6 +199,9 @@ // ProcessInstructionPatterns - Read in all subclasses of Instruction, and // process those with a useful Pattern field. void ProcessInstructionPatterns(); + + // ProcessExpanderPatterns - Read in all of the expanded patterns. + void ProcessExpanderPatterns(); }; #endif From lattner at cs.uiuc.edu Thu Aug 7 14:30:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 14:30:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308071929.OAA19203@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.7 -> 1.8 InstrSelectorEmitter.h updated: 1.6 -> 1.7 --- Log message: Cleanup and reorganize code, no functional changes --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.7 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.8 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.7 Thu Aug 7 14:21:10 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 14:28:55 2003 @@ -19,6 +19,25 @@ throw "Unknown DagNodeValType '" + Name + "'!"; } + +//===----------------------------------------------------------------------===// +// TreePatternNode implementation +// + +// updateNodeType - Set the node type of N to VT if VT contains information. If +// N already contains a conflicting type, then throw an exception +// +bool TreePatternNode::updateNodeType(MVT::ValueType VT, + const std::string &RecName) { + if (VT == MVT::Other || getType() == VT) return false; + if (getType() == MVT::Other) { + setType(VT); + return true; + } + + throw "Type inferfence contradiction found for pattern " + RecName; +} + std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) { if (N.isLeaf()) return OS << N.getType() << ":" << *N.getValue(); @@ -35,63 +54,9 @@ } void TreePatternNode::dump() const { std::cerr << *this; } - -/// ProcessNodeTypes - Process all of the node types in the current -/// RecordKeeper, turning them into the more accessible NodeTypes data -/// structure. -/// -void InstrSelectorEmitter::ProcessNodeTypes() { - std::vector Nodes = Records.getAllDerivedDefinitions("DagNode"); - DEBUG(std::cerr << "Getting node types: "); - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { - Record *Node = Nodes[i]; - - // Translate the return type... - NodeType::ArgResultTypes RetTy = - NodeType::Translate(Node->getValueAsDef("RetType")); - - // Translate the arguments... - ListInit *Args = Node->getValueAsListInit("ArgTypes"); - std::vector ArgTypes; - - for (unsigned a = 0, e = Args->getSize(); a != e; ++a) { - if (DefInit *DI = dynamic_cast(Args->getElement(a))) - ArgTypes.push_back(NodeType::Translate(DI->getDef())); - else - throw "In node " + Node->getName() + ", argument is not a Def!"; - - if (a == 0 && ArgTypes.back() == NodeType::Arg0) - throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!"; - if (ArgTypes.back() == NodeType::Void) - throw "In node " + Node->getName() + ", args cannot be void type!"; - } - if (RetTy == NodeType::Arg0 && Args->getSize() == 0) - throw "In node " + Node->getName() + - ", invalid return type for nullary node!"; - - // Add the node type mapping now... - NodeTypes[Node] = NodeType(RetTy, ArgTypes); - DEBUG(std::cerr << Node->getName() << ", "); - } - DEBUG(std::cerr << "DONE!\n"); -} - -static MVT::ValueType getIntrinsicType(Record *R) { - // Check to see if this is a register or a register class... - const std::vector &SuperClasses = R->getSuperClasses(); - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - if (SuperClasses[i]->getName() == "RegisterClass") { - return getValueType(R->getValueAsDef("RegType")); - } else if (SuperClasses[i]->getName() == "Register") { - std::cerr << "WARNING: Explicit registers not handled yet!\n"; - return MVT::Other; - } else if (SuperClasses[i]->getName() == "Nonterminal") { - //std::cerr << "Warning nonterminal type not handled yet:" << R->getName() - // << "\n"; - return MVT::Other; - } - throw "Error: Unknown value used: " + R->getName(); -} +//===----------------------------------------------------------------------===// +// Pattern implementation +// // Parse the specified DagInit into a TreePattern which we can use. // @@ -143,6 +108,22 @@ throw M + TheRecord->getName() + ": " + Msg; } +static MVT::ValueType getIntrinsicType(Record *R) { + // Check to see if this is a register or a register class... + const std::vector &SuperClasses = R->getSuperClasses(); + for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) + if (SuperClasses[i]->getName() == "RegisterClass") { + return getValueType(R->getValueAsDef("RegType")); + } else if (SuperClasses[i]->getName() == "Register") { + std::cerr << "WARNING: Explicit registers not handled yet!\n"; + return MVT::Other; + } else if (SuperClasses[i]->getName() == "Nonterminal") { + //std::cerr << "Warning nonterminal type not handled yet:" << R->getName() + // << "\n"; + return MVT::Other; + } + throw "Error: Unknown value used: " + R->getName(); +} TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) { Record *Operator = DI->getNodeType(); @@ -170,20 +151,6 @@ return new TreePatternNode(Operator, Children); } -// UpdateNodeType - Set the node type of N to VT if VT contains information. If -// N already contains a conflicting type, then throw an exception -// -static bool UpdateNodeType(TreePatternNode *N, MVT::ValueType VT, - const std::string &RecName) { - if (VT == MVT::Other || N->getType() == VT) return false; - - if (N->getType() == MVT::Other) { - N->setType(VT); - return true; - } - - throw "Type inferfence contradiction found for pattern " + RecName; -} // InferTypes - Perform type inference on the tree, returning true if there // are any remaining untyped nodes and setting MadeChange if any changes were @@ -203,21 +170,21 @@ error("Incorrect number of children for " + Operator->getName() + " node!"); for (unsigned i = 0, e = Children.size(); i != e; ++i) { - AnyUnset |= InferTypes(Children[i], MadeChange); + TreePatternNode *Child = Children[i]; + AnyUnset |= InferTypes(Child, MadeChange); switch (NT.ArgTypes[i]) { case NodeType::Arg0: - MadeChange |= UpdateNodeType(Children[i], Children[0]->getType(), - TheRecord->getName()); + MadeChange |= Child->updateNodeType(Children[0]->getType(), + TheRecord->getName()); break; case NodeType::Val: - if (Children[i]->getType() == MVT::isVoid) + if (Child->getType() == MVT::isVoid) error("Inferred a void node in an illegal place!"); break; case NodeType::Ptr: - MadeChange |= UpdateNodeType(Children[i], - ISE.getTarget().getPointerType(), - TheRecord->getName()); + MadeChange |= Child->updateNodeType(ISE.getTarget().getPointerType(), + TheRecord->getName()); break; default: assert(0 && "Invalid argument ArgType!"); } @@ -226,16 +193,16 @@ // See if we can infer anything about the return type now... switch (NT.ResultType) { case NodeType::Void: - MadeChange |= UpdateNodeType(N, MVT::isVoid, TheRecord->getName()); + MadeChange |= N->updateNodeType(MVT::isVoid, TheRecord->getName()); break; case NodeType::Arg0: - MadeChange |= UpdateNodeType(N, Children[0]->getType(), - TheRecord->getName()); + MadeChange |= N->updateNodeType(Children[0]->getType(), + TheRecord->getName()); break; case NodeType::Ptr: - MadeChange |= UpdateNodeType(N, ISE.getTarget().getPointerType(), - TheRecord->getName()); + MadeChange |= N->updateNodeType(ISE.getTarget().getPointerType(), + TheRecord->getName()); break; case NodeType::Val: if (N->getType() == MVT::isVoid) @@ -267,6 +234,50 @@ return OS; } + +//===----------------------------------------------------------------------===// +// InstrSelectorEmitter implementation +// + +/// ProcessNodeTypes - Process all of the node types in the current +/// RecordKeeper, turning them into the more accessible NodeTypes data +/// structure. +/// +void InstrSelectorEmitter::ProcessNodeTypes() { + std::vector Nodes = Records.getAllDerivedDefinitions("DagNode"); + DEBUG(std::cerr << "Getting node types: "); + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + Record *Node = Nodes[i]; + + // Translate the return type... + NodeType::ArgResultTypes RetTy = + NodeType::Translate(Node->getValueAsDef("RetType")); + + // Translate the arguments... + ListInit *Args = Node->getValueAsListInit("ArgTypes"); + std::vector ArgTypes; + + for (unsigned a = 0, e = Args->getSize(); a != e; ++a) { + if (DefInit *DI = dynamic_cast(Args->getElement(a))) + ArgTypes.push_back(NodeType::Translate(DI->getDef())); + else + throw "In node " + Node->getName() + ", argument is not a Def!"; + + if (a == 0 && ArgTypes.back() == NodeType::Arg0) + throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!"; + if (ArgTypes.back() == NodeType::Void) + throw "In node " + Node->getName() + ", args cannot be void type!"; + } + if (RetTy == NodeType::Arg0 && Args->getSize() == 0) + throw "In node " + Node->getName() + + ", invalid return type for nullary node!"; + + // Add the node type mapping now... + NodeTypes[Node] = NodeType(RetTy, ArgTypes); + DEBUG(std::cerr << Node->getName() << ", "); + } + DEBUG(std::cerr << "DONE!\n"); +} // ProcessNonTerminals - Read in all nonterminals and incorporate them into // our pattern database. Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.6 llvm/utils/TableGen/InstrSelectorEmitter.h:1.7 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.6 Thu Aug 7 14:21:10 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 14:28:55 2003 @@ -88,6 +88,13 @@ } void dump() const; + + + // UpdateNodeType - Set the node type of N to VT if VT contains information. + // If N already contains a conflicting type, then throw an exception. This + // returns true if any information was updated. + // + bool updateNodeType(MVT::ValueType VT, const std::string &RecName); }; std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N); From gaeke at niobe.cs.uiuc.edu Thu Aug 7 14:38:01 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 14:38:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/GetTraceTime.pl Makefile.programs Message-ID: <200308071937.h77JbWl21251@niobe.cs.uiuc.edu> Changes in directory llvm/test/Programs: GetTraceTime.pl updated: 1.2 -> 1.3 Makefile.programs updated: 1.82 -> 1.83 --- Log message: GetTraceTime.pl: Determine $prog from $llc instead of passing it in as a separate argument. Pass output file in as a separate argument. Makefile.programs: Remove GetTraceTime, TIMESCRIPT, and GETTIMECOMPARISON for now. *.out-tracing are actually named *.out-trace. Remove *.performance rules that don't seem to work. --- Diffs of the changes: Index: llvm/test/Programs/GetTraceTime.pl diff -u llvm/test/Programs/GetTraceTime.pl:1.2 llvm/test/Programs/GetTraceTime.pl:1.3 --- llvm/test/Programs/GetTraceTime.pl:1.2 Mon Jul 21 17:00:30 2003 +++ llvm/test/Programs/GetTraceTime.pl Thu Aug 7 14:37:22 2003 @@ -1,6 +1,6 @@ #!/usr/bin/perl -($prog, $llc, $trace, @rest) = @ARGV; -$runs = $llc; $runs =~ s/llc/runs/; +($llc, $trace, $out) = @ARGV; +$prog = $llc; $prog =~ s/\.out.*$//; open LLC, $llc; foreach $line (){ @@ -36,7 +36,7 @@ $pct = "n/a"; $pct = sprintf("%.2f", ($time_t2/$time_t)*100.0) if ($time_t != 0); $report = "$prog percentage: $pct; time: $time_t2\n"; -if (open(OUTPUT, ">>$runs")) { +if (open(OUTPUT, ">>$out")) { print OUTPUT $report; close OUTPUT; } Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.82 llvm/test/Programs/Makefile.programs:1.83 --- llvm/test/Programs/Makefile.programs:1.82 Wed Aug 6 15:52:59 2003 +++ llvm/test/Programs/Makefile.programs Thu Aug 7 14:37:22 2003 @@ -56,8 +56,6 @@ # TIMEPROG - The program used to get timing results for a program TIMEPROG := $(PROGDIR)/TimeProgram.sh -TIMESCRIPT := $(PROGDIR)/GetTraceTime.pl - # DIFFPROG - The program used to diff the output DIFFPROG := $(PROGDIR)/DiffOutput.sh @@ -107,7 +105,7 @@ CBEOUTPUT := $(addsuffix .out-cbe, $(PREFIXED_PROGRAMS_TO_TEST)) #output for tracing framework -TRACINGOUTPUT := $(addsuffix .out-tracing, $(PREFIXED_PROGRAMS_TO_TEST)) +TRACINGOUTPUT := $(addsuffix .out-trace, $(PREFIXED_PROGRAMS_TO_TEST)) # Diffs of program runs vs the native program LLIDIFFS := $(addsuffix .diff-lli, $(PREFIXED_PROGRAMS_TO_TEST)) @@ -115,11 +113,8 @@ LLCDIFFS := $(addsuffix .diff-llc, $(PREFIXED_PROGRAMS_TO_TEST)) CBEDIFFS := $(addsuffix .diff-cbe, $(PREFIXED_PROGRAMS_TO_TEST)) -#Diffs for tracing framework -GETTIMECOMPARISON := $(addsuffix .performance, $(PREFIXED_PROGRAMS_TO_TEST)) - # Build Program outputs: -.PRECIOUS: Output/%.out-lli Output/%.out-jit Output/%.out-llc Output/%.out-tracing +.PRECIOUS: Output/%.out-lli Output/%.out-jit Output/%.out-llc Output/%.out-trace .PRECIOUS: Output/%.out-nat Output/%.out-cbe Output/%.llc.bc # Build diffs from the output... @@ -178,7 +173,7 @@ all:: $(TRACINGCODEGEN) all:: $(TRACINGLLCCODEGEN) all:: $(TRACINGEXECUTABLE) -all:: $(GETTIMECOMPARISON) +all:: $(TRACINGOUTPUT) DISABLE_CBE = 1 DISABLE_LLC_DIFFS = 1 @@ -379,13 +374,9 @@ Output/%.out-cbe: Output/%.cbe -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) -$(PROGRAMS_TO_TEST:%=Output/%.out-tracing): \ -Output/%.out-tracing: Output/%.trace +$(PROGRAMS_TO_TEST:%=Output/%.out-trace): \ +Output/%.out-trace: Output/%.trace -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) - -$(PROGRAMS_TO_TEST:%=Output/%.performance): \ -Output/%.performance: Output/%.out-llc.time Output/%.out-tracing.time - -$(TIMESCRIPT) $* Output/$*.out-llc.time Output/$*.out-tracing.time $@ endif From gaeke at niobe.cs.uiuc.edu Thu Aug 7 14:39:01 2003 From: gaeke at niobe.cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 14:39:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/GetTraceTime.pl Message-ID: <200308071938.h77Jck921284@niobe.cs.uiuc.edu> Changes in directory llvm/test/Programs: GetTraceTime.pl (r1.3) removed --- Log message: As this isn't being used anymore, we'll give it a new comfy home in the Attic. --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Aug 7 14:43:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 14:43:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp Message-ID: <200308071942.OAA20706@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.8 -> 1.9 --- Log message: Use the new version of isSubClassOf --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.8 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.9 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.8 Thu Aug 7 14:28:55 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 14:42:14 2003 @@ -110,18 +110,17 @@ static MVT::ValueType getIntrinsicType(Record *R) { // Check to see if this is a register or a register class... - const std::vector &SuperClasses = R->getSuperClasses(); - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - if (SuperClasses[i]->getName() == "RegisterClass") { - return getValueType(R->getValueAsDef("RegType")); - } else if (SuperClasses[i]->getName() == "Register") { - std::cerr << "WARNING: Explicit registers not handled yet!\n"; - return MVT::Other; - } else if (SuperClasses[i]->getName() == "Nonterminal") { - //std::cerr << "Warning nonterminal type not handled yet:" << R->getName() - // << "\n"; - return MVT::Other; - } + if (R->isSubClassOf("RegisterClass")) { + return getValueType(R->getValueAsDef("RegType")); + } else if (R->isSubClassOf("Register")) { + std::cerr << "WARNING: Explicit registers not handled yet!\n"; + return MVT::Other; + } else if (R->isSubClassOf("Nonterminal")) { + //std::cerr << "Warning nonterminal type not handled yet:" << R->getName() + // << "\n"; + return MVT::Other; + } + throw "Error: Unknown value used: " + R->getName(); } From lattner at cs.uiuc.edu Thu Aug 7 14:43:14 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 14:43:14 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Record.h Message-ID: <200308071942.OAA20713@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.10 -> 1.11 Record.h updated: 1.33 -> 1.34 --- Log message: Add and use a new method --- Diffs of the changes: Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.10 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.11 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.10 Thu Aug 7 00:39:09 2003 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Thu Aug 7 14:41:58 2003 @@ -73,7 +73,6 @@ Records.getAllDerivedDefinitions("RegisterClass"); std::vector Registers = Records.getAllDerivedDefinitions("Register"); - Record *RegisterClass = Records.getClass("Register"); std::set RegistersFound; std::vector RegClassNames; @@ -99,7 +98,7 @@ DefInit *RegDef = dynamic_cast(RegList->getElement(i)); if (!RegDef) throw "Register class member is not a record!"; Record *Reg = RegDef->getDef(); - if (!Reg->isSubClassOf(RegisterClass)) + if (!Reg->isSubClassOf("Register")) throw "Register Class member '" + Reg->getName() + " does not derive from the Register class!"; if (RegistersFound.count(Reg)) Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.33 llvm/utils/TableGen/Record.h:1.34 --- llvm/utils/TableGen/Record.h:1.33 Thu Aug 7 01:00:43 2003 +++ llvm/utils/TableGen/Record.h Thu Aug 7 14:41:59 2003 @@ -703,6 +703,13 @@ return false; } + bool isSubClassOf(const std::string &Name) const { + for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) + if (SuperClasses[i]->getName() == Name) + return true; + return false; + } + void addSuperClass(Record *R) { assert(!isSubClassOf(R) && "Already subclassing record!"); SuperClasses.push_back(R); From lattner at cs.uiuc.edu Thu Aug 7 15:00:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 15:00:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp Message-ID: <200308071959.OAA21862@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.9 -> 1.10 --- Log message: Add support for "cast" nodes, which are required when there is not enough information to infer type type of all nodes, e.g. (ret imm) --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.9 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.10 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.9 Thu Aug 7 14:42:14 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 14:59:42 2003 @@ -52,6 +52,7 @@ } return OS << ")"; } + void TreePatternNode::dump() const { std::cerr << *this; } //===----------------------------------------------------------------------===// @@ -126,11 +127,33 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) { Record *Operator = DI->getNodeType(); + const std::vector &Args = DI->getArgs(); + + if (Operator->isSubClassOf("ValueType")) { + // If the operator is a ValueType, then this must be "type cast" of a leaf + // node. + if (Args.size() != 1) + error("Type cast only valid for a leaf node!"); + + Init *Arg = Args[0]; + TreePatternNode *New; + if (DefInit *DI = dynamic_cast(Arg)) { + New = new TreePatternNode(DI); + // If it's a regclass or something else known, set the type. + New->setType(getIntrinsicType(DI->getDef())); + } else { + Arg->dump(); + error("Unknown leaf value for tree pattern!"); + } + + // Apply the type cast... + New->updateNodeType(getValueType(Operator), TheRecord->getName()); + return New; + } if (!ISE.getNodeTypes().count(Operator)) error("Unrecognized node '" + Operator->getName() + "'!"); - const std::vector &Args = DI->getArgs(); std::vector Children; for (unsigned i = 0, e = Args.size(); i != e; ++i) { From lattner at cs.uiuc.edu Thu Aug 7 15:43:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 15:43:03 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308072042.PAA23283@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.10 -> 1.11 InstrSelectorEmitter.h updated: 1.7 -> 1.8 --- Log message: Rename all of the "Process" methods to be "read" methods, start the Instantiate method --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.10 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.11 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.10 Thu Aug 7 14:59:42 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 15:42:23 2003 @@ -261,11 +261,10 @@ // InstrSelectorEmitter implementation // -/// ProcessNodeTypes - Process all of the node types in the current -/// RecordKeeper, turning them into the more accessible NodeTypes data -/// structure. +/// ReadNodeTypes - Read in all of the node types in the current RecordKeeper, +/// turning them into the more accessible NodeTypes data structure. /// -void InstrSelectorEmitter::ProcessNodeTypes() { +void InstrSelectorEmitter::ReadNodeTypes() { std::vector Nodes = Records.getAllDerivedDefinitions("DagNode"); DEBUG(std::cerr << "Getting node types: "); for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { @@ -301,61 +300,66 @@ DEBUG(std::cerr << "DONE!\n"); } -// ProcessNonTerminals - Read in all nonterminals and incorporate them into -// our pattern database. -void InstrSelectorEmitter::ProcessNonterminals() { +// ReadNonTerminals - Read in all nonterminals and incorporate them into our +// pattern database. +void InstrSelectorEmitter::ReadNonterminals() { std::vector NTs = Records.getAllDerivedDefinitions("Nonterminal"); for (unsigned i = 0, e = NTs.size(); i != e; ++i) { DagInit *DI = NTs[i]->getValueAsDag("Pattern"); - Pattern *P = new Pattern(Pattern::Nonterminal, DI, NTs[i], *this); - - - DEBUG(std::cerr << "Parsed " << *P << "\n"); + Patterns[NTs[i]] = new Pattern(Pattern::Nonterminal, DI, NTs[i], *this); + DEBUG(std::cerr << "Parsed " << *Patterns[NTs[i]] << "\n"); } } -/// ProcessInstructionPatterns - Read in all subclasses of Instruction, and -/// process those with a useful Pattern field. +/// ReadInstructionPatterns - Read in all subclasses of Instruction, and process +/// those with a useful Pattern field. /// -void InstrSelectorEmitter::ProcessInstructionPatterns() { +void InstrSelectorEmitter::ReadInstructionPatterns() { std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); for (unsigned i = 0, e = Insts.size(); i != e; ++i) { Record *Inst = Insts[i]; if (DagInit *DI = dynamic_cast(Inst->getValueInit("Pattern"))) { - Pattern *P = new Pattern(Pattern::Instruction, DI, Inst, *this); - - DEBUG(std::cerr << "Parsed " << *P << "\n"); + Patterns[Inst] = new Pattern(Pattern::Instruction, DI, Inst, *this); + DEBUG(std::cerr << "Parsed " << *Patterns[Inst] << "\n"); } } } -/// ProcessExpanderPatterns - Read in all expander patterns... +/// ReadExpanderPatterns - Read in all expander patterns... /// -void InstrSelectorEmitter::ProcessExpanderPatterns() { +void InstrSelectorEmitter::ReadExpanderPatterns() { std::vector Expanders = Records.getAllDerivedDefinitions("Expander"); for (unsigned i = 0, e = Expanders.size(); i != e; ++i) { Record *Expander = Expanders[i]; - DagInit *DI = Expanders[i]->getValueAsDag("Pattern"); + DagInit *DI = Expander->getValueAsDag("Pattern"); + Patterns[Expander] = new Pattern(Pattern::Expander, DI, Expander, *this); + DEBUG(std::cerr << "Parsed " << *Patterns[Expander] << "\n"); + } +} + - Pattern *P = new Pattern(Pattern::Expander, DI, Expanders[i], *this); +// InstantiateNonterminals - Instantiate any unresolved nonterminals with +// information from the context that they are used in. +void InstrSelectorEmitter::InstantiateNonterminals() { + for (std::map::iterator I = Patterns.begin(), + E = Patterns.end(); I != E; ++I) { - DEBUG(std::cerr << "Parsed " << *P << "\n"); } } void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. - ProcessNodeTypes(); + ReadNodeTypes(); - // Read in all of the nonterminals... - ProcessNonterminals(); - - // Read all of the instruction patterns in... - ProcessInstructionPatterns(); - - // Read all of the Expander patterns in... - ProcessExpanderPatterns(); + // Read in all of the nonterminals, instructions, and expanders... + ReadNonterminals(); + ReadInstructionPatterns(); + ReadExpanderPatterns(); + + // Instantiate any unresolved nonterminals with information from the context + // that they are used in. + InstantiateNonterminals(); } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.7 llvm/utils/TableGen/InstrSelectorEmitter.h:1.8 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.7 Thu Aug 7 14:28:55 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 15:42:23 2003 @@ -194,21 +194,24 @@ std::map &getNodeTypes() { return NodeTypes; } private: - // ProcessNodeTypes - Process all of the node types in the current - // RecordKeeper, turning them into the more accessible NodeTypes data - // structure. - void ProcessNodeTypes(); + // ReadNodeTypes - Read in all of the node types in the current RecordKeeper, + // turning them into the more accessible NodeTypes data structure. + void ReadNodeTypes(); - // ProcessNonTerminals - Read in all nonterminals and incorporate them into - // our pattern database. - void ProcessNonterminals(); + // ReadNonTerminals - Read in all nonterminals and incorporate them into our + // pattern database. + void ReadNonterminals(); - // ProcessInstructionPatterns - Read in all subclasses of Instruction, and + // ReadInstructionPatterns - Read in all subclasses of Instruction, and // process those with a useful Pattern field. - void ProcessInstructionPatterns(); + void ReadInstructionPatterns(); - // ProcessExpanderPatterns - Read in all of the expanded patterns. - void ProcessExpanderPatterns(); + // ReadExpanderPatterns - Read in all of the expanded patterns. + void ReadExpanderPatterns(); + + // InstantiateNonterminals - Instantiate any unresolved nonterminals with + // information from the context that they are used in. + void InstantiateNonterminals(); }; #endif From lattner at cs.uiuc.edu Thu Aug 7 16:04:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 16:04:02 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308072103.QAA26090@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.11 -> 1.12 InstrSelectorEmitter.h updated: 1.8 -> 1.9 --- Log message: Implement type-inference/checking for non-terminal references --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.11 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.12 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.11 Thu Aug 7 15:42:23 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 16:02:56 2003 @@ -99,7 +99,7 @@ Resolved = !AnyUnset; } -void Pattern::error(const std::string &Msg) { +void Pattern::error(const std::string &Msg) const { std::string M = "In "; switch (PTy) { case Nonterminal: M += "nonterminal "; break; @@ -109,17 +109,19 @@ throw M + TheRecord->getName() + ": " + Msg; } -static MVT::ValueType getIntrinsicType(Record *R) { +/// getIntrinsicType - Check to see if the specified record has an intrinsic +/// type which should be applied to it. This infer the type of register +/// references from the register file information, for example. +/// +MVT::ValueType Pattern::getIntrinsicType(Record *R) const { // Check to see if this is a register or a register class... - if (R->isSubClassOf("RegisterClass")) { + if (R->isSubClassOf("RegisterClass")) return getValueType(R->getValueAsDef("RegType")); - } else if (R->isSubClassOf("Register")) { + else if (R->isSubClassOf("Nonterminal")) + return ISE.ReadNonterminal(R)->getTree()->getType(); + else if (R->isSubClassOf("Register")) { std::cerr << "WARNING: Explicit registers not handled yet!\n"; return MVT::Other; - } else if (R->isSubClassOf("Nonterminal")) { - //std::cerr << "Warning nonterminal type not handled yet:" << R->getName() - // << "\n"; - return MVT::Other; } throw "Error: Unknown value used: " + R->getName(); @@ -238,6 +240,15 @@ return AnyUnset | N->getType() == MVT::Other; } +/// InstantiateNonterminalsReferenced - If this pattern refers to any +/// nonterminals which are not themselves completely resolved, clone the +/// nonterminal and resolve it with the using context we provide. +/// +void Pattern::InstantiateNonterminalsReferenced() { + +} + + std::ostream &operator<<(std::ostream &OS, const Pattern &P) { switch (P.getPatternType()) { case Pattern::Nonterminal: OS << "Nonterminal pattern "; break; @@ -300,16 +311,23 @@ DEBUG(std::cerr << "DONE!\n"); } +Pattern *InstrSelectorEmitter::ReadNonterminal(Record *R) { + Pattern *&P = Patterns[R]; + if (P) return P; // Don't reread it! + + DagInit *DI = R->getValueAsDag("Pattern"); + P = new Pattern(Pattern::Nonterminal, DI, R, *this); + DEBUG(std::cerr << "Parsed " << *P << "\n"); + return P; +} + + // ReadNonTerminals - Read in all nonterminals and incorporate them into our // pattern database. void InstrSelectorEmitter::ReadNonterminals() { std::vector NTs = Records.getAllDerivedDefinitions("Nonterminal"); - for (unsigned i = 0, e = NTs.size(); i != e; ++i) { - DagInit *DI = NTs[i]->getValueAsDag("Pattern"); - - Patterns[NTs[i]] = new Pattern(Pattern::Nonterminal, DI, NTs[i], *this); - DEBUG(std::cerr << "Parsed " << *Patterns[NTs[i]] << "\n"); - } + for (unsigned i = 0, e = NTs.size(); i != e; ++i) + ReadNonterminal(NTs[i]); } @@ -342,11 +360,12 @@ // InstantiateNonterminals - Instantiate any unresolved nonterminals with // information from the context that they are used in. +// void InstrSelectorEmitter::InstantiateNonterminals() { for (std::map::iterator I = Patterns.begin(), - E = Patterns.end(); I != E; ++I) { - - } + E = Patterns.end(); I != E; ++I) + if (I->second->isResolved()) + I->second->InstantiateNonterminalsReferenced(); } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.8 llvm/utils/TableGen/InstrSelectorEmitter.h:1.9 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.8 Thu Aug 7 15:42:23 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 16:02:56 2003 @@ -162,10 +162,15 @@ bool isResolved() const { return Resolved; } + /// InstantiateNonterminalsReferenced - If this pattern refers to any + /// nonterminals which are not themselves completely resolved, clone the + /// nonterminal and resolve it with the using context we provide. + void InstantiateNonterminalsReferenced(); private: + MVT::ValueType getIntrinsicType(Record *R) const; TreePatternNode *ParseTreePattern(DagInit *DI); bool InferTypes(TreePatternNode *N, bool &MadeChange); - void error(const std::string &Msg); + void error(const std::string &Msg) const; }; std::ostream &operator<<(std::ostream &OS, const Pattern &P); @@ -192,6 +197,17 @@ const CodeGenTarget &getTarget() const { return Target; } std::map &getNodeTypes() { return NodeTypes; } + + /// getPattern - return the pattern corresponding to the specified record, or + /// null if there is none. + Pattern *getPattern(Record *R) const { + std::map::const_iterator I = Patterns.find(R); + return I != Patterns.end() ? I->second : 0; + } + + /// ReadNonterminal - This method parses the specified record as a + /// nonterminal, but only if it hasn't been read in already. + Pattern *ReadNonterminal(Record *R); private: // ReadNodeTypes - Read in all of the node types in the current RecordKeeper, From brukman at cs.uiuc.edu Thu Aug 7 16:05:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:05:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp CrashDebugger.cpp ExecutionDriver.cpp Miscompilation.cpp OptimizerDriver.cpp SystemUtils.h SystemUtils.cpp Message-ID: <200308072104.QAA16948@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.9 -> 1.10 CrashDebugger.cpp updated: 1.14 -> 1.15 ExecutionDriver.cpp updated: 1.15 -> 1.16 Miscompilation.cpp updated: 1.12 -> 1.13 OptimizerDriver.cpp updated: 1.8 -> 1.9 SystemUtils.h (r1.1) removed SystemUtils.cpp (r1.9) removed --- Log message: Moved SystemUtils.h to include/Support and SystemUtils.cpp to lib/Support. --- Diffs of the changes: Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.9 llvm/tools/bugpoint/BugDriver.cpp:1.10 --- llvm/tools/bugpoint/BugDriver.cpp:1.9 Thu Jul 24 16:59:10 2003 +++ llvm/tools/bugpoint/BugDriver.cpp Thu Aug 7 16:04:42 2003 @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include "llvm/Module.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Assembly/Parser.h" Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.14 llvm/tools/bugpoint/CrashDebugger.cpp:1.15 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.14 Tue Aug 5 10:51:05 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Thu Aug 7 16:04:42 2003 @@ -5,7 +5,7 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include "ListReducer.h" #include "llvm/Module.h" #include "llvm/PassManager.h" Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.15 llvm/tools/bugpoint/ExecutionDriver.cpp:1.16 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.15 Sun Aug 3 19:56:43 2003 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu Aug 7 16:04:42 2003 @@ -15,7 +15,7 @@ */ #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include "Support/CommandLine.h" #include "Support/Debug.h" #include "Support/FileUtilities.h" Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.12 llvm/tools/bugpoint/Miscompilation.cpp:1.13 --- llvm/tools/bugpoint/Miscompilation.cpp:1.12 Mon Aug 4 14:03:42 2003 +++ llvm/tools/bugpoint/Miscompilation.cpp Thu Aug 7 16:04:42 2003 @@ -5,7 +5,7 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include "ListReducer.h" #include "llvm/Pass.h" #include "llvm/Module.h" Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.8 llvm/tools/bugpoint/OptimizerDriver.cpp:1.9 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.8 Mon Jul 21 16:58:16 2003 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Thu Aug 7 16:04:42 2003 @@ -9,7 +9,7 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/WriteBytecodePass.h" From brukman at cs.uiuc.edu Thu Aug 7 16:06:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:06:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CodeGeneratorBug.cpp Message-ID: <200308072105.QAA16973@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CodeGeneratorBug.cpp updated: 1.11 -> 1.12 --- Log message: Fixed path for SystemUtils.h and a few code cleanups. --- Diffs of the changes: Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.11 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.12 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.11 Sun Aug 3 19:56:27 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Thu Aug 7 16:05:13 2003 @@ -5,7 +5,7 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include "ListReducer.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -236,17 +236,15 @@ int Result = BD.diffProgram(TestModuleBC, SharedObject, false); if (Result) - std::cerr << ": Still failing!\n"; + std::cerr << ": still failing!\n"; else std::cerr << ": didn't fail.\n"; - if (KeepFiles) { std::cout << "You can reproduce the problem with the command line: \n"; if (BD.isExecutingJIT()) { std::cout << " lli -load " << SharedObject << " " << TestModuleBC; } else { - //<< (BD.isExecutingJIT() ? "lli" : "llc") std::cout << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; std::cout << " gcc " << SharedObject << " " << TestModuleBC << ".s -o " << TestModuleBC << ".exe\n"; @@ -255,8 +253,8 @@ for (unsigned i=0, e = InputArgv.size(); i != e; ++i) std::cout << " " << InputArgv[i]; std::cout << "\n"; - std::cout << "The shared object " << SharedObject << " was created from " - << SafeModuleBC << ", using `dis -c'.\n"; + std::cout << "The shared object was created with:\ndis -c " << SafeModuleBC + << "-o " << SharedObject << "\n"; } else { removeFile(TestModuleBC); removeFile(SafeModuleBC); @@ -350,7 +348,7 @@ Function *oldMain = Program->getNamedFunction("main"); assert(oldMain && "`main' function not found in program!"); // Rename it - oldMain->setName("old_main"); + oldMain->setName("llvm_old_main"); // Create a NEW `main' function with same type Function *newMain = new Function(oldMain->getFunctionType(), GlobalValue::ExternalLinkage, From brukman at cs.uiuc.edu Thu Aug 7 16:20:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:20:02 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp CodeGeneratorBug.cpp CrashDebugger.cpp ExecutionDriver.cpp ExtractFunction.cpp Miscompilation.cpp OptimizerDriver.cpp TestPasses.cpp bugpoint.cpp Message-ID: <200308072119.QAA18076@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.10 -> 1.11 CodeGeneratorBug.cpp updated: 1.12 -> 1.13 CrashDebugger.cpp updated: 1.15 -> 1.16 ExecutionDriver.cpp updated: 1.16 -> 1.17 ExtractFunction.cpp updated: 1.12 -> 1.13 Miscompilation.cpp updated: 1.13 -> 1.14 OptimizerDriver.cpp updated: 1.9 -> 1.10 TestPasses.cpp updated: 1.2 -> 1.3 bugpoint.cpp updated: 1.5 -> 1.6 --- Log message: Re-grouped and alphabetized headers for easier reading and cleaner style. --- Diffs of the changes: Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.10 llvm/tools/bugpoint/BugDriver.cpp:1.11 --- llvm/tools/bugpoint/BugDriver.cpp:1.10 Thu Aug 7 16:04:42 2003 +++ llvm/tools/bugpoint/BugDriver.cpp Thu Aug 7 16:19:30 2003 @@ -7,13 +7,13 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "Support/SystemUtils.h" #include "llvm/Module.h" -#include "llvm/Bytecode/Reader.h" +#include "llvm/Pass.h" #include "llvm/Assembly/Parser.h" +#include "llvm/Bytecode/Reader.h" #include "llvm/Transforms/Utils/Linker.h" -#include "llvm/Pass.h" #include "Support/CommandLine.h" +#include "Support/SystemUtils.h" #include // Anonymous namespace to define command line options for debugging. Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.12 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.13 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.12 Thu Aug 7 16:05:13 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Thu Aug 7 16:19:30 2003 @@ -5,7 +5,6 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "Support/SystemUtils.h" #include "ListReducer.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -23,6 +22,7 @@ #include "Support/CommandLine.h" #include "Support/Debug.h" #include "Support/StringExtras.h" +#include "Support/SystemUtils.h" #include #include Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.15 llvm/tools/bugpoint/CrashDebugger.cpp:1.16 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.15 Thu Aug 7 16:04:42 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Thu Aug 7 16:19:30 2003 @@ -5,20 +5,20 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "Support/SystemUtils.h" #include "ListReducer.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Pass.h" #include "llvm/Constant.h" #include "llvm/iTerminators.h" -#include "llvm/Type.h" +#include "llvm/Module.h" +#include "llvm/Pass.h" +#include "llvm/PassManager.h" #include "llvm/SymbolTable.h" -#include "llvm/Support/CFG.h" +#include "llvm/Type.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/Bytecode/Writer.h" +#include "llvm/Support/CFG.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Bytecode/Writer.h" +#include "Support/SystemUtils.h" #include #include Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.16 llvm/tools/bugpoint/ExecutionDriver.cpp:1.17 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.16 Thu Aug 7 16:04:42 2003 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu Aug 7 16:19:30 2003 @@ -15,10 +15,10 @@ */ #include "BugDriver.h" -#include "Support/SystemUtils.h" #include "Support/CommandLine.h" #include "Support/Debug.h" #include "Support/FileUtilities.h" +#include "Support/SystemUtils.h" #include #include Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.12 llvm/tools/bugpoint/ExtractFunction.cpp:1.13 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.12 Tue Aug 5 10:51:05 2003 +++ llvm/tools/bugpoint/ExtractFunction.cpp Thu Aug 7 16:19:30 2003 @@ -6,14 +6,14 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" +#include "llvm/Constant.h" #include "llvm/Module.h" #include "llvm/PassManager.h" +#include "llvm/Type.h" +#include "llvm/Analysis/Verifier.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Type.h" -#include "llvm/Constant.h" #include "Support/CommandLine.h" bool DisableSimplifyCFG = false; Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.13 llvm/tools/bugpoint/Miscompilation.cpp:1.14 --- llvm/tools/bugpoint/Miscompilation.cpp:1.13 Thu Aug 7 16:04:42 2003 +++ llvm/tools/bugpoint/Miscompilation.cpp Thu Aug 7 16:19:30 2003 @@ -5,12 +5,12 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "Support/SystemUtils.h" #include "ListReducer.h" -#include "llvm/Pass.h" #include "llvm/Module.h" +#include "llvm/Pass.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Linker.h" +#include "Support/SystemUtils.h" class ReduceMiscompilingPasses : public ListReducer { BugDriver &BD; Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.9 llvm/tools/bugpoint/OptimizerDriver.cpp:1.10 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.9 Thu Aug 7 16:04:42 2003 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Thu Aug 7 16:19:30 2003 @@ -9,16 +9,16 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "Support/SystemUtils.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/Target/TargetData.h" +#include "Support/SystemUtils.h" +#include +#include +#include #include #include -#include -#include -#include /// writeProgramToFile - This writes the current "Program" to the named bytecode /// file. If an error occurs, true is returned. Index: llvm/tools/bugpoint/TestPasses.cpp diff -u llvm/tools/bugpoint/TestPasses.cpp:1.2 llvm/tools/bugpoint/TestPasses.cpp:1.3 --- llvm/tools/bugpoint/TestPasses.cpp:1.2 Wed Apr 23 11:38:00 2003 +++ llvm/tools/bugpoint/TestPasses.cpp Thu Aug 7 16:19:30 2003 @@ -5,11 +5,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Pass.h" +#include "llvm/BasicBlock.h" +#include "llvm/Constant.h" #include "llvm/iOther.h" +#include "llvm/Pass.h" #include "llvm/Support/InstVisitor.h" -#include "llvm/Constant.h" -#include "llvm/BasicBlock.h" namespace { /// CrashOnCalls - This pass is used to test bugpoint. It intentionally Index: llvm/tools/bugpoint/bugpoint.cpp diff -u llvm/tools/bugpoint/bugpoint.cpp:1.5 llvm/tools/bugpoint/bugpoint.cpp:1.6 --- llvm/tools/bugpoint/bugpoint.cpp:1.5 Wed Jul 30 12:59:23 2003 +++ llvm/tools/bugpoint/bugpoint.cpp Thu Aug 7 16:19:30 2003 @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "Support/CommandLine.h" #include "llvm/Support/PassNameParser.h" +#include "Support/CommandLine.h" static cl::list InputFilenames(cl::Positional, cl::OneOrMore, From brukman at cs.uiuc.edu Thu Aug 7 16:25:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:25:01 2003 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200308072124.QAA18134@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.66 -> 1.67 --- Log message: * The possessive third-person singular has no apostrophe (its) * Grouped header files to fit with the LLVM standard * Fit code into 80 columns --- Diffs of the changes: Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.66 llvm/tools/gccas/gccas.cpp:1.67 --- llvm/tools/gccas/gccas.cpp:1.66 Sun Jun 22 15:11:45 2003 +++ llvm/tools/gccas/gccas.cpp Thu Aug 7 16:23:52 2003 @@ -1,22 +1,22 @@ //===----------------------------------------------------------------------===// // LLVM 'GCCAS' UTILITY // -// This utility is designed to be used by the GCC frontend for creating -// bytecode files from it's intermediate llvm assembly. The requirements for -// this utility are thus slightly different than that of the standard as util. +// This utility is designed to be used by the GCC frontend for creating bytecode +// files from its intermediate LLVM assembly. The requirements for this utility +// are thus slightly different than that of the standard `as' util. // //===----------------------------------------------------------------------===// #include "llvm/Module.h" #include "llvm/PassManager.h" -#include "llvm/Assembly/Parser.h" -#include "llvm/Transforms/RaisePointerReferences.h" -#include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/Scalar.h" #include "llvm/Analysis/LoadValueNumbering.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/Assembly/Parser.h" #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/Target/TargetData.h" +#include "llvm/Transforms/RaisePointerReferences.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Scalar.h" #include "Support/CommandLine.h" #include "Support/Signals.h" #include @@ -75,7 +75,8 @@ addPass(PM, createPromoteMemoryToRegister()); // Promote alloca's to regs addPass(PM, createIndVarSimplifyPass()); // Simplify indvars addPass(PM, createReassociatePass()); // Reassociate expressions - //addPass(PM, createCorrelatedExpressionEliminationPass());// Kill corr branches + // Kill corr branches + //addPass(PM, createCorrelatedExpressionEliminationPass()); addPass(PM, createInstructionCombiningPass()); // Combine silly seq's addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs addPass(PM, createLICMPass()); // Hoist loop invariants From brukman at cs.uiuc.edu Thu Aug 7 16:29:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:29:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/FileUtilities.h SystemUtils.h Message-ID: <200308072128.QAA18209@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: FileUtilities.h updated: 1.1 -> 1.2 SystemUtils.h updated: 1.1 -> 1.2 --- Log message: Moved removeFile() and getUniqueFilename() into FileUtilities. --- Diffs of the changes: Index: llvm/include/Support/FileUtilities.h diff -u llvm/include/Support/FileUtilities.h:1.1 llvm/include/Support/FileUtilities.h:1.2 --- llvm/include/Support/FileUtilities.h:1.1 Fri Aug 1 15:28:55 2003 +++ llvm/include/Support/FileUtilities.h Thu Aug 7 16:28:47 2003 @@ -26,4 +26,14 @@ /// void MoveFileOverIfUpdated(const std::string &New, const std::string &Old); +/// removeFile - Delete the specified file +/// +void removeFile(const std::string &Filename); + +/// getUniqueFilename - Return a filename with the specified prefix. If the +/// file does not exist yet, return it, otherwise add a suffix to make it +/// unique. +/// +std::string getUniqueFilename(const std::string &FilenameBase); + #endif Index: llvm/include/Support/SystemUtils.h diff -u llvm/include/Support/SystemUtils.h:1.1 llvm/include/Support/SystemUtils.h:1.2 --- llvm/include/Support/SystemUtils.h:1.1 Mon Dec 23 17:50:16 2002 +++ llvm/include/Support/SystemUtils.h Thu Aug 7 16:28:47 2003 @@ -22,16 +22,6 @@ std::string FindExecutable(const std::string &ExeName, const std::string &BugPointPath); -/// removeFile - Delete the specified file -/// -void removeFile(const std::string &Filename); - -/// getUniqueFilename - Return a filename with the specified prefix. If the -/// file does not exist yet, return it, otherwise add a suffix to make it -/// unique. -/// -std::string getUniqueFilename(const std::string &FilenameBase); - /// RunProgramWithTimeout - This function executes the specified program, with /// the specified null-terminated argument array, with the stdin/out/err fd's /// redirected, with a timeout specified on the commandline. This terminates From brukman at cs.uiuc.edu Thu Aug 7 16:30:03 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:30:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp SystemUtils.cpp Message-ID: <200308072129.QAA18218@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.1 -> 1.2 SystemUtils.cpp updated: 1.9 -> 1.10 --- Log message: Moved removeFile() and getUniqueFilename() into FileUtilities. --- Diffs of the changes: Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.1 llvm/lib/Support/FileUtilities.cpp:1.2 --- llvm/lib/Support/FileUtilities.cpp:1.1 Fri Aug 1 16:16:14 2003 +++ llvm/lib/Support/FileUtilities.cpp Thu Aug 7 16:28:50 2003 @@ -54,3 +54,38 @@ std::remove(New.c_str()); } } + +/// removeFile - Delete the specified file +/// +void removeFile(const std::string &Filename) { + std::remove(Filename.c_str()); +} + +/// getUniqueFilename - Return a filename with the specified prefix. If the +/// file does not exist yet, return it, otherwise add a suffix to make it +/// unique. +/// +std::string getUniqueFilename(const std::string &FilenameBase) { + if (!std::ifstream(FilenameBase.c_str())) + return FilenameBase; // Couldn't open the file? Use it! + + // Create a pattern for mkstemp... + char *FNBuffer = new char[FilenameBase.size()+8]; + strcpy(FNBuffer, FilenameBase.c_str()); + strcpy(FNBuffer+FilenameBase.size(), "-XXXXXX"); + + // Agree on a temporary file name to use.... + int TempFD; + if ((TempFD = mkstemp(FNBuffer)) == -1) { + std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current " + << " directory!\n"; + exit(1); + } + + // We don't need to hold the temp file descriptor... we will trust that noone + // will overwrite/delete the file while we are working on it... + close(TempFD); + std::string Result(FNBuffer); + delete[] FNBuffer; + return Result; +} Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.9 llvm/lib/Support/SystemUtils.cpp:1.10 --- llvm/lib/Support/SystemUtils.cpp:1.9 Fri Aug 1 15:29:18 2003 +++ llvm/lib/Support/SystemUtils.cpp Thu Aug 7 16:28:50 2003 @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include #include #include @@ -16,41 +16,6 @@ #include "Config/sys/wait.h" #include "Config/unistd.h" #include "Config/errno.h" - -/// removeFile - Delete the specified file -/// -void removeFile(const std::string &Filename) { - std::remove(Filename.c_str()); -} - -/// getUniqueFilename - Return a filename with the specified prefix. If the -/// file does not exist yet, return it, otherwise add a suffix to make it -/// unique. -/// -std::string getUniqueFilename(const std::string &FilenameBase) { - if (!std::ifstream(FilenameBase.c_str())) - return FilenameBase; // Couldn't open the file? Use it! - - // Create a pattern for mkstemp... - char *FNBuffer = new char[FilenameBase.size()+8]; - strcpy(FNBuffer, FilenameBase.c_str()); - strcpy(FNBuffer+FilenameBase.size(), "-XXXXXX"); - - // Agree on a temporary file name to use.... - int TempFD; - if ((TempFD = mkstemp(FNBuffer)) == -1) { - std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current " - << " directory!\n"; - exit(1); - } - - // We don't need to hold the temp file descriptor... we will trust that noone - // will overwrite/delete the file while we are working on it... - close(TempFD); - std::string Result(FNBuffer); - delete[] FNBuffer; - return Result; -} /// isExecutableFile - This function returns true if the filename specified /// exists and is executable. From lattner at cs.uiuc.edu Thu Aug 7 16:31:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 16:31:02 2003 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200308072130.QAA26210@apoc.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.67 -> 1.68 --- Log message: Completely remove mention of the correlated branch elimination pass. It has bugs and needs to be reworked anyway. --- Diffs of the changes: Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.67 llvm/tools/gccas/gccas.cpp:1.68 --- llvm/tools/gccas/gccas.cpp:1.67 Thu Aug 7 16:23:52 2003 +++ llvm/tools/gccas/gccas.cpp Thu Aug 7 16:30:12 2003 @@ -75,8 +75,6 @@ addPass(PM, createPromoteMemoryToRegister()); // Promote alloca's to regs addPass(PM, createIndVarSimplifyPass()); // Simplify indvars addPass(PM, createReassociatePass()); // Reassociate expressions - // Kill corr branches - //addPass(PM, createCorrelatedExpressionEliminationPass()); addPass(PM, createInstructionCombiningPass()); // Combine silly seq's addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs addPass(PM, createLICMPass()); // Hoist loop invariants From brukman at cs.uiuc.edu Thu Aug 7 16:34:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:34:02 2003 Subject: [llvm-commits] CVS: llvm/include/Support/SystemUtils.h Message-ID: <200308072133.QAA18277@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: SystemUtils.h updated: 1.2 -> 1.3 --- Log message: Remove references to `bugpoint' from the now-generic system utilities. --- Diffs of the changes: Index: llvm/include/Support/SystemUtils.h diff -u llvm/include/Support/SystemUtils.h:1.2 llvm/include/Support/SystemUtils.h:1.3 --- llvm/include/Support/SystemUtils.h:1.2 Thu Aug 7 16:28:47 2003 +++ llvm/include/Support/SystemUtils.h Thu Aug 7 16:33:32 2003 @@ -15,12 +15,13 @@ /// bool isExecutableFile(const std::string &ExeFileName); -// FindExecutable - Find a named executable, giving the argv[0] of bugpoint. -// This assumes the executable is in the same directory as bugpoint itself. -// If the executable cannot be found, return an empty string. -// +/// FindExecutable - Find a named executable, giving the argv[0] of program +/// being executed. This allows us to find another LLVM tool if it is built into +/// the same directory, but that directory is neither the current directory, nor +/// in the PATH. If the executable cannot be found, return an empty string. +/// std::string FindExecutable(const std::string &ExeName, - const std::string &BugPointPath); + const std::string &ProgramPath); /// RunProgramWithTimeout - This function executes the specified program, with /// the specified null-terminated argument array, with the stdin/out/err fd's From brukman at cs.uiuc.edu Thu Aug 7 16:34:15 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:34:15 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/SystemUtils.cpp Message-ID: <200308072133.QAA18284@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: SystemUtils.cpp updated: 1.10 -> 1.11 --- Log message: Remove references to `bugpoint' from the now-generic system utilities. --- Diffs of the changes: Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.10 llvm/lib/Support/SystemUtils.cpp:1.11 --- llvm/lib/Support/SystemUtils.cpp:1.10 Thu Aug 7 16:28:50 2003 +++ llvm/lib/Support/SystemUtils.cpp Thu Aug 7 16:33:33 2003 @@ -37,17 +37,18 @@ } -// FindExecutable - Find a named executable, giving the argv[0] of bugpoint. -// This assumes the executable is in the same directory as bugpoint itself. -// If the executable cannot be found, return an empty string. +// FindExecutable - Find a named executable, giving the argv[0] of program being +// executed. This allows us to find another LLVM tool if it is built into the +// same directory, but that directory is neither the current directory, nor in +// the PATH. If the executable cannot be found, return an empty string. // std::string FindExecutable(const std::string &ExeName, - const std::string &BugPointPath) { + const std::string &ProgramPath) { // First check the directory that bugpoint is in. We can do this if // BugPointPath contains at least one / character, indicating that it is a // relative path to bugpoint itself. // - std::string Result = BugPointPath; + std::string Result = ProgramPath; while (!Result.empty() && Result[Result.size()-1] != '/') Result.erase(Result.size()-1, 1); @@ -56,8 +57,8 @@ if (isExecutableFile(Result)) return Result; // Found it? } - // Okay, if the path to bugpoint didn't tell us anything, try using the PATH - // environment variable. + // Okay, if the path to the program didn't tell us anything, try using the + // PATH environment variable. const char *PathStr = getenv("PATH"); if (PathStr == 0) return ""; From brukman at cs.uiuc.edu Thu Aug 7 16:35:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:35:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/SystemUtils.cpp Message-ID: <200308072134.QAA18511@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: SystemUtils.cpp updated: 1.11 -> 1.12 --- Log message: Doxygen-ify the comments by using '///' instead of '//'. --- Diffs of the changes: Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.11 llvm/lib/Support/SystemUtils.cpp:1.12 --- llvm/lib/Support/SystemUtils.cpp:1.11 Thu Aug 7 16:33:33 2003 +++ llvm/lib/Support/SystemUtils.cpp Thu Aug 7 16:34:25 2003 @@ -37,11 +37,11 @@ } -// FindExecutable - Find a named executable, giving the argv[0] of program being -// executed. This allows us to find another LLVM tool if it is built into the -// same directory, but that directory is neither the current directory, nor in -// the PATH. If the executable cannot be found, return an empty string. -// +/// FindExecutable - Find a named executable, giving the argv[0] of program +/// being executed. This allows us to find another LLVM tool if it is built into +/// the same directory, but that directory is neither the current directory, nor +/// in the PATH. If the executable cannot be found, return an empty string. +/// std::string FindExecutable(const std::string &ExeName, const std::string &ProgramPath) { // First check the directory that bugpoint is in. We can do this if From brukman at cs.uiuc.edu Thu Aug 7 16:36:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:36:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200308072135.QAA18967@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.2 -> 1.3 --- Log message: close() requires "unistd.h" . --- Diffs of the changes: Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.2 llvm/lib/Support/FileUtilities.cpp:1.3 --- llvm/lib/Support/FileUtilities.cpp:1.2 Thu Aug 7 16:28:50 2003 +++ llvm/lib/Support/FileUtilities.cpp Thu Aug 7 16:35:41 2003 @@ -6,6 +6,7 @@ //===----------------------------------------------------------------------===// #include "Support/FileUtilities.h" +#include "Config/unistd.h" #include #include #include From criswell at cs.uiuc.edu Thu Aug 7 16:39:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 16:39:00 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Programs/External/SPEC/Makefile Message-ID: <200308072138.QAA07606@choi.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC: Makefile updated: 1.1 -> 1.1.8.1 --- Log message: Added the use of USE_SPEC to prevent SPEC from being used if it is not available. --- Diffs of the changes: Index: llvm/test/Programs/External/SPEC/Makefile diff -u llvm/test/Programs/External/SPEC/Makefile:1.1 llvm/test/Programs/External/SPEC/Makefile:1.1.8.1 --- llvm/test/Programs/External/SPEC/Makefile:1.1 Wed May 14 18:20:53 2003 +++ llvm/test/Programs/External/SPEC/Makefile Thu Aug 7 16:38:14 2003 @@ -1,3 +1,5 @@ LEVEL = ../../../.. +ifdef USE_SPEC DIRS := $(sort $(filter-out CVS/, $(wildcard */))) +endif include ${LEVEL}/test/Makefile.tests From brukman at cs.uiuc.edu Thu Aug 7 16:43:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 7 16:43:02 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp CodeGeneratorBug.cpp CrashDebugger.cpp Miscompilation.cpp OptimizerDriver.cpp Message-ID: <200308072142.QAA23562@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.11 -> 1.12 CodeGeneratorBug.cpp updated: 1.13 -> 1.14 CrashDebugger.cpp updated: 1.16 -> 1.17 Miscompilation.cpp updated: 1.14 -> 1.15 OptimizerDriver.cpp updated: 1.10 -> 1.11 --- Log message: File-related functions moved to FileUtilities.h . --- Diffs of the changes: Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.11 llvm/tools/bugpoint/BugDriver.cpp:1.12 --- llvm/tools/bugpoint/BugDriver.cpp:1.11 Thu Aug 7 16:19:30 2003 +++ llvm/tools/bugpoint/BugDriver.cpp Thu Aug 7 16:42:28 2003 @@ -13,7 +13,7 @@ #include "llvm/Bytecode/Reader.h" #include "llvm/Transforms/Utils/Linker.h" #include "Support/CommandLine.h" -#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include // Anonymous namespace to define command line options for debugging. Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.13 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.14 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.13 Thu Aug 7 16:19:30 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Thu Aug 7 16:42:28 2003 @@ -22,7 +22,7 @@ #include "Support/CommandLine.h" #include "Support/Debug.h" #include "Support/StringExtras.h" -#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include #include Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.16 llvm/tools/bugpoint/CrashDebugger.cpp:1.17 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.16 Thu Aug 7 16:19:30 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Thu Aug 7 16:42:28 2003 @@ -18,7 +18,7 @@ #include "llvm/Support/CFG.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include #include Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.14 llvm/tools/bugpoint/Miscompilation.cpp:1.15 --- llvm/tools/bugpoint/Miscompilation.cpp:1.14 Thu Aug 7 16:19:30 2003 +++ llvm/tools/bugpoint/Miscompilation.cpp Thu Aug 7 16:42:28 2003 @@ -10,7 +10,7 @@ #include "llvm/Pass.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Linker.h" -#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" class ReduceMiscompilingPasses : public ListReducer { BugDriver &BD; Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.10 llvm/tools/bugpoint/OptimizerDriver.cpp:1.11 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.10 Thu Aug 7 16:19:30 2003 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Thu Aug 7 16:42:28 2003 @@ -13,7 +13,7 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/Target/TargetData.h" -#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include #include #include From lattner at cs.uiuc.edu Thu Aug 7 16:47:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 16:47:02 2003 Subject: [llvm-commits] CVS: llvm/www/docs/CodingStandards.html Message-ID: <200308072145.QAA05365@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: CodingStandards.html updated: 1.8 -> 1.9 --- Log message: * Fix <>'s in code to be <>'s * Add section describing how we prefer #includes to be ordered --- Diffs of the changes: Index: llvm/www/docs/CodingStandards.html diff -u llvm/www/docs/CodingStandards.html:1.8 llvm/www/docs/CodingStandards.html:1.9 --- llvm/www/docs/CodingStandards.html:1.8 Mon Jul 28 16:57:18 2003 +++ llvm/www/docs/CodingStandards.html Thu Aug 7 16:45:47 2003 @@ -14,6 +14,7 @@
      1. Commenting
      2. Comment Formatting +
      3. #include Style
      4. Source Code Width
      5. Use Spaces Instead of Tabs
      6. Indent Code Consistently @@ -123,6 +124,39 @@ To comment out a large block of code, use #if 0 and #endif. These nest properly and are better behaved in general than C style comments.

        + +


    #include Style


    Source Code Width

      @@ -253,12 +287,6 @@ functions, classes or data structures, but the important issue is how they work together.

      - - In general, a module should be implemented with one or more .cpp files. Each of these .cpp files should include the header that defines their interface first. This ensure that all of the dependences of the module header @@ -450,13 +478,13 @@ you actually implement it. Typically it looks something like this (I'll start with the const-iterator-only situation): - #include + #include <iterator> class container { public: typedef something_or_other value_type; class const_iterator: - public std::iterator { + public std::iterator<std::forward_iterator_tag, value_type> { friend class container; public: const value_type& operator*() const; @@ -568,7 +596,7 @@ typedef something_or_other value_type; class const_iterator; class iterator: - public std::iterator { + public std::iterator<std::forward_iterator_tag, value_type> { friend class container; friend class container::const_iterator; public: @@ -582,7 +610,7 @@ //... }; class const_iterator: - public std::iterator { + public std::iterator<std::forward_iterator_tag, value_type> { friend class container; public: const_iterator(); @@ -615,7 +643,7 @@ iterators: class iterator: - public std::iterator { + public std::iterator<std::bidirectional_iterator_tag, value_type> { public: //... iterator& operator--(); @@ -629,7 +657,7 @@ Random access iterators add several more member and friend functions: class iterator: - public std::iterator { + public std::iterator<std::random_access_iterator_tag, value_type> { public: //... iterator& operator+=(difference_type rhs); @@ -638,10 +666,10 @@ friend iterator operator+(difference_type lhs, iterator rhs); friend iterator operator-(iterator lhs, difference_type rhs); friend difference_type operator-(iterator lhs, iterator rhs); - friend bool operator<(iterator lhs, iterator rhs); - friend bool operator>(iterator lhs, iterator rhs); - friend bool operator<=(iterator lhs, iterator rhs); - friend bool operator>=(iterator lhs, iterator rhs); + friend bool operator<(iterator lhs, iterator rhs); + friend bool operator>(iterator lhs, iterator rhs); + friend bool operator<=(iterator lhs, iterator rhs); + friend bool operator>=(iterator lhs, iterator rhs); //... }; @@ -677,24 +705,24 @@ // calculate distance between iterators } - bool operator<(container::iterator lhs, container::iterator rhs) { + bool operator<(container::iterator lhs, container::iterator rhs) { // perform less-than comparison } - bool operator>(container::iterator lhs, container::iterator rhs) { - return rhs < lhs; + bool operator>(container::iterator lhs, container::iterator rhs) { + return rhs < lhs; } - bool operator<=(container::iterator lhs, container::iterator rhs) { - return !(rhs < lhs); + bool operator<=(container::iterator lhs, container::iterator rhs) { + return !(rhs < lhs); } - bool operator>=(container::iterator lhs, container::iterator rhs) { - return !(lhs < rhs); + bool operator>=(container::iterator lhs, container::iterator rhs) { + return !(lhs < rhs); } Four of the functions (operator+=(), operator-=(), the second -operator-(), and operator<()) are nontrivial; the rest are +operator-(), and operator<()) are nontrivial; the rest are boilerplate. One feature of the above code that some experts may disapprove of is @@ -712,7 +740,7 @@ STL-like containers and iterators. -- -Ross Smith The Internet Group, Auckland, New Zealand +Ross Smith <ross.s at ihug.co.nz> The Internet Group, Auckland, New Zealand

  • @@ -741,7 +769,7 @@
    Chris Lattner
    -Last modified: Fri Jul 25 12:29:52 CDT 2003 +Last modified: Thu Aug 7 16:44:33 CDT 2003 From criswell at cs.uiuc.edu Thu Aug 7 17:39:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 7 17:39:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/README Message-ID: <200308072238.RAA07762@choi.cs.uiuc.edu> Changes in directory llvm: README added (r1.1.2.1) --- Log message: New README file for LLVM Pre-Release. It contains a list of bug fixes and the general spiel we send to people when we email them download information. --- Diffs of the changes: Index: llvm/README diff -c /dev/null llvm/README:1.1.2.1 *** /dev/null Thu Aug 7 17:38:55 2003 --- llvm/README Thu Aug 7 17:38:45 2003 *************** *** 0 **** --- 1,40 ---- + Welcome to the Pre-Release 1.1 of LLVM! + + LICENSE: + ======== + Before using LLVM, you should read the pre-release license in LICENSE.TXT. + + BUILDING: + ========= + To build LLVM, please consult the "Getting Started" guide on the LLVM web site + at http://llvm.cs.uiuc.edu/docs/GettingStarted.html. + + CHANGES: + ======== + o The Sparc JIT is now much more stable. + o The x86 JIT performs faster. + o Bugpoint is now able to debug JIT code. + o Numerous bug fixes have been made to Sparc LLC. + o The Sparc C front-end has been fixed so that it does not fail on an + assertion. + o A segmentation fault in gccld was fixed. + o An infinite loop in the tail recursion optimization was fixed. + o The libtool program has been updated. This fixes several bugs with + building dynamic libraries. + o The JIT is enabled by default on Sparc and x86. + o The configure script attempts to set OBJ_ROOT to /localhome/$USER. + o The --enable-spec/--disable-spec configure options should work. + o The Pool Allocator (which is still experimental and under development) + does not generate incorrect code. + + BUGS: + ===== + Please see our website for information on how to report bugs + (http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html). + + LLVM DEVELOPER'S MAILING LIST + ============================= + The LLVM Developer's Mailing List provides announcements and general discussion + about LLVM. The list is low volume. You can subscribe to it at + http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev. + From lattner at cs.uiuc.edu Thu Aug 7 18:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 18:16:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenWrappers.cpp CodeGenWrappers.h Message-ID: <200308072315.SAA31790@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenWrappers.cpp updated: 1.1 -> 1.2 CodeGenWrappers.h updated: 1.2 -> 1.3 --- Log message: Add new method to get a value type as a string --- Diffs of the changes: Index: llvm/utils/TableGen/CodeGenWrappers.cpp diff -u llvm/utils/TableGen/CodeGenWrappers.cpp:1.1 llvm/utils/TableGen/CodeGenWrappers.cpp:1.2 --- llvm/utils/TableGen/CodeGenWrappers.cpp:1.1 Thu Aug 7 00:38:11 2003 +++ llvm/utils/TableGen/CodeGenWrappers.cpp Thu Aug 7 18:15:21 2003 @@ -16,22 +16,27 @@ return (MVT::ValueType)Rec->getValueAsInt("Value"); } -std::ostream &operator<<(std::ostream &OS, MVT::ValueType T) { +std::string getName(MVT::ValueType T) { switch (T) { - case MVT::Other: return OS << "UNKNOWN"; - case MVT::i1: return OS << "i1"; - case MVT::i8: return OS << "i8"; - case MVT::i16: return OS << "i16"; - case MVT::i32: return OS << "i32"; - case MVT::i64: return OS << "i64"; - case MVT::i128: return OS << "i128"; - case MVT::f32: return OS << "f32"; - case MVT::f64: return OS << "f64"; - case MVT::f80: return OS << "f80"; - case MVT::f128: return OS << "f128"; - case MVT::isVoid:return OS << "void"; + case MVT::Other: return "UNKNOWN"; + case MVT::i1: return "i1"; + case MVT::i8: return "i8"; + case MVT::i16: return "i16"; + case MVT::i32: return "i32"; + case MVT::i64: return "i64"; + case MVT::i128: return "i128"; + case MVT::f32: return "f32"; + case MVT::f64: return "f64"; + case MVT::f80: return "f80"; + case MVT::f128: return "f128"; + case MVT::isVoid:return "void"; + default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; } - return OS; +} + + +std::ostream &operator<<(std::ostream &OS, MVT::ValueType T) { + return OS << getName(T); } Index: llvm/utils/TableGen/CodeGenWrappers.h diff -u llvm/utils/TableGen/CodeGenWrappers.h:1.2 llvm/utils/TableGen/CodeGenWrappers.h:1.3 --- llvm/utils/TableGen/CodeGenWrappers.h:1.2 Thu Aug 7 01:01:44 2003 +++ llvm/utils/TableGen/CodeGenWrappers.h Thu Aug 7 18:15:21 2003 @@ -21,7 +21,7 @@ MVT::ValueType getValueType(Record *Rec); std::ostream &operator<<(std::ostream &OS, MVT::ValueType T); - +std::string getName(MVT::ValueType T); /// CodeGenTarget - This class corresponds to the Target class in the .td files. From lattner at cs.uiuc.edu Thu Aug 7 18:17:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 7 18:17:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308072316.SAA32080@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.12 -> 1.13 InstrSelectorEmitter.h updated: 1.9 -> 1.10 --- Log message: Finish implementation of nonterminal instantiation. Tree patterns are now, finally, ready to use! --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.12 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.13 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.12 Thu Aug 7 16:02:56 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Thu Aug 7 18:16:20 2003 @@ -38,6 +38,49 @@ throw "Type inferfence contradiction found for pattern " + RecName; } +/// InstantiateNonterminals - If this pattern refers to any nonterminals which +/// are not themselves completely resolved, clone the nonterminal and resolve it +/// with the using context we provide. +/// +void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) { + if (!isLeaf()) { + for (unsigned i = 0, e = Children.size(); i != e; ++i) + Children[i]->InstantiateNonterminals(ISE); + return; + } + + // If this is a leaf, it might be a reference to a nonterminal! Check now. + if (DefInit *DI = dynamic_cast(getValue())) + if (DI->getDef()->isSubClassOf("Nonterminal")) { + Pattern *NT = ISE.getPattern(DI->getDef()); + if (!NT->isResolved()) { + // We found an unresolved nonterminal reference. Ask the ISE to clone + // it for us, then update our reference to the fresh, new, resolved, + // nonterminal. + + Value = new DefInit(ISE.InstantiateNonterminal(NT, getType())); + } + } +} + + +/// clone - Make a copy of this tree and all of its children. +/// +TreePatternNode *TreePatternNode::clone() const { + TreePatternNode *New; + if (isLeaf()) { + New = new TreePatternNode(Value); + } else { + std::vector CChildren(Children.size()); + for (unsigned i = 0, e = Children.size(); i != e; ++i) + CChildren[i] = Children[i]->clone(); + New = new TreePatternNode(Operator, CChildren); + } + New->setType(Type); + return New; +} + + std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) { if (N.isLeaf()) return OS << N.getType() << ":" << *N.getValue(); @@ -67,16 +110,13 @@ // First, parse the pattern... Tree = ParseTreePattern(RawPat); - - bool MadeChange, AnyUnset; - do { - MadeChange = false; - AnyUnset = InferTypes(Tree, MadeChange); - } while ((AnyUnset || MadeChange) && !(AnyUnset && !MadeChange)); + + // Run the type-inference engine... + InferAllTypes(); if (PTy == Instruction || PTy == Expander) { // Check to make sure there is not any unset types in the tree pattern... - if (AnyUnset) { + if (!isResolved()) { std::cerr << "In pattern: " << *Tree << "\n"; error("Could not infer all types!"); } @@ -92,13 +132,12 @@ Result = RegInit->getDef(); Tree = Tree->getChild(1); - } } - - Resolved = !AnyUnset; } + + void Pattern::error(const std::string &Msg) const { std::string M = "In "; switch (PTy) { @@ -175,6 +214,15 @@ return new TreePatternNode(Operator, Children); } +void Pattern::InferAllTypes() { + bool MadeChange, AnyUnset; + do { + MadeChange = false; + AnyUnset = InferTypes(Tree, MadeChange); + } while ((AnyUnset || MadeChange) && !(AnyUnset && !MadeChange)); + Resolved = !AnyUnset; +} + // InferTypes - Perform type inference on the tree, returning true if there // are any remaining untyped nodes and setting MadeChange if any changes were @@ -240,15 +288,16 @@ return AnyUnset | N->getType() == MVT::Other; } -/// InstantiateNonterminalsReferenced - If this pattern refers to any -/// nonterminals which are not themselves completely resolved, clone the -/// nonterminal and resolve it with the using context we provide. +/// clone - This method is used to make an exact copy of the current pattern, +/// then change the "TheRecord" instance variable to the specified record. /// -void Pattern::InstantiateNonterminalsReferenced() { - +Pattern *Pattern::clone(Record *R) const { + assert(PTy == Nonterminal && "Can only clone nonterminals"); + return new Pattern(Tree->clone(), R, Resolved, ISE); } + std::ostream &operator<<(std::ostream &OS, const Pattern &P) { switch (P.getPatternType()) { case Pattern::Nonterminal: OS << "Nonterminal pattern "; break; @@ -362,10 +411,50 @@ // information from the context that they are used in. // void InstrSelectorEmitter::InstantiateNonterminals() { + DEBUG(std::cerr << "Instantiating nonterminals:\n"); for (std::map::iterator I = Patterns.begin(), E = Patterns.end(); I != E; ++I) if (I->second->isResolved()) - I->second->InstantiateNonterminalsReferenced(); + I->second->InstantiateNonterminals(); +} + +/// InstantiateNonterminal - This method takes the nonterminal specified by +/// NT, which should not be completely resolved, clones it, applies ResultTy +/// to its root, then runs the type inference stuff on it. This should +/// produce a newly resolved nonterminal, which we make a record for and +/// return. To be extra fancy and efficient, this only makes one clone for +/// each type it is instantiated with. +Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT, + MVT::ValueType ResultTy) { + assert(!NT->isResolved() && "Nonterminal is already resolved!"); + + // Check to see if we have already instantiated this pair... + Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)]; + if (Slot) return Slot; + + DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName() + << "' for type '" << getName(ResultTy) << "'\n"); + + Record *New = new Record(NT->getRecord()->getName()+"_"+getName(ResultTy)); + + // Copy the pattern... + Pattern *NewPat = NT->clone(New); + + // Apply the type to the root... + NewPat->getTree()->updateNodeType(ResultTy, New->getName()); + + // Infer types... + NewPat->InferAllTypes(); + + // Make sure everything is good to go now... + if (!NewPat->isResolved()) + NewPat->error("Instantiating nonterminal did not resolve all types!"); + + // Add the pattern to the patterns map, add the record to the RecordKeeper, + // return the new record. + Patterns[New] = NewPat; + Records.addDef(New); + return Slot = New; } @@ -381,4 +470,11 @@ // Instantiate any unresolved nonterminals with information from the context // that they are used in. InstantiateNonterminals(); + + + std::cerr << "Patterns aquired:\n"; + for (std::map::iterator I = Patterns.begin(), + E = Patterns.end(); I != E; ++I) + if (I->second->isResolved()) + std::cerr << " " << *I->second << "\n"; } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.9 llvm/utils/TableGen/InstrSelectorEmitter.h:1.10 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.9 Thu Aug 7 16:02:56 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Thu Aug 7 18:16:20 2003 @@ -87,8 +87,16 @@ return Value; } + /// clone - Make a copy of this tree and all of its children. + /// + TreePatternNode *clone() const; + void dump() const; + /// InstantiateNonterminals - If this pattern refers to any nonterminals which + /// are not themselves completely resolved, clone the nonterminal and resolve + /// it with the using context we provide. + void InstantiateNonterminals(InstrSelectorEmitter &ISE); // UpdateNodeType - Set the node type of N to VT if VT contains information. // If N already contains a conflicting type, then throw an exception. This @@ -145,6 +153,11 @@ Pattern(PatternType pty, DagInit *RawPat, Record *TheRec, InstrSelectorEmitter &ise); + /// Pattern - Constructor used for cloning nonterminal patterns + Pattern(TreePatternNode *tree, Record *rec, bool res, + InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0), + TheRecord(rec), Resolved(res), ISE(ise){} + /// getPatternType - Return what flavor of Record this pattern originated from /// PatternType getPatternType() const { return PTy; } @@ -162,15 +175,30 @@ bool isResolved() const { return Resolved; } - /// InstantiateNonterminalsReferenced - If this pattern refers to any - /// nonterminals which are not themselves completely resolved, clone the - /// nonterminal and resolve it with the using context we provide. - void InstantiateNonterminalsReferenced(); + /// InferAllTypes - Runs the type inference engine on the current pattern, + /// stopping when nothing can be inferred, then updating the Resolved field. + void InferAllTypes(); + + /// InstantiateNonterminals - If this pattern refers to any nonterminals which + /// are not themselves completely resolved, clone the nonterminal and resolve + /// it with the using context we provide. + void InstantiateNonterminals() { + Tree->InstantiateNonterminals(ISE); + } + + /// clone - This method is used to make an exact copy of the current pattern, + /// then change the "TheRecord" instance variable to the specified record. + /// + Pattern *clone(Record *R) const; + + /// error - Throw an exception, prefixing it with information about this + /// pattern. + void error(const std::string &Msg) const; + private: MVT::ValueType getIntrinsicType(Record *R) const; TreePatternNode *ParseTreePattern(DagInit *DI); bool InferTypes(TreePatternNode *N, bool &MadeChange); - void error(const std::string &Msg) const; }; std::ostream &operator<<(std::ostream &OS, const Pattern &P); @@ -189,6 +217,11 @@ /// Patterns - a list of all of the patterns defined by the target description /// std::map Patterns; + + /// InstantiatedNTs - A data structure to keep track of which nonterminals + /// have been instantiated already... + /// + std::map, Record*> InstantiatedNTs; public: InstrSelectorEmitter(RecordKeeper &R) : Records(R) {} @@ -208,6 +241,14 @@ /// ReadNonterminal - This method parses the specified record as a /// nonterminal, but only if it hasn't been read in already. Pattern *ReadNonterminal(Record *R); + + /// InstantiateNonterminal - This method takes the nonterminal specified by + /// NT, which should not be completely resolved, clones it, applies ResultTy + /// to its root, then runs the type inference stuff on it. This should + /// produce a newly resolved nonterminal, which we make a record for and + /// return. To be extra fancy and efficient, this only makes one clone for + /// each type it is instantiated with. + Record *InstantiateNonterminal(Pattern *NT, MVT::ValueType ResultTy); private: // ReadNodeTypes - Read in all of the node types in the current RecordKeeper, From gaeke at cs.uiuc.edu Thu Aug 7 22:53:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 22:53:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h SecondTrigger.cpp Message-ID: <200308080352.WAA16297@neo.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: GetTimer.h updated: 1.3 -> 1.4 SecondTrigger.cpp updated: 1.8 -> 1.9 --- Log message: FOR_DEBUG merged with GET_ALL_INFO. triggerBB renamed to optimizeTrace. Print out trace in this method if GET_ALL_INFO is on. Get rid of no-op XORs with zero of fprs_reg and ccr_reg. Rewrite doTrigger into two smaller methods: getSuccessorByPath and constructVBB. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.3 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.4 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.3 Tue Aug 5 15:00:18 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h Thu Aug 7 22:51:58 2003 @@ -7,9 +7,14 @@ #ifndef GETTIMER_H #define GETTIMER_H +// When this is defined, the reoptimizer prints out lots of debugging +// information. (We can't easily pass arguments such as -debug to the +// reoptimizer as with other LLVM tools, so we use this for now.) #define GET_ALL_INFO + // #undef GET_COVERAGE -// #undef FOR_DEBUG + +// Tunable parameters (see thesis?) #define MAX_PATH_HISTORIES 12 #define MAX_ALLOWED_PATHS 6 #define THRESHOLD_PERCENTAGE 90 Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.8 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.9 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.8 Thu Aug 7 13:11:44 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Thu Aug 7 22:51:58 2003 @@ -66,8 +66,17 @@ /// the trace; the second parameter is presumably one of the starting /// addresses for the trace. /// -void triggerBB(vector &vBB, uint64_t a) { - std::cerr << "We made it to triggerBB\n"; +void optimizeTrace (vector &vBB, uint64_t a) { +#ifdef GET_ALL_INFO + // Dump the trace to the standard error stream. + std::cerr << "=== In optimizeTrace; a = " << a << "================\n"; + std::cerr << "--- Function where the trace starts -----------------\n"; + std::cerr << vBB[0]->getParent(); + std::cerr << "--- BasicBlocks in the trace ------------------------\n"; + for (unsigned i = 0; i < vBB.size(); ++i) + std::cerr << *vBB[i]; + std::cerr << "=====================================================\n"; +#endif // GET_ALL_INFO } extern "C" void llvm_time_start(){ @@ -141,9 +150,6 @@ firstTriggerAddr[reverseAddr]); } - fprs_reg ^= 0; - ccr_reg ^= 0; - // Restore registers from local variables. LOAD_CCR_REG(ccr_reg); LOAD_I_REGS(i_reg_save); @@ -376,9 +382,6 @@ pathCounter[pcAddr] = newMap; } - fprs_reg ^= 0; - ccr_reg ^= 0; - LOAD_CCR_REG(ccr_reg); LOAD_I_REGS(i_reg_save); LOAD_G1_REG(g1_reg); @@ -459,58 +462,57 @@ std::cerr<<"\n"; } -#if 0 -void doTrigger(unsigned int path, uint64_t start, - uint64_t firstLevelTraceStartAddr){ - vector vBB; - BasicBlock *startBB, *bb; - - //std::cerr<<"FINAL TRACE ---------------------------------\n"; - - assert(getReverseBBMap(start, M, startBB) && "No BB found"); +/// Given a BranchInst BRANCH and a PATH that starts at the basic +/// block ending with BRANCH, return the successor basic block of +/// BRANCH which is on the trace. As a side effect, modifies PATH +/// so that it starts at the returned basic block. +/// +BasicBlock *getSuccessorByPath (BranchInst &branch, unsigned &path) +{ + BasicBlock *bb; - vBB.push_back(startBB); - //std::cerr<getTerminator(); - BranchInst *BI = dyn_cast(TI); - assert(BI && "Must be a branch!"); - - if(BI->isConditional()){ - if(path & 1) - bb = BI->getSuccessor(0); + if (branch.isConditional ()) { + // If the branch is conditional, it corresponds to a bit in PATH. + if (path & 1) + bb = branch.getSuccessor (0); else - bb = BI->getSuccessor(1); - path = path >> 1; - } - else - bb = BI->getSuccessor(0); - - while(bb != startBB){ - vBB.push_back(bb); - //std::cerr<getTerminator(); - BI = dyn_cast(TI); - assert(BI && "Must be a branch!"); - - if(BI->isConditional()){ - if(path & 1) - bb = BI->getSuccessor(0); - else - bb = BI->getSuccessor(1); + bb = branch.getSuccessor (1); + // Now we're done with this bit of PATH, so shift it off the end. + path >>= 1; + } else { + // Unconditional branches do not correspond to a PATH bit. + bb = branch.getSuccessor (0); + } + return bb; +} - path = path >> 1; - } - else{ - bb = BI->getSuccessor(0); +/// Given a path PATH starting in the basic block whose machine +/// address is START, construct in VBB a vector of LLVM BasicBlocks +/// that represents the trace. +/// +void constructVBB (unsigned int path, uint64_t start, vector&vBB){ + BasicBlock *bb; + BasicBlock *startBB; + // Get the first basic block by querying the mapping information. + assert (getReverseBBMap (start, M, startBB) && + "Couldn't find starting BasicBlock for trace start addr"); + bb = startBB; + do { + // Add basic block to trace. + vBB.push_back(bb); + // Try to find the next basic block. FIXME: Currently we're + // limited to looking for a terminating branch and following that + // branch according to the path. This dies if there is a basic + // block in the trace which ends in a `ret'. + TerminatorInst *TI = bb->getTerminator(); + BranchInst *BI = dyn_cast(TI); + if (!BI) { + std::cerr << "Offending instruction: " << *TI << "\n"; + assert(0 && "Terminator instruction of BB must be a branch"); } - } - - triggerBB(vBB, firstLevelTraceStartAddr); -} -#endif - + bb = getSuccessorByPath (*BI, path); + } while (bb != vBB[0]); +} //Create traces, stich them together, and add them to tracecache void generateTraces(uint64_t start, uint64_t end, @@ -527,8 +529,7 @@ return; } - -#ifdef FOR_DEBUG +#ifdef GET_ALL_INFO std::cerr<<"Start: "<<(void *)start<<"\t End: "<<(void *)end<<"\n"; std::cerr<<"Paths------\n"; for(std::vector::iterator VI = paths.begin(), VE = paths.end(); @@ -555,10 +556,12 @@ getPathIntersections(pathIntersections, paths); //use path 0 to form vBB - //doTrigger(paths[0], start, firstLevelTraceStartAddr); + //vector vBB; + //constructVBB (path, start, vBB); + //optimizeTrace (vBB, firstLevelTraceStartAddr); //return; -#ifdef FOR_DEBUG +#ifdef GET_ALL_INFO std::cerr<<"Path Intersections------\n"; for(std::map >::iterator MI = pathIntersections.begin(), ME = pathIntersections.end(); MI != ME; @@ -630,7 +633,7 @@ seenStartPC = true; sawUnconditional = false; -#ifdef FOR_DEBUG +#ifdef GET_ALL_INFO std::cerr<<"PC:\t"<<(void *)pc<<"\n"; #endif @@ -793,7 +796,7 @@ //is it taken? if(firstPath & (1ULL << pathIndex)){ -#ifdef FOR_DEBUG +#ifdef GET_ALL_INFO std::cerr<<" taken \t"; #endif From gaeke at cs.uiuc.edu Thu Aug 7 22:57:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 22:57:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp Message-ID: <200308080356.WAA13153@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: FirstTrigger.cpp updated: 1.9 -> 1.10 --- Log message: Remove no-op XORs with zero of fprs_reg, ccr_reg. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.9 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.10 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.9 Wed Aug 6 16:52:04 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp Thu Aug 7 22:56:07 2003 @@ -152,10 +152,6 @@ doFlush(pcAddr-8, pcAddr+16); } - // FIXME: Why are these here? - fprs_reg ^= 0; - ccr_reg ^= 0; - // Restore registers from local variables, and return to executing code. LOAD_CCR_REG(ccr_reg); LOAD_I_REGS(i_reg_save); From gaeke at cs.uiuc.edu Thu Aug 7 23:06:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 23:06:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Message-ID: <200308080405.XAA13485@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: SecondTrigger.cpp updated: 1.9 -> 1.10 --- Log message: Move forward decl up to top where the others are. Squash extra whitespace. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.9 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.10 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.9 Thu Aug 7 22:51:58 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Thu Aug 7 23:05:43 2003 @@ -56,6 +56,10 @@ uint64_t firstLevelTraceStartAddr); void getReturnCode(vector &traces, int &index, uint64_t ret); +void getBranchExitCode(std::vector &instVec, + std::map &branchMap, + std::map &targetMap, + std::map &callMap); std::map exitCounter; std::map firstTriggerAddr; //tracestart addr @@ -392,11 +396,6 @@ LOAD_FSR_REG(fsr_reg); } -void getBranchExitCode(std::vector &instVec, - std::map &branchMap, - std::map &targetMap, - std::map &callMap); - /// Find first set bit in the 64-bit number n. This should probably be /// reworked to use libc's ffs(3), but note that the return values are /// off by one and ffs() takes 32-bit ints. @@ -1003,6 +1002,3 @@ index += 6; } - - - From gaeke at cs.uiuc.edu Thu Aug 7 23:14:00 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 7 23:14:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h Message-ID: <200308080413.XAA13514@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: GetTimer.h updated: 1.4 -> 1.5 --- Log message: Just marking my FIXMEs more clearly, nothing to see here, move along citizen... --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.4 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.5 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h:1.4 Thu Aug 7 22:51:58 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/GetTimer.h Thu Aug 7 23:13:23 2003 @@ -12,9 +12,11 @@ // reoptimizer as with other LLVM tools, so we use this for now.) #define GET_ALL_INFO +// FIXME: What does this do? // #undef GET_COVERAGE -// Tunable parameters (see thesis?) +// Tunable parameters +// FIXME: What do they do? (see thesis?) #define MAX_PATH_HISTORIES 12 #define MAX_ALLOWED_PATHS 6 #define THRESHOLD_PERCENTAGE 90 From criswell at cs.uiuc.edu Fri Aug 8 08:57:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 08:57:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200308081356.IAA14704@choi.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp (r1.15) removed --- Log message: Removing Pool Allocation from this branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Fri Aug 8 08:58:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 08:58:00 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/include/llvm/Transforms/PoolAllocate.h Message-ID: <200308081357.IAA14726@choi.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: PoolAllocate.h (r1.6) removed --- Log message: Removing Pool Allocation from this branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Fri Aug 8 09:00:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 09:00:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Transforms/IPO/OldPoolAllocate.cpp Message-ID: <200308081359.IAA14757@choi.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: OldPoolAllocate.cpp (r1.45) removed --- Log message: Removing pool allocation from this branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Fri Aug 8 09:01:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 09:01:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Libraries/libpoolalloc/Makefile PoolAllocatorChained.c Message-ID: <200308081400.JAA14805@choi.cs.uiuc.edu> Changes in directory llvm/test/Libraries/libpoolalloc: Makefile (r1.1) removed PoolAllocatorChained.c (r1.3) removed --- Log message: Removing pool allocation from this branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Fri Aug 8 09:01:14 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 09:01:14 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/test/Programs/TEST.poolalloc.Makefile Message-ID: <200308081400.JAA14782@choi.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.poolalloc.Makefile (r1.3) removed --- Log message: Removing pool allocation from this branch. --- Diffs of the changes: From criswell at cs.uiuc.edu Fri Aug 8 09:07:03 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 09:07:03 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/lib/Support/SystemUtils.cpp Message-ID: <200308081406.JAA27068@choi.cs.uiuc.edu> Changes in directory llvm/lib/Support: SystemUtils.cpp updated: 1.9 -> 1.9.2.1 --- Log message: Fixed the SystemUtils.h include. --- Diffs of the changes: Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.9 llvm/lib/Support/SystemUtils.cpp:1.9.2.1 --- llvm/lib/Support/SystemUtils.cpp:1.9 Fri Aug 1 15:29:18 2003 +++ llvm/lib/Support/SystemUtils.cpp Fri Aug 8 09:06:31 2003 @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -#include "SystemUtils.h" +#include "Support/SystemUtils.h" #include #include #include From criswell at cs.uiuc.edu Fri Aug 8 09:34:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 09:34:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/README Message-ID: <200308081433.JAA05095@choi.cs.uiuc.edu> Changes in directory llvm: README updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Removed the note on the Pool Allocator. --- Diffs of the changes: Index: llvm/README diff -u llvm/README:1.1.2.1 llvm/README:1.1.2.2 --- llvm/README:1.1.2.1 Thu Aug 7 17:38:45 2003 +++ llvm/README Fri Aug 8 09:33:16 2003 @@ -24,8 +24,6 @@ o The JIT is enabled by default on Sparc and x86. o The configure script attempts to set OBJ_ROOT to /localhome/$USER. o The --enable-spec/--disable-spec configure options should work. - o The Pool Allocator (which is still experimental and under development) - does not generate incorrect code. BUGS: ===== From criswell at cs.uiuc.edu Fri Aug 8 10:32:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 10:32:02 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/tools/bugpoint/SystemUtils.cpp SystemUtils.h Message-ID: <200308081531.KAA07919@choi.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: SystemUtils.cpp (r1.9) removed SystemUtils.h (r1.1) removed --- Log message: Removed this ala the main CVS tree. Somehow these changes sneaked into my branch. --- Diffs of the changes: From brukman at cs.uiuc.edu Fri Aug 8 10:38:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 8 10:38:01 2003 Subject: [llvm-commits] CVS: llvm/tools/dis/Makefile Message-ID: <200308081537.KAA02522@zion.cs.uiuc.edu> Changes in directory llvm/tools/dis: Makefile updated: 1.9 -> 1.10 --- Log message: Chomped spurious blank lines. --- Diffs of the changes: Index: llvm/tools/dis/Makefile diff -u llvm/tools/dis/Makefile:1.9 llvm/tools/dis/Makefile:1.10 --- llvm/tools/dis/Makefile:1.9 Fri Aug 30 19:29:36 2002 +++ llvm/tools/dis/Makefile Fri Aug 8 10:37:35 2003 @@ -3,5 +3,3 @@ TOOLNAME = dis USEDLIBS = bcreader cwriter ipa.a vmcore support.a include $(LEVEL)/Makefile.common - - From criswell at cs.uiuc.edu Fri Aug 8 10:58:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 10:58:02 2003 Subject: [llvm-commits] [1.3.1] CVS: llvm/include/Support/SystemUtils.h Message-ID: <200308081557.KAA16075@choi.cs.uiuc.edu> Changes in directory llvm/include/Support: SystemUtils.h updated: 1.3 -> 1.3.1.1 --- Log message: Addeding SystemUtils.h into the pre-release 1.1 branch. --- Diffs of the changes: From lattner at cs.uiuc.edu Fri Aug 8 11:31:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 8 11:31:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308081630.LAA09359@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.13 -> 1.14 InstrSelectorEmitter.h updated: 1.10 -> 1.11 --- Log message: Emit the first half of the instruction selector. --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.13 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.14 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.13 Thu Aug 7 18:16:20 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Fri Aug 8 11:30:10 2003 @@ -318,6 +318,41 @@ //===----------------------------------------------------------------------===// +// PatternOrganizer implementation +// + +/// addPattern - Add the specified pattern to the appropriate location in the +/// collection. +void PatternOrganizer::addPattern(Pattern *P) { + std::string ValueName; + if (P->getPatternType() == Pattern::Nonterminal) { + // Just use the nonterminal name, which will already include the type if + // it has been cloned. + ValueName = P->getRecord()->getName(); + } else { + if (P->getResult()) + ValueName += P->getResult()->getName()+"_"; + else + ValueName += "Void_"; + ValueName += getName(P->getTree()->getType()); + } + + NodesForSlot &Nodes = AllPatterns[ValueName]; + if (!P->getTree()->isLeaf()) + Nodes[P->getTree()->getOperator()].push_back(P); + else { + // Right now we only support DefInit's with node types... + DefInit *Val = dynamic_cast(P->getTree()->getValue()); + if (!Val) + throw std::string("We only support def inits in PatternOrganizer" + "::addPattern so far!"); + Nodes[Val->getDef()].push_back(P); + } +} + + + +//===----------------------------------------------------------------------===// // InstrSelectorEmitter implementation // @@ -432,11 +467,12 @@ Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)]; if (Slot) return Slot; - DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName() - << "' for type '" << getName(ResultTy) << "'\n"); - Record *New = new Record(NT->getRecord()->getName()+"_"+getName(ResultTy)); + DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName() + << "' for type '" << getName(ResultTy) << "', producing '" + << New->getName() << "'\n"); + // Copy the pattern... Pattern *NewPat = NT->clone(New); @@ -457,6 +493,15 @@ return Slot = New; } +// CalculateComputableValues - Fill in the ComputableValues map through +// analysis of the patterns we are playing with. +void InstrSelectorEmitter::CalculateComputableValues() { + // Loop over all of the patterns, adding them to the ComputableValues map + for (std::map::iterator I = Patterns.begin(), + E = Patterns.end(); I != E; ++I) + if (I->second->isResolved()) + ComputableValues.addPattern(I->second); +} void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. @@ -471,10 +516,103 @@ // that they are used in. InstantiateNonterminals(); + // Clear InstantiatedNTs, we don't need it anymore... + InstantiatedNTs.clear(); std::cerr << "Patterns aquired:\n"; for (std::map::iterator I = Patterns.begin(), E = Patterns.end(); I != E; ++I) if (I->second->isResolved()) std::cerr << " " << *I->second << "\n"; + + CalculateComputableValues(); + + // Output the slot number enums... + OS << "\n\nenum { // Slot numbers...\n" + << " LastBuiltinSlot = ISD::NumBuiltinSlots-1, // Start numbering here\n"; + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) + OS << " " << I->first << "_Slot,\n"; + OS << " NumSlots\n};\n\n// Reduction value typedefs...\n"; + + // Output the reduction value typedefs... + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) + OS << "typedef ReduceValuefirst + << "_Slot> ReducedValue_" << I->first << ";\n"; + + // Output the pattern enums... + OS << "\n\n" + << "enum { // Patterns...\n" + << " NotComputed = 0,\n" + << " NoMatchPattern, \n"; + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) { + OS << " // " << I->first << " patterns...\n"; + for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), + E = I->second.end(); J != E; ++J) + for (unsigned i = 0, e = J->second.size(); i != e; ++i) + OS << " " << J->second[i]->getRecord()->getName() << "_Pattern,\n"; + } + OS << "};\n\n"; + + // Start emitting the class... + OS << "namespace {\n" + << " class " << Target.getName() << "ISel {\n" + << " SelectionDAG &DAG;\n" + << " public:\n" + << " X86ISel(SelectionDag &D) : DAG(D) {}\n" + << " void generateCode();\n" + << " private:\n" + << " unsigned makeAnotherReg(const TargetRegisterClass *RC) {\n" + << " return DAG.getMachineFunction().getSSARegMap()->createVirt" + "ualRegister(RC);\n" + << " }\n\n" + << " // DAG matching methods for classes... all of these methods" + " return the cost\n" + <<" // of producing a value of the specified class and type, which" + " also gets\n" + << " // added to the DAG node.\n"; + + // Output all of the matching prototypes for slots... + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) + OS << " unsigned Match_" << I->first << "(SelectionDAGNode *N);\n"; + OS << "\n // DAG matching methods for DAG nodes...\n"; + + // Output all of the matching prototypes for slot/node pairs + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) + for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), + E = I->second.end(); J != E; ++J) + OS << " unsigned Match_" << I->first << "_" << J->first->getName() + << "(SelectionDAGNode *N);\n"; + + // Output all of the dag reduction methods prototypes... + OS << "\n // DAG reduction methods...\n"; + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) + OS << " ReducedValue_" << I->first << " *Reduce_" << I->first + << "(SelectionDAGNode *N,\n" << std::string(25+2*I->first.size(), ' ') + << "MachineBasicBlock *MBB);\n"; + OS << " };\n}\n\n"; + + OS << "void X86ISel::generateCode() {\n" + << " SelectionDAGNode *Root = DAG.getRoot();\n" + << " assert(Root->getValueType() == ISD::Void && " + "\"Root of DAG produces value??\");\n\n" + << " std::cerr << \"\\n\";\n" + << " unsigned Cost = Match_Void_Void(Root);\n" + << " if (Cost >= ~0U >> 1) {\n" + << " std::cerr << \"Match failed!\\n\";\n" + << " Root->dump();\n" + << " abort();\n" + << " }\n\n" + << " std::cerr << \"Total DAG Cost: \" << Cost << \"\\n\\n\";\n\n" + << " Reduce_Void_Void(Root, 0);\n" + << "}\n\n" + << "//===" << std::string(70, '-') << "===//\n" + << "// Matching methods...\n" + << "//\n"; } + Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.10 llvm/utils/TableGen/InstrSelectorEmitter.h:1.11 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.10 Thu Aug 7 18:16:20 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Fri Aug 8 11:30:10 2003 @@ -67,7 +67,10 @@ : Operator(o), Type(MVT::Other), Children(c), Value(0) {} TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {} - Record *getOperator() const { return Operator; } + Record *getOperator() const { + assert(Operator && "This is a leaf node!"); + return Operator; + } MVT::ValueType getType() const { return Type; } void setType(MVT::ValueType T) { Type = T; } @@ -204,6 +207,36 @@ std::ostream &operator<<(std::ostream &OS, const Pattern &P); +/// PatternOrganizer - This class represents all of the patterns which are +/// useful for the instruction selector, neatly catagorized in a hierarchical +/// structure. +struct PatternOrganizer { + /// PatternsForNode - The list of patterns which can produce a value of a + /// particular slot type, given a particular root node in the tree. All of + /// the patterns in this vector produce the same value type and have the same + /// root DAG node. + typedef std::vector PatternsForNode; + + /// NodesForSlot - This map keeps track of all of the root DAG nodes which can + /// lead to the production of a value for this slot. All of the patterns in + /// this data structure produces values of the same slot. + typedef std::map NodesForSlot; + + /// AllPatterns - This data structure contains all patterns in the instruction + /// selector. + std::map AllPatterns; + + // Forwarding functions... + typedef std::map::iterator iterator; + iterator begin() { return AllPatterns.begin(); } + iterator end() { return AllPatterns.end(); } + + + /// addPattern - Add the specified pattern to the appropriate location in the + /// collection. + void addPattern(Pattern *P); +}; + /// InstrSelectorEmitter - The top-level class which coordinates construction /// and emission of the instruction selector. @@ -222,6 +255,13 @@ /// have been instantiated already... /// std::map, Record*> InstantiatedNTs; + + /// ComputableValues - This map indicates which patterns can be used to + /// generate a value that is used by the selector. The keys of this map + /// implicitly define the values that are used by the selector. + /// + PatternOrganizer ComputableValues; + public: InstrSelectorEmitter(RecordKeeper &R) : Records(R) {} @@ -269,6 +309,10 @@ // InstantiateNonterminals - Instantiate any unresolved nonterminals with // information from the context that they are used in. void InstantiateNonterminals(); + + // CalculateComputableValues - Fill in the ComputableValues map through + // analysis of the patterns we are playing with. + void CalculateComputableValues(); }; #endif From criswell at cs.uiuc.edu Fri Aug 8 11:43:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 11:43:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/include/Support/FileUtilities.h Message-ID: <200308081642.LAA29545@choi.cs.uiuc.edu> Changes in directory llvm/include/Support: FileUtilities.h updated: 1.1 -> 1.1.4.1 --- Log message: Merged in HEAD on August 8, 2003. --- Diffs of the changes: Index: llvm/include/Support/FileUtilities.h diff -u llvm/include/Support/FileUtilities.h:1.1 llvm/include/Support/FileUtilities.h:1.1.4.1 --- llvm/include/Support/FileUtilities.h:1.1 Fri Aug 1 15:28:55 2003 +++ llvm/include/Support/FileUtilities.h Fri Aug 8 11:42:45 2003 @@ -26,4 +26,14 @@ /// void MoveFileOverIfUpdated(const std::string &New, const std::string &Old); +/// removeFile - Delete the specified file +/// +void removeFile(const std::string &Filename); + +/// getUniqueFilename - Return a filename with the specified prefix. If the +/// file does not exist yet, return it, otherwise add a suffix to make it +/// unique. +/// +std::string getUniqueFilename(const std::string &FilenameBase); + #endif From criswell at cs.uiuc.edu Fri Aug 8 11:52:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 11:52:01 2003 Subject: [llvm-commits] [pre-11] CVS: llvm/tools/bugpoint/BugDriver.cpp CodeGeneratorBug.cpp CrashDebugger.cpp ExecutionDriver.cpp Miscompilation.cpp OptimizerDriver.cpp Message-ID: <200308081651.LAA32632@choi.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.9 -> 1.9.4.1 CodeGeneratorBug.cpp updated: 1.11 -> 1.11.2.1 CrashDebugger.cpp updated: 1.14 -> 1.14.2.1 ExecutionDriver.cpp updated: 1.15 -> 1.15.2.1 Miscompilation.cpp updated: 1.12 -> 1.12.2.1 OptimizerDriver.cpp updated: 1.8 -> 1.8.4.1 --- Log message: Updated for the move of functions from llvm/tools/bugpoint to llvm/lib/Support. --- Diffs of the changes: Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.9 llvm/tools/bugpoint/BugDriver.cpp:1.9.4.1 --- llvm/tools/bugpoint/BugDriver.cpp:1.9 Thu Jul 24 16:59:10 2003 +++ llvm/tools/bugpoint/BugDriver.cpp Fri Aug 8 11:51:46 2003 @@ -7,7 +7,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include "llvm/Module.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Assembly/Parser.h" Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.11 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.11.2.1 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.11 Sun Aug 3 19:56:27 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Fri Aug 8 11:51:46 2003 @@ -5,7 +5,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include "ListReducer.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.14 llvm/tools/bugpoint/CrashDebugger.cpp:1.14.2.1 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.14 Tue Aug 5 10:51:05 2003 +++ llvm/tools/bugpoint/CrashDebugger.cpp Fri Aug 8 11:51:46 2003 @@ -5,7 +5,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include "ListReducer.h" #include "llvm/Module.h" #include "llvm/PassManager.h" Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.15 llvm/tools/bugpoint/ExecutionDriver.cpp:1.15.2.1 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.15 Sun Aug 3 19:56:43 2003 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Fri Aug 8 11:51:46 2003 @@ -15,7 +15,8 @@ */ #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include "Support/CommandLine.h" #include "Support/Debug.h" #include "Support/FileUtilities.h" Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.12 llvm/tools/bugpoint/Miscompilation.cpp:1.12.2.1 --- llvm/tools/bugpoint/Miscompilation.cpp:1.12 Mon Aug 4 14:03:42 2003 +++ llvm/tools/bugpoint/Miscompilation.cpp Fri Aug 8 11:51:46 2003 @@ -5,7 +5,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include "ListReducer.h" #include "llvm/Pass.h" #include "llvm/Module.h" Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.8 llvm/tools/bugpoint/OptimizerDriver.cpp:1.8.4.1 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.8 Mon Jul 21 16:58:16 2003 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Fri Aug 8 11:51:46 2003 @@ -9,7 +9,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" +#include "Support/SystemUtils.h" +#include "Support/FileUtilities.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/WriteBytecodePass.h" From gaeke at cs.uiuc.edu Fri Aug 8 14:35:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Aug 8 14:35:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Message-ID: <200308081934.OAA01218@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger: SecondTrigger.cpp updated: 1.10 -> 1.11 --- Log message: Remove garbage from end of lines. Re-indent and organize the huge if...else if...else statement into paragraphs with 1 paragraph per case. Write many new comments, including comments for each case, and for some of the asserts. --- Diffs of the changes: Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.10 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.11 --- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.10 Thu Aug 7 23:05:43 2003 +++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Fri Aug 8 14:33:50 2003 @@ -624,8 +624,8 @@ uint64_t lastPC = pc; bool sawUnconditional = false; - while(!(seenStartPC && pc==start)){///while - lastPC = pc; + while(!(seenStartPC && pc==start)) { + lastPC = pc; //so in the end, if we end the loop through second //while condition, we'd know which PC was branch. @@ -644,45 +644,46 @@ } } - - unsigned int instr = vm->readInstrFrmVm(pc, tr, tr2);//, tr2);//, tr2); + unsigned int instr = vm->readInstrFrmVm(pc, tr, tr2); - //case: unconditional jump - //neglect the branch, copy the delay slot - assert(! isBranchNever(instr)); - if(isBranchInstr(instr) && (isBranchAlways(instr) ) ){ - //push in the delay slot - if(insertCode){ + // case: unconditional jump + // Don't copy the branch, but copy the instruction in the delay + // slot following it. Then start copying from the branch's + // target. + assert((! isBranchNever (instr)) + && "Unsupported branch never instruction found!"); + if (isBranchInstr (instr) && isBranchAlways (instr)) { + if(insertCode){ + // Copy the instruction in the branch's delay slot, unless + // it's a NOP. unsigned dslot = vm->readInstrFrmVm(pc+4, tr, tr2); if(dslot != NOP){ - traces.push_back(dslot);//, tr2)); + traces.push_back(dslot); index++; } - } - pc = getBranchTarget(instr, pc); - sawUnconditional = true; - continue; + } + // Start copying from the branch's target. + pc = getBranchTarget(instr, pc); + sawUnconditional = true; } - //case: call instruction - //just rewrite the target later. Right now, just store the index - if(isReturn(instr)){ - //assert(callStack.size() && "Stack empty and a return is found!"); + // case: return instruction + // Don't copy the return, but copy the instruction in the delay + // slot following it. Then pop the call stack and start copying + // from where we left off in the caller. + else if (isReturn(instr)) { + // If we find a return we must have previously found the + // corresponding call. if(!callStack.size()){ tr->patchTrace(firstLevelTraceStartAddr); - assert(0 && "Found return"); -#ifdef GET_ALL_INFO - std::cerr<<"Found-return\n"; -#endif + assert(0 && "Call stack empty and return instruction found!"); return; } - #ifdef GET_ALL_INFO numberOfFunctions++; #endif - if(insertCode){ - //insert DS + // Copy the instruction in the return's delay slot. traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2)); index++; } @@ -690,6 +691,10 @@ callStack.pop_back(); calledStack.pop_back(); } + + // case: indirect call instruction + // Copy the call instruction and the instruction in the delay + // slot following it. else if(isIndirectCall(instr)){ if(insertCode){ #ifdef GET_COVERAGE @@ -703,7 +708,6 @@ traces.push_back(instr); traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2)); index += 2; - #ifdef GET_COVERAGE traces.push_back(0xde77a7ef);//save o7 traces.push_back(CALL); @@ -716,19 +720,21 @@ pc += 8; } + // case: ordinary call instruction + // If the function being called is simple enough to inline, then + // inline it; i.e. we continue copying instructions from the + // beginning of the called function. Otherwise, we proceed as + // with an indirect call, unless the target of the call is a + // reoptimizer entry point. else if(isCallInstr(instr)){ uint64_t callTarget = getCallTarget(instr, pc); - Function *callFunc = getRevFunction(M, callTarget); - //inline the function if its just one basic block //avoid recursion - if(callFunc && isInlinable(callFunc) && (callFunc->size() == 1 || tr->hasTraceAddr(callTarget)) && std::find(calledStack.begin(), calledStack.end(), callTarget) == calledStack.end()){ - //push DS, and set PC to new target if(insertCode){ //std::cerr<<"Inlining function\n"; @@ -738,18 +744,19 @@ //if(callFunc->size() > 1) getReturnCode(traces, index, pc); } - callStack.push_back(pc+8); //return address calledStack.push_back(callTarget); pc = callTarget; - } else{ - + // Can't inline the called function if(callTarget != (uint64_t)llvm_first_trigger && callTarget != (uint64_t)countPath){ + // Ordinary function being called; copy the call + // instruction and the instruction in the delay slot + // following it. Record the call target function in the + // call map. if(insertCode){ - #ifdef GET_COVERAGE traces.push_back(0xde77a7ef);//save o7 traces.push_back(CALL); @@ -774,39 +781,41 @@ } } else{ + // Reoptimizer entry point being called; skip the call, + // but copy its delay slot instruction. if(insertCode){ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2)); index += 1; } } - pc += 8; } } - //case: conditional branch + // case: conditional branch + // If the branch was taken, then insert an opposite branch to + // the fall-through. Then follow the taken branch, continuing to + // copy instructions starting from the branch's target. If the + // branch was not taken, then copy the branch and its delay + // slot instruction. else if(isBranchInstr(instr)){ - int nextTrace = -1; if(myIntersections && myIntersections->find(pathIndex) != - myIntersections->end())// && pathNumber==0) + myIntersections->end()) nextTrace = (*myIntersections)[pathIndex]; - - //is it taken? + // Check bit number pathIndex of firstPath to see whether the + // branch was taken. if(firstPath & (1ULL << pathIndex)){ - #ifdef GET_ALL_INFO std::cerr<<" taken \t"; #endif - if(insertCode){ - //invert the branch, and use the fall through as the target + // Invert the branch, and use the fall-through as the target. assert(!(instr & 0x20000000)); unsigned brInstr = vm->getInvertedBranch(instr); if(isNonDepJump(brInstr)) brInstr = (brInstr & 0xfff7ffff); traces.push_back(brInstr); - if(nextTrace < 0){ targetMap[index] = pc+8; } @@ -815,44 +824,45 @@ && "a given trace can have only one entry"); targetTraceMap[nextTrace] = index; } - - traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));;//, tr2)); + traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2)); index +=2; } - //continue pc from the target of the branch + // Continue copying instructions from the target of the branch. pc = getBranchTarget(instr, pc); } else{ + // Not-taken branch: just copy the branch and the + // instruction in the delay slot following it. if(insertCode){ - //just copy the branch if(isNonDepJump(instr)) instr = instr & 0xfff7ffff; - traces.push_back(instr); - if(nextTrace < 0){ targetMap[index] = getBranchTarget(instr, pc); } else{ targetTraceMap[nextTrace] = index; } - - - traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));//, tr2)); + traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2)); index +=2; } - pc += 8; } - - //increment pathIndex - + // Increment pathIndex here to make sure that the next time we + // process a conditional branch, we get the next branch's + // profile data. pathIndex++; } + + // case: unsupported control flow transfer instructions (???) + // FIXME: This matches a lot of different instructions; what + // kind of instruction is really unsupported here? else if((instr & 0x81c70000) == 0x81c70000){ - assert(0); + assert(0 && "Unsupported JMP/JMPL/RETT/TN/SAVE/ADDXCC instr. found!"); } - //just copy the instruction + + // case: default + // All other instructions are just copied into the traces vector. else{ if(insertCode){ if(instr!=NOP){ @@ -862,10 +872,10 @@ } pc += 4; } - } + } // End of while loop. if(sawUnconditional){ - //insert branch back to top! + //insert branch back to top! unsigned int br = vm->readInstrFrmVm(lastPC, tr, tr2);//, tr2); assert(isBranchInstr(br)); unsigned int ds = vm->readInstrFrmVm(lastPC+4, tr, tr2);//, tr2); From lattner at cs.uiuc.edu Fri Aug 8 17:30:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 8 17:30:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308082229.RAA30802@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.14 -> 1.15 InstrSelectorEmitter.h updated: 1.11 -> 1.12 --- Log message: This implements a large amount of the matcher, in fact, all of it except for one bug --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.14 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.15 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.14 Fri Aug 8 11:30:10 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Fri Aug 8 17:29:23 2003 @@ -9,6 +9,8 @@ #include "CodeGenWrappers.h" #include "Record.h" #include "Support/Debug.h" +#include "Support/StringExtras.h" +#include NodeType::ArgResultTypes NodeType::Translate(Record *R) { const std::string &Name = R->getName(); @@ -24,6 +26,15 @@ // TreePatternNode implementation // +/// getValueRecord - Returns the value of this tree node as a record. For now +/// we only allow DefInit's as our leaf values, so this is used. +Record *TreePatternNode::getValueRecord() const { + DefInit *DI = dynamic_cast(getValue()); + assert(DI && "Instruction Selector does not yet support non-def leaves!"); + return DI->getDef(); +} + + // updateNodeType - Set the node type of N to VT if VT contains information. If // N already contains a conflicting type, then throw an exception // @@ -50,17 +61,17 @@ } // If this is a leaf, it might be a reference to a nonterminal! Check now. - if (DefInit *DI = dynamic_cast(getValue())) - if (DI->getDef()->isSubClassOf("Nonterminal")) { - Pattern *NT = ISE.getPattern(DI->getDef()); - if (!NT->isResolved()) { - // We found an unresolved nonterminal reference. Ask the ISE to clone - // it for us, then update our reference to the fresh, new, resolved, - // nonterminal. - - Value = new DefInit(ISE.InstantiateNonterminal(NT, getType())); - } + Record *R = getValueRecord(); + if (R->isSubClassOf("Nonterminal")) { + Pattern *NT = ISE.getPattern(R); + if (!NT->isResolved()) { + // We found an unresolved nonterminal reference. Ask the ISE to clone + // it for us, then update our reference to the fresh, new, resolved, + // nonterminal. + + Value = new DefInit(ISE.InstantiateNonterminal(NT, getType())); } + } } @@ -80,7 +91,6 @@ return New; } - std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) { if (N.isLeaf()) return OS << N.getType() << ":" << *N.getValue(); @@ -126,11 +136,7 @@ assert(Tree->getChildren().size() == 2 && "Set with != 2 arguments?"); if (!Tree->getChild(0)->isLeaf()) error("Arg #0 of set should be a register or register class!"); - DefInit *RegInit = dynamic_cast(Tree->getChild(0)->getValue()); - if (RegInit == 0) - error("LHS of 'set' expected to be a register or register class!"); - - Result = RegInit->getDef(); + Result = Tree->getChild(0)->getValueRecord(); Tree = Tree->getChild(1); } } @@ -232,8 +238,7 @@ bool AnyUnset = false; Record *Operator = N->getOperator(); - assert(ISE.getNodeTypes().count(Operator) && "No node info for node!"); - const NodeType &NT = ISE.getNodeTypes()[Operator]; + const NodeType &NT = ISE.getNodeType(Operator); // Check to see if we can infer anything about the argument types from the // return types... @@ -317,6 +322,38 @@ } +/// getSlotName - If this is a leaf node, return the slot name that the operand +/// will update. +std::string Pattern::getSlotName() const { + if (getPatternType() == Pattern::Nonterminal) { + // Just use the nonterminal name, which will already include the type if + // it has been cloned. + return getRecord()->getName(); + } else { + std::string SlotName; + if (getResult()) + SlotName = getResult()->getName()+"_"; + else + SlotName = "Void_"; + return SlotName + getName(getTree()->getType()); + } +} + +/// getSlotName - If this is a leaf node, return the slot name that the +/// operand will update. +std::string Pattern::getSlotName(Record *R) { + if (R->isSubClassOf("Nonterminal")) { + // Just use the nonterminal name, which will already include the type if + // it has been cloned. + return R->getName(); + } else if (R->isSubClassOf("RegisterClass")) { + MVT::ValueType Ty = getValueType(R->getValueAsDef("RegType")); + return R->getName() + "_" + getName(Ty); + } else { + assert(0 && "Don't know how to get a slot name for this!"); + } +} + //===----------------------------------------------------------------------===// // PatternOrganizer implementation // @@ -324,29 +361,12 @@ /// addPattern - Add the specified pattern to the appropriate location in the /// collection. void PatternOrganizer::addPattern(Pattern *P) { - std::string ValueName; - if (P->getPatternType() == Pattern::Nonterminal) { - // Just use the nonterminal name, which will already include the type if - // it has been cloned. - ValueName = P->getRecord()->getName(); - } else { - if (P->getResult()) - ValueName += P->getResult()->getName()+"_"; - else - ValueName += "Void_"; - ValueName += getName(P->getTree()->getType()); - } - - NodesForSlot &Nodes = AllPatterns[ValueName]; + NodesForSlot &Nodes = AllPatterns[P->getSlotName()]; if (!P->getTree()->isLeaf()) Nodes[P->getTree()->getOperator()].push_back(P); else { // Right now we only support DefInit's with node types... - DefInit *Val = dynamic_cast(P->getTree()->getValue()); - if (!Val) - throw std::string("We only support def inits in PatternOrganizer" - "::addPattern so far!"); - Nodes[Val->getDef()].push_back(P); + Nodes[P->getTree()->getValueRecord()].push_back(P); } } @@ -469,6 +489,11 @@ Record *New = new Record(NT->getRecord()->getName()+"_"+getName(ResultTy)); + // Copy over the superclasses... + const std::vector &SCs = NT->getRecord()->getSuperClasses(); + for (unsigned i = 0, e = SCs.size(); i != e; ++i) + New->addSuperClass(SCs[i]); + DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName() << "' for type '" << getName(ResultTy) << "', producing '" << New->getName() << "'\n"); @@ -503,6 +528,242 @@ ComputableValues.addPattern(I->second); } +#if 0 +// MoveIdenticalPatterns - Given a tree pattern 'P', move all of the tree +// patterns which have the same top-level structure as P from the 'From' list to +// the 'To' list. +static void MoveIdenticalPatterns(TreePatternNode *P, + std::vector > &From, + std::vector > &To) { + assert(!P->isLeaf() && "All leaves are identical!"); + + const std::vector &PChildren = P->getChildren(); + for (unsigned i = 0; i != From.size(); ++i) { + TreePatternNode *N = From[i].second; + assert(P->getOperator() == N->getOperator() &&"Differing operators?"); + assert(PChildren.size() == N->getChildren().size() && + "Nodes with different arity??"); + bool isDifferent = false; + for (unsigned c = 0, e = PChildren.size(); c != e; ++c) { + TreePatternNode *PC = PChildren[c]; + TreePatternNode *NC = N->getChild(c); + if (PC->isLeaf() != NC->isLeaf()) { + isDifferent = true; + break; + } + + if (!PC->isLeaf()) { + if (PC->getOperator() != NC->getOperator()) { + isDifferent = true; + break; + } + } else { // It's a leaf! + if (PC->getValueRecord() != NC->getValueRecord()) { + isDifferent = true; + break; + } + } + } + // If it's the same as the reference one, move it over now... + if (!isDifferent) { + To.push_back(std::make_pair(From[i].first, N)); + From.erase(From.begin()+i); + --i; // Don't skip an entry... + } + } +} +#endif + +static void EmitPatternPredicates(TreePatternNode *Tree, + const std::string &VarName, std::ostream &OS){ + OS << " && " << VarName << "->getNodeType() == ISD::" + << Tree->getOperator()->getName(); + + for (unsigned c = 0, e = Tree->getNumChildren(); c != e; ++c) + if (!Tree->getChild(c)->isLeaf()) + EmitPatternPredicates(Tree->getChild(c), + VarName + "->getUse(" + utostr(c)+")", OS); +} + +static void EmitPatternCosts(TreePatternNode *Tree, const std::string &VarName, + std::ostream &OS) { + for (unsigned c = 0, e = Tree->getNumChildren(); c != e; ++c) + if (Tree->getChild(c)->isLeaf()) { + OS << " + Match_" + << Pattern::getSlotName(Tree->getChild(c)->getValueRecord()) << "(" + << VarName << "->getUse(" << c << "))"; + } else { + EmitPatternCosts(Tree->getChild(c), + VarName + "->getUse(" + utostr(c) + ")", OS); + } +} + + +// EmitMatchCosters - Given a list of patterns, which all have the same root +// pattern operator, emit an efficient decision tree to decide which one to +// pick. This is structured this way to avoid reevaluations of non-obvious +// subexpressions. +void InstrSelectorEmitter::EmitMatchCosters(std::ostream &OS, + const std::vector > &Patterns, + const std::string &VarPrefix, + unsigned IndentAmt) { + assert(!Patterns.empty() && "No patterns to emit matchers for!"); + std::string Indent(IndentAmt, ' '); + + // Load all of the operands of the root node into scalars for fast access + const NodeType &ONT = getNodeType(Patterns[0].second->getOperator()); + for (unsigned i = 0, e = ONT.ArgTypes.size(); i != e; ++i) + OS << Indent << "SelectionDAGNode *" << VarPrefix << "_Op" << i + << " = N->getUse(" << i << ");\n"; + + // Compute the costs of computing the various nonterminals/registers, which + // are directly used at this level. + OS << "\n" << Indent << "// Operand matching costs...\n"; + std::set ComputedValues; // Avoid duplicate computations... + for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { + const std::vector &Children = + Patterns[i].second->getChildren(); + for (unsigned c = 0, e = Children.size(); c != e; ++c) { + TreePatternNode *N = Children[c]; + if (N->isLeaf()) { + Record *VR = N->getValueRecord(); + const std::string &LeafName = VR->getName(); + std::string OpName = VarPrefix + "_Op" + utostr(c); + std::string ValName = OpName + "_" + LeafName + "_Cost"; + if (!ComputedValues.count(ValName)) { + OS << Indent << "unsigned " << ValName << " = Match_" + << Pattern::getSlotName(VR) << "(" << OpName << ");\n"; + ComputedValues.insert(ValName); + } + } + } + } + OS << "\n"; + + + std::string LocCostName = VarPrefix + "_Cost"; + OS << Indent << "unsigned " << LocCostName << "Min = ~0U >> 1;\n" + << Indent << "unsigned " << VarPrefix << "_PatternMin = NoMatch;\n"; + +#if 0 + // Separate out all of the patterns into groups based on what their top-level + // signature looks like... + std::vector > PatternsLeft(Patterns); + while (!PatternsLeft.empty()) { + // Process all of the patterns that have the same signature as the last + // element... + std::vector > Group; + MoveIdenticalPatterns(PatternsLeft.back().second, PatternsLeft, Group); + assert(!Group.empty() && "Didn't at least pick the source pattern?"); + +#if 0 + OS << "PROCESSING GROUP:\n"; + for (unsigned i = 0, e = Group.size(); i != e; ++i) + OS << " " << *Group[i].first << "\n"; + OS << "\n\n"; +#endif + + OS << Indent << "{ // "; + + if (Group.size() != 1) { + OS << Group.size() << " size group...\n"; + OS << Indent << " unsigned " << VarPrefix << "_Pattern = NoMatch;\n"; + } else { + OS << *Group[0].first << "\n"; + OS << Indent << " unsigned " << VarPrefix << "_Pattern = " + << Group[0].first->getRecord()->getName() << "_Pattern;\n"; + } + + OS << Indent << " unsigned " << LocCostName << " = "; + if (Group.size() == 1) + OS << "1;\n"; // Add inst cost if at individual rec + else + OS << "0;\n"; + + // Loop over all of the operands, adding in their costs... + TreePatternNode *N = Group[0].second; + const std::vector &Children = N->getChildren(); + + // If necessary, emit conditionals to check for the appropriate tree + // structure here... + for (unsigned i = 0, e = Children.size(); i != e; ++i) { + TreePatternNode *C = Children[i]; + if (C->isLeaf()) { + // We already calculated the cost for this leaf, add it in now... + OS << Indent << " " << LocCostName << " += " + << VarPrefix << "_Op" << utostr(i) << "_" + << C->getValueRecord()->getName() << "_Cost;\n"; + } else { + // If it's not a leaf, we have to check to make sure that the current + // node has the appropriate structure, then recurse into it... + OS << Indent << " if (" << VarPrefix << "_Op" << i + << "->getNodeType() == ISD::" << C->getOperator()->getName() + << ") {\n"; + std::vector > SubPatterns; + for (unsigned n = 0, e = Group.size(); n != e; ++n) + SubPatterns.push_back(std::make_pair(Group[n].first, + Group[n].second->getChild(i))); + EmitMatchCosters(OS, SubPatterns, VarPrefix+"_Op"+utostr(i), + IndentAmt + 4); + OS << Indent << " }\n"; + } + } + + // If the cost for this match is less than the minimum computed cost so far, + // update the minimum cost and selected pattern. + OS << Indent << " if (" << LocCostName << " < " << LocCostName << "Min) { " + << LocCostName << "Min = " << LocCostName << "; " << VarPrefix + << "_PatternMin = " << VarPrefix << "_Pattern; }\n"; + + OS << Indent << "}\n"; + } +#endif + + for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { + Pattern *P = Patterns[i].first; + TreePatternNode *PTree = P->getTree(); + unsigned PatternCost = 1; + + // Check to see if there are any non-leaf elements in the pattern. If so, + // we need to emit a predicate for this match. + bool AnyNonLeaf = false; + for (unsigned c = 0, e = PTree->getNumChildren(); c != e; ++c) + if (!PTree->getChild(c)->isLeaf()) { + AnyNonLeaf = true; + break; + } + + if (!AnyNonLeaf) { // No predicate necessary, just output a scope... + OS << " {// " << *P << "\n"; + } else { + // We need to emit a predicate to make sure the tree pattern matches, do + // so now... + OS << " if (1"; + for (unsigned c = 0, e = PTree->getNumChildren(); c != e; ++c) + if (!PTree->getChild(c)->isLeaf()) + EmitPatternPredicates(PTree->getChild(c), + VarPrefix + "_Op" + utostr(c), OS); + + OS << ") {\n // " << *P << "\n"; + } + + OS << " unsigned PatCost = " << PatternCost; + + for (unsigned c = 0, e = PTree->getNumChildren(); c != e; ++c) + if (PTree->getChild(c)->isLeaf()) { + OS << " + " << VarPrefix << "_Op" << c << "_" + << PTree->getChild(c)->getValueRecord()->getName() << "_Cost"; + } else { + EmitPatternCosts(PTree->getChild(c), VarPrefix + "_Op" + utostr(c), OS); + } + OS << ";\n"; + OS << " if (PatCost < MinCost) { MinCost = PatCost; Pattern = " + << P->getRecord()->getName() << "_Pattern; }\n" + << " }\n"; + } +} + + void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. ReadNodeTypes(); @@ -570,30 +831,30 @@ << " }\n\n" << " // DAG matching methods for classes... all of these methods" " return the cost\n" - <<" // of producing a value of the specified class and type, which" + << " // of producing a value of the specified class and type, which" " also gets\n" << " // added to the DAG node.\n"; // Output all of the matching prototypes for slots... for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) - OS << " unsigned Match_" << I->first << "(SelectionDAGNode *N);\n"; - OS << "\n // DAG matching methods for DAG nodes...\n"; + OS << " unsigned Match_" << I->first << "(SelectionDAGNode *N);\n"; + OS << "\n // DAG matching methods for DAG nodes...\n"; // Output all of the matching prototypes for slot/node pairs for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) - OS << " unsigned Match_" << I->first << "_" << J->first->getName() + OS << " unsigned Match_" << I->first << "_" << J->first->getName() << "(SelectionDAGNode *N);\n"; // Output all of the dag reduction methods prototypes... - OS << "\n // DAG reduction methods...\n"; + OS << "\n // DAG reduction methods...\n"; for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) - OS << " ReducedValue_" << I->first << " *Reduce_" << I->first - << "(SelectionDAGNode *N,\n" << std::string(25+2*I->first.size(), ' ') + OS << " ReducedValue_" << I->first << " *Reduce_" << I->first + << "(SelectionDAGNode *N,\n" << std::string(27+2*I->first.size(), ' ') << "MachineBasicBlock *MBB);\n"; OS << " };\n}\n\n"; @@ -613,6 +874,52 @@ << "}\n\n" << "//===" << std::string(70, '-') << "===//\n" << "// Matching methods...\n" - << "//\n"; + << "//\n\n"; + + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) { + const std::string &SlotName = I->first; + OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName + << "(SelectionDAGNode *N) {\n" + << " assert(N->getValueType() == ISD::" + << getName((*I->second.begin()).second[0]->getTree()->getType())<< ");\n" + << " // If we already have a cost available for " << SlotName + << " use it!\n" + << " if (N->getPatternFor(" << SlotName << "_Slot))\n" + << " return N->getCostFor(" << SlotName << "_Slot);\n\n" + << " unsigned Cost;\n" + << " switch (N->getNodeType()) {\n" + << " default: assert(0 && \"Unhandled node type for " << SlotName + << "!\");\n"; + + for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), + E = I->second.end(); J != E; ++J) + OS << " case ISD::" << J->first->getName() << ":\tCost = Match_" + << SlotName << "_" << J->first->getName() << "(N); break;\n"; + + OS << " }\n return Cost;\n}\n\n"; + + for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), + E = I->second.end(); J != E; ++J) { + Record *Operator = J->first; + OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName << "_" + << Operator->getName() << "(SelectionDAGNode *N) {\n" + << " unsigned Pattern = NoMatchPattern;\n" + << " unsigned MinCost = ~0U >> 1;\n"; + + std::vector > Patterns; + for (unsigned i = 0, e = J->second.size(); i != e; ++i) + Patterns.push_back(std::make_pair(J->second[i], + J->second[i]->getTree())); + EmitMatchCosters(OS, Patterns, "N", 2); + + OS << "\n N->setPatternCostFor(" << SlotName + << "_Slot, Pattern, MinCost, NumSlots);\n" + << " return MinCost;\n" + << "}\n"; + } + + break; // FIXME: REMOVE + } } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.11 llvm/utils/TableGen/InstrSelectorEmitter.h:1.12 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.11 Fri Aug 8 11:30:10 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Fri Aug 8 17:29:23 2003 @@ -80,6 +80,7 @@ assert(Operator != 0 && "This is a leaf node!"); return Children; } + unsigned getNumChildren() const { return Children.size(); } TreePatternNode *getChild(unsigned c) const { assert(c < Children.size() && "Child access out of range!"); return getChildren()[c]; @@ -90,6 +91,10 @@ return Value; } + /// getValueRecord - Returns the value of this tree node as a record. For now + /// we only allow DefInit's as our leaf values, so this is used. + Record *getValueRecord() const; + /// clone - Make a copy of this tree and all of its children. /// TreePatternNode *clone() const; @@ -101,10 +106,10 @@ /// it with the using context we provide. void InstantiateNonterminals(InstrSelectorEmitter &ISE); - // UpdateNodeType - Set the node type of N to VT if VT contains information. - // If N already contains a conflicting type, then throw an exception. This - // returns true if any information was updated. - // + /// UpdateNodeType - Set the node type of N to VT if VT contains information. + /// If N already contains a conflicting type, then throw an exception. This + /// returns true if any information was updated. + /// bool updateNodeType(MVT::ValueType VT, const std::string &RecName); }; @@ -198,6 +203,11 @@ /// pattern. void error(const std::string &Msg) const; + /// getSlotName - If this is a leaf node, return the slot name that the + /// operand will update. + std::string getSlotName() const; + static std::string getSlotName(Record *R); + private: MVT::ValueType getIntrinsicType(Record *R) const; TreePatternNode *ParseTreePattern(DagInit *DI); @@ -270,6 +280,11 @@ const CodeGenTarget &getTarget() const { return Target; } std::map &getNodeTypes() { return NodeTypes; } + const NodeType &getNodeType(Record *R) const { + std::map::const_iterator I = NodeTypes.find(R); + assert(I != NodeTypes.end() && "Unknown node type!"); + return I->second; + } /// getPattern - return the pattern corresponding to the specified record, or /// null if there is none. @@ -313,6 +328,14 @@ // CalculateComputableValues - Fill in the ComputableValues map through // analysis of the patterns we are playing with. void CalculateComputableValues(); + + // EmitMatchCosters - Given a list of patterns, which all have the same root + // pattern operator, emit an efficient decision tree to decide which one to + // pick. This is structured this way to avoid reevaluations of non-obvious + // subexpressions. + void EmitMatchCosters(std::ostream &OS, + const std::vector > &Patterns, + const std::string &VarPrefix, unsigned Indent); }; #endif From criswell at cs.uiuc.edu Fri Aug 8 17:37:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 17:37:02 2003 Subject: [llvm-commits] CVS: llvm/www/docs/GettingStarted.html Message-ID: <200308082236.RAA14395@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: GettingStarted.html updated: 1.26 -> 1.27 --- Log message: Updated for the 1.1 pre-release. Attempted to explain how OBJ_ROOT=. and OBJ_ROOT=`pwd` are not the same thing. --- Diffs of the changes: Index: llvm/www/docs/GettingStarted.html diff -u llvm/www/docs/GettingStarted.html:1.26 llvm/www/docs/GettingStarted.html:1.27 --- llvm/www/docs/GettingStarted.html:1.26 Tue Jul 8 15:35:59 2003 +++ llvm/www/docs/GettingStarted.html Fri Aug 8 17:36:30 2003 @@ -496,7 +496,16 @@ object files, libraries, and executables should be placed. If this is set to ., then the object files will be placed within the source code tree. If left unspecified, the default value is - .. + the following: +
      +
    • + If the USER environment variable is specified and the directory + /localhome/$USER exists, then the default value is + /localhome/$USER. + +
    • + Otherwise, the default value is .. +
    (See the Section on The Location of LLVM Object Files for more information.) @@ -632,7 +641,19 @@

    If OBJ_ROOT is specified, then the build system will create a directory tree underneath it that resembles the source code's pathname - relative to your home directory. + relative to your home directory (unless OBJ_ROOT is set to + ., in which case object files are placed within the LLVM source + tree). +

    + +

    + Note that + --with-objroot=. + and + --with-objroot=`pwd` + are not the same thing. The former will simply place object files within + the source tree, while the latter will set the location of object files + using the source tree's relative path from the home directory.

    From criswell at cs.uiuc.edu Fri Aug 8 17:44:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 17:44:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/GettingStarted.html Message-ID: <200308082243.RAA14453@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: GettingStarted.html updated: 1.27 -> 1.28 --- Log message: Added a FAQ about how to clean the directory if it fails to build after an update. --- Diffs of the changes: Index: llvm/www/docs/GettingStarted.html diff -u llvm/www/docs/GettingStarted.html:1.27 llvm/www/docs/GettingStarted.html:1.28 --- llvm/www/docs/GettingStarted.html:1.27 Fri Aug 8 17:36:30 2003 +++ llvm/www/docs/GettingStarted.html Fri Aug 8 17:43:39 2003 @@ -1036,6 +1036,19 @@ configure to do its work without having to adjust your PATH permanently. + +

    I've upgraded to a new version of LLVM, and I get strange build + errors. +
    + Sometimes changes to the LLVM source code alters how the build system + works. Changes in libtool, autoconf, or header file dependencies are + especially prone to this sort of problem. +

    + The best thing to try is to remove the old files and re-build. In most + cases, this takes care of the problem. To do this, just type make + clean and then make in the directory that fails to build. +

    + From criswell at cs.uiuc.edu Fri Aug 8 17:47:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 8 17:47:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/GettingStarted.html Message-ID: <200308082246.RAA14532@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: GettingStarted.html updated: 1.28 -> 1.29 --- Log message: Removed information on the Pool Allocator as it is no longer available. Fixed a spelling error. --- Diffs of the changes: Index: llvm/www/docs/GettingStarted.html diff -u llvm/www/docs/GettingStarted.html:1.28 llvm/www/docs/GettingStarted.html:1.29 --- llvm/www/docs/GettingStarted.html:1.28 Fri Aug 8 17:43:39 2003 +++ llvm/www/docs/GettingStarted.html Fri Aug 8 17:46:30 2003 @@ -774,8 +774,7 @@

    llvm/lib/Transforms/
    This directory contains the source code for the LLVM to LLVM program transformations, such as Aggressive Dead Code Elimination, Sparse Conditional Constant Propagation, Inlining, Loop - Invarient Code Motion, Dead Global Elimination, Pool Allocation, and many - others... + Invarient Code Motion, Dead Global Elimination, and many others...
    llvm/lib/Target/
    This directory contains files that describe various target architectures for code generation. For example, @@ -879,7 +878,7 @@

    - This step is optional if you have the C front end binary distrubtion for + This step is optional if you have the C front end binary distribution for your platform.

    From lattner at cs.uiuc.edu Sun Aug 10 14:51:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 14:51:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenWrappers.cpp CodeGenWrappers.h Message-ID: <200308101950.OAA24956@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenWrappers.cpp updated: 1.2 -> 1.3 CodeGenWrappers.h updated: 1.3 -> 1.4 --- Log message: Add new function --- Diffs of the changes: Index: llvm/utils/TableGen/CodeGenWrappers.cpp diff -u llvm/utils/TableGen/CodeGenWrappers.cpp:1.2 llvm/utils/TableGen/CodeGenWrappers.cpp:1.3 --- llvm/utils/TableGen/CodeGenWrappers.cpp:1.2 Thu Aug 7 18:15:21 2003 +++ llvm/utils/TableGen/CodeGenWrappers.cpp Sun Aug 10 14:50:32 2003 @@ -34,6 +34,24 @@ } } +std::string getEnumName(MVT::ValueType T) { + switch (T) { + case MVT::Other: return "Other"; + case MVT::i1: return "i1"; + case MVT::i8: return "i8"; + case MVT::i16: return "i16"; + case MVT::i32: return "i32"; + case MVT::i64: return "i64"; + case MVT::i128: return "i128"; + case MVT::f32: return "f32"; + case MVT::f64: return "f64"; + case MVT::f80: return "f80"; + case MVT::f128: return "f128"; + case MVT::isVoid:return "isVoid"; + default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; + } +} + std::ostream &operator<<(std::ostream &OS, MVT::ValueType T) { return OS << getName(T); Index: llvm/utils/TableGen/CodeGenWrappers.h diff -u llvm/utils/TableGen/CodeGenWrappers.h:1.3 llvm/utils/TableGen/CodeGenWrappers.h:1.4 --- llvm/utils/TableGen/CodeGenWrappers.h:1.3 Thu Aug 7 18:15:21 2003 +++ llvm/utils/TableGen/CodeGenWrappers.h Sun Aug 10 14:50:32 2003 @@ -22,6 +22,7 @@ std::ostream &operator<<(std::ostream &OS, MVT::ValueType T); std::string getName(MVT::ValueType T); +std::string getEnumName(MVT::ValueType T); /// CodeGenTarget - This class corresponds to the Target class in the .td files. From lattner at cs.uiuc.edu Sun Aug 10 14:52:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 14:52:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200308101951.OAA25009@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.16 -> 1.17 --- Log message: Make imm be a leaf instead of a nonterminal --- Diffs of the changes: Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.16 llvm/lib/Target/Target.td:1.17 --- llvm/lib/Target/Target.td:1.16 Thu Aug 7 08:52:22 2003 +++ llvm/lib/Target/Target.td Sun Aug 10 14:51:16 2003 @@ -178,7 +178,7 @@ def set : DagNode; // Terminals... -def Constant : BuiltinDagNode; +def imm : BuiltinDagNode; // def frameidx : BuiltinDagNode; // Arithmetic... @@ -206,5 +206,5 @@ } // imm - Immediate value... -def imm : Nonterminal<(Constant)> { let BuiltIn = 1; } +//def imm : Nonterminal<(Constant)> { let BuiltIn = 1; } From lattner at cs.uiuc.edu Sun Aug 10 14:52:15 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 14:52:15 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308101951.OAA24976@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.15 -> 1.16 InstrSelectorEmitter.h updated: 1.12 -> 1.13 --- Log message: Finish the matcher! --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.15 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.16 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.15 Fri Aug 8 17:29:23 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Sun Aug 10 14:50:51 2003 @@ -142,8 +142,6 @@ } } - - void Pattern::error(const std::string &Msg) const { std::string M = "In "; switch (PTy) { @@ -321,6 +319,9 @@ return OS; } +void Pattern::dump() const { std::cerr << *this; } + + /// getSlotName - If this is a leaf node, return the slot name that the operand /// will update. @@ -574,10 +575,20 @@ } #endif +static std::string getNodeName(Record *R) { + RecordVal *RV = R->getValue("EnumName"); + if (RV) + if (Init *I = RV->getValue()) + if (StringInit *SI = dynamic_cast(I)) + return SI->getValue(); + return R->getName(); +} + + static void EmitPatternPredicates(TreePatternNode *Tree, const std::string &VarName, std::ostream &OS){ OS << " && " << VarName << "->getNodeType() == ISD::" - << Tree->getOperator()->getName(); + << getNodeName(Tree->getOperator()); for (unsigned c = 0, e = Tree->getNumChildren(); c != e; ++c) if (!Tree->getChild(c)->isLeaf()) @@ -643,7 +654,7 @@ std::string LocCostName = VarPrefix + "_Cost"; OS << Indent << "unsigned " << LocCostName << "Min = ~0U >> 1;\n" - << Indent << "unsigned " << VarPrefix << "_PatternMin = NoMatch;\n"; + << Indent << "unsigned " << VarPrefix << "_PatternMin = NoMatchPattern;\n"; #if 0 // Separate out all of the patterns into groups based on what their top-level @@ -697,7 +708,7 @@ // If it's not a leaf, we have to check to make sure that the current // node has the appropriate structure, then recurse into it... OS << Indent << " if (" << VarPrefix << "_Op" << i - << "->getNodeType() == ISD::" << C->getOperator()->getName() + << "->getNodeType() == ISD::" << getNodeName(C->getOperator()) << ") {\n"; std::vector > SubPatterns; for (unsigned n = 0, e = Group.size(); n != e; ++n) @@ -763,7 +774,6 @@ } } - void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. ReadNodeTypes(); @@ -788,8 +798,11 @@ CalculateComputableValues(); + EmitSourceFileHeader("Instruction Selector for the " + Target.getName() + + " target", OS); + // Output the slot number enums... - OS << "\n\nenum { // Slot numbers...\n" + OS << "\nenum { // Slot numbers...\n" << " LastBuiltinSlot = ISD::NumBuiltinSlots-1, // Start numbering here\n"; for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) @@ -798,9 +811,11 @@ // Output the reduction value typedefs... for (PatternOrganizer::iterator I = ComputableValues.begin(), - E = ComputableValues.end(); I != E; ++I) - OS << "typedef ReduceValuefirst + E = ComputableValues.end(); I != E; ++I) { + + OS << "typedef ReducedValuefirst << "_Slot> ReducedValue_" << I->first << ";\n"; + } // Output the pattern enums... OS << "\n\n" @@ -822,7 +837,7 @@ << " class " << Target.getName() << "ISel {\n" << " SelectionDAG &DAG;\n" << " public:\n" - << " X86ISel(SelectionDag &D) : DAG(D) {}\n" + << " X86ISel(SelectionDAG &D) : DAG(D) {}\n" << " void generateCode();\n" << " private:\n" << " unsigned makeAnotherReg(const TargetRegisterClass *RC) {\n" @@ -846,7 +861,7 @@ E = ComputableValues.end(); I != E; ++I) for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) - OS << " unsigned Match_" << I->first << "_" << J->first->getName() + OS << " unsigned Match_" << I->first << "_" << getNodeName(J->first) << "(SelectionDAGNode *N);\n"; // Output all of the dag reduction methods prototypes... @@ -860,17 +875,17 @@ OS << "void X86ISel::generateCode() {\n" << " SelectionDAGNode *Root = DAG.getRoot();\n" - << " assert(Root->getValueType() == ISD::Void && " + << " assert(Root->getValueType() == MVT::isVoid && " "\"Root of DAG produces value??\");\n\n" << " std::cerr << \"\\n\";\n" - << " unsigned Cost = Match_Void_Void(Root);\n" + << " unsigned Cost = Match_Void_void(Root);\n" << " if (Cost >= ~0U >> 1) {\n" << " std::cerr << \"Match failed!\\n\";\n" << " Root->dump();\n" << " abort();\n" << " }\n\n" << " std::cerr << \"Total DAG Cost: \" << Cost << \"\\n\\n\";\n\n" - << " Reduce_Void_Void(Root, 0);\n" + << " Reduce_Void_void(Root, 0);\n" << "}\n\n" << "//===" << std::string(70, '-') << "===//\n" << "// Matching methods...\n" @@ -881,9 +896,9 @@ const std::string &SlotName = I->first; OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName << "(SelectionDAGNode *N) {\n" - << " assert(N->getValueType() == ISD::" - << getName((*I->second.begin()).second[0]->getTree()->getType())<< ");\n" - << " // If we already have a cost available for " << SlotName + << " assert(N->getValueType() == MVT::" + << getEnumName((*I->second.begin()).second[0]->getTree()->getType()) + << ");\n" << " // If we already have a cost available for " << SlotName << " use it!\n" << " if (N->getPatternFor(" << SlotName << "_Slot))\n" << " return N->getCostFor(" << SlotName << "_Slot);\n\n" @@ -894,32 +909,47 @@ for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) - OS << " case ISD::" << J->first->getName() << ":\tCost = Match_" - << SlotName << "_" << J->first->getName() << "(N); break;\n"; + if (!J->first->isSubClassOf("Nonterminal")) + OS << " case ISD::" << getNodeName(J->first) << ":\tCost = Match_" + << SlotName << "_" << getNodeName(J->first) << "(N); break;\n"; + OS << " }\n"; // End of the switch statement + + // Emit any patterns which have a nonterminal leaf as the RHS. These may + // match multiple root nodes, so they cannot be handled with the switch... + for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), + E = I->second.end(); J != E; ++J) + if (J->first->isSubClassOf("Nonterminal")) { + OS << " unsigned " << J->first->getName() << "_Cost = Match_" + << getNodeName(J->first) << "(N);\n" + << " if (" << getNodeName(J->first) << "_Cost < Cost) Cost = " + << getNodeName(J->first) << "_Cost;\n"; + } - OS << " }\n return Cost;\n}\n\n"; + OS << " return Cost;\n}\n\n"; for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) { Record *Operator = J->first; - OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName << "_" - << Operator->getName() << "(SelectionDAGNode *N) {\n" - << " unsigned Pattern = NoMatchPattern;\n" - << " unsigned MinCost = ~0U >> 1;\n"; - - std::vector > Patterns; - for (unsigned i = 0, e = J->second.size(); i != e; ++i) - Patterns.push_back(std::make_pair(J->second[i], - J->second[i]->getTree())); - EmitMatchCosters(OS, Patterns, "N", 2); - - OS << "\n N->setPatternCostFor(" << SlotName - << "_Slot, Pattern, MinCost, NumSlots);\n" - << " return MinCost;\n" - << "}\n"; + bool isNonterm = Operator->isSubClassOf("Nonterminal"); + if (!isNonterm) { + OS << "unsigned " << Target.getName() << "ISel::Match_"; + if (!isNonterm) OS << SlotName << "_"; + OS << getNodeName(Operator) << "(SelectionDAGNode *N) {\n" + << " unsigned Pattern = NoMatchPattern;\n" + << " unsigned MinCost = ~0U >> 1;\n"; + + std::vector > Patterns; + for (unsigned i = 0, e = J->second.size(); i != e; ++i) + Patterns.push_back(std::make_pair(J->second[i], + J->second[i]->getTree())); + EmitMatchCosters(OS, Patterns, "N", 2); + + OS << "\n N->setPatternCostFor(" << SlotName + << "_Slot, Pattern, MinCost, NumSlots);\n" + << " return MinCost;\n" + << "}\n"; + } } - - break; // FIXME: REMOVE } } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.12 llvm/utils/TableGen/InstrSelectorEmitter.h:1.13 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.12 Fri Aug 8 17:29:23 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Sun Aug 10 14:50:51 2003 @@ -208,6 +208,8 @@ std::string getSlotName() const; static std::string getSlotName(Record *R); + void dump() const; + private: MVT::ValueType getIntrinsicType(Record *R) const; TreePatternNode *ParseTreePattern(DagInit *DI); From lattner at cs.uiuc.edu Sun Aug 10 15:35:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 15:35:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp Message-ID: <200308102034.PAA30470@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.16 -> 1.17 --- Log message: First cut at emitting the reducer. This reducer just prints out the patterns selected, but it seems to work great! --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.16 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.17 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.16 Sun Aug 10 14:50:51 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Sun Aug 10 15:34:13 2003 @@ -774,6 +774,24 @@ } } +static void ReduceAllOperands(TreePatternNode *N, const std::string &Name, + std::vector > &Operands, + std::ostream &OS) { + if (!N->isLeaf()) { + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + std::string ChildName = Name + "_Op" + utostr(i); + OS << " SelectionDAGNode *" << ChildName << " = " << Name + << "->getUse(" << i << ");\n"; + ReduceAllOperands(N->getChild(i), ChildName, Operands, OS); + } + } else { + std::string SlotName = Pattern::getSlotName(N->getValueRecord()); + OS << " ReducedValue_" << SlotName << " *" << Name << "Val = Reduce_" + << SlotName << "(" << Name << ", MBB);\n"; + Operands.push_back(std::make_pair(N, Name+"Val")); + } +} + void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. ReadNodeTypes(); @@ -832,7 +850,9 @@ } OS << "};\n\n"; - // Start emitting the class... + //===--------------------------------------------------------------------===// + // Emit the class definition... + // OS << "namespace {\n" << " class " << Target.getName() << "ISel {\n" << " SelectionDAG &DAG;\n" @@ -873,6 +893,7 @@ << "MachineBasicBlock *MBB);\n"; OS << " };\n}\n\n"; + // Emit the generateCode entry-point... OS << "void X86ISel::generateCode() {\n" << " SelectionDAGNode *Root = DAG.getRoot();\n" << " assert(Root->getValueType() == MVT::isVoid && " @@ -891,6 +912,9 @@ << "// Matching methods...\n" << "//\n\n"; + //===--------------------------------------------------------------------===// + // Emit all of the matcher methods... + // for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) { const std::string &SlotName = I->first; @@ -950,6 +974,50 @@ << "}\n"; } } + } + + //===--------------------------------------------------------------------===// + // Emit all of the reducer methods... + // + OS << "\n\n//===" << std::string(70, '-') << "===//\n" + << "// Reducer methods...\n" + << "//\n"; + + for (PatternOrganizer::iterator I = ComputableValues.begin(), + E = ComputableValues.end(); I != E; ++I) { + const std::string &SlotName = I->first; + OS << "ReducedValue_" << SlotName << " *" << Target.getName() + << "ISel::Reduce_" << SlotName + << "(SelectionDAGNode *N, MachineBasicBlock *MBB) {\n" + << " ReducedValue_" << SlotName << " *Val = N->hasValue(" << SlotName << "_Slot);\n" + << " if (Val) return Val;\n" + << " if (N->getBB()) MBB = N->getBB();\n\n" + << " switch (N->getPatternFor(" << SlotName << "_Slot)) {\n"; + + // Loop over all of the patterns that can produce a value for this slot... + PatternOrganizer::NodesForSlot &NodesForSlot = I->second; + for (PatternOrganizer::NodesForSlot::iterator J = NodesForSlot.begin(), + E = NodesForSlot.end(); J != E; ++J) + for (unsigned i = 0, e = J->second.size(); i != e; ++i) { + Pattern *P = J->second[i]; + OS << " case " << P->getRecord()->getName() << "_Pattern: {\n" + << " // " << *P << "\n"; + // Loop over the operands, reducing them... + std::vector > Operands; + ReduceAllOperands(P->getTree(), "N", Operands, OS); + + + OS << " std::cerr << \" " << P->getRecord()->getName()<< "\\n\";\n"; + OS << " Val = new ReducedValue_" << SlotName << "(0);\n" + << " break;\n" + << " }\n"; + } + + + OS << " default: assert(0 && \"Unknown " << SlotName << " pattern!\");\n" + << " }\n\n N->addValue(Val); // Do not ever recalculate this\n" + << " return Val;\n}\n\n"; } } From lattner at cs.uiuc.edu Sun Aug 10 16:55:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 16:55:01 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp Message-ID: <200308102154.QAA05976@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.17 -> 1.18 --- Log message: Implement real code emission, at least for Instruction patterns, next up: support for expanders --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.17 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.18 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.17 Sun Aug 10 15:34:13 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Sun Aug 10 16:54:43 2003 @@ -777,18 +777,31 @@ static void ReduceAllOperands(TreePatternNode *N, const std::string &Name, std::vector > &Operands, std::ostream &OS) { - if (!N->isLeaf()) { + if (N->isLeaf()) { + // If this is a leaf, register or nonterminal reference... + std::string SlotName = Pattern::getSlotName(N->getValueRecord()); + OS << " ReducedValue_" << SlotName << " *" << Name << "Val = Reduce_" + << SlotName << "(" << Name << ", MBB);\n"; + Operands.push_back(std::make_pair(N, Name+"Val")); + } else if (N->getNumChildren() == 0) { + // This is a reference to a leaf tree node, like an immediate or frame + // index. + if (N->getType() != MVT::isVoid) { + std::string SlotName = + getNodeName(N->getOperator()) + "_" + getName(N->getType()); + OS << " ReducedValue_" << SlotName << " *" << Name << "Val = " + << Name << "->getValue(ISD::" + << SlotName << "_Slot);\n"; + Operands.push_back(std::make_pair(N, Name+"Val")); + } + } else { + // Otherwise this is an interior node... for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { std::string ChildName = Name + "_Op" + utostr(i); OS << " SelectionDAGNode *" << ChildName << " = " << Name << "->getUse(" << i << ");\n"; ReduceAllOperands(N->getChild(i), ChildName, Operands, OS); } - } else { - std::string SlotName = Pattern::getSlotName(N->getValueRecord()); - OS << " ReducedValue_" << SlotName << " *" << Name << "Val = Reduce_" - << SlotName << "(" << Name << ", MBB);\n"; - Operands.push_back(std::make_pair(N, Name+"Val")); } } @@ -818,6 +831,7 @@ EmitSourceFileHeader("Instruction Selector for the " + Target.getName() + " target", OS); + OS << "#include \"llvm/CodeGen/MachineInstrBuilder.h\"\n"; // Output the slot number enums... OS << "\nenum { // Slot numbers...\n" @@ -1007,9 +1021,68 @@ std::vector > Operands; ReduceAllOperands(P->getTree(), "N", Operands, OS); + // Now that we have reduced all of our operands, and have the values + // that reduction produces, perform the reduction action for this + // pattern. + std::string Result; + + // If the pattern produces a register result, generate a new register + // now. + if (Record *R = P->getResult()) { + assert(R->isSubClassOf("RegisterClass") && + "Only handle register class results so far!"); + OS << " unsigned NewReg = makeAnotherReg(" << Target.getName() + << "::" << R->getName() << "RegisterClass);\n"; + Result = "NewReg"; + DEBUG(OS << " std::cerr << \"%reg\" << NewReg << \" =\t\";\n"); + } else { + DEBUG(OS << " std::cerr << \"\t\t\";\n"); + Result = "0"; + } + + // Print out the pattern that matched... + DEBUG(OS << " std::cerr << \" " << P->getRecord()->getName() <<'"'); + DEBUG(for (unsigned i = 0, e = Operands.size(); i != e; ++i) + if (Operands[i].first->isLeaf()) { + Record *RV = Operands[i].first->getValueRecord(); + assert(RV->isSubClassOf("RegisterClass") && + "Only handles registers here so far!"); + OS << " << \" %reg\" << " << Operands[i].second + << "->Val"; + } else { + OS << " << ' ' << " << Operands[i].second + << "->Val"; + }); + DEBUG(OS << " << \"\\n\";\n"); - OS << " std::cerr << \" " << P->getRecord()->getName()<< "\\n\";\n"; - OS << " Val = new ReducedValue_" << SlotName << "(0);\n" + // Generate the reduction code appropriate to the particular type of + // pattern that this is... + switch (P->getPatternType()) { + case Pattern::Instruction: + OS << " BuildMI(MBB, " << Target.getName() << "::" + << P->getRecord()->getName() << ", " << Operands.size(); + if (P->getResult()) OS << ", NewReg"; + OS << ")"; + + for (unsigned i = 0, e = Operands.size(); i != e; ++i) + if (Operands[i].first->isLeaf()) { + Record *RV = Operands[i].first->getValueRecord(); + assert(RV->isSubClassOf("RegisterClass") && + "Only handles registers here so far!"); + OS << ".addReg(" << Operands[i].second << "->Val)"; + } else { + OS << ".addZImm(" << Operands[i].second << "->Val)"; + } + OS << ";\n"; + + break; + case Pattern::Expander: + break; + default: + assert(0 && "Reduction of this type of pattern not implemented!"); + } + + OS << " Val = new ReducedValue_" << SlotName << "(" << Result<<");\n" << " break;\n" << " }\n"; } From lattner at cs.uiuc.edu Sun Aug 10 17:03:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 17:03:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/TreeNames.td Message-ID: <200308102202.RAA06172@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: TreeNames.td added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/TableGen/TreeNames.td diff -c /dev/null llvm/test/Regression/TableGen/TreeNames.td:1.1 *** /dev/null Sun Aug 10 17:02:54 2003 --- llvm/test/Regression/TableGen/TreeNames.td Sun Aug 10 17:02:44 2003 *************** *** 0 **** --- 1,17 ---- + // This tests to make sure we can parse tree patterns with names. + // RUN: tblgen %s + + class TreeNode; + class RegisterClass; + + def set : TreeNode; + def plus : TreeNode; + def imm : TreeNode; + def R32 : RegisterClass; + + class Inst { + dag Pattern = T; + } + + def ADDrr32 : Inst<(set R32, (plus R32:$A, R32:$def))>; + From lattner at cs.uiuc.edu Sun Aug 10 18:53:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 18:53:02 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp InstrSelectorEmitter.h Message-ID: <200308102352.SAA28999@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.20 -> 1.21 InstrSelectorEmitter.h updated: 1.13 -> 1.14 --- Log message: Add full support for code generating expanders! This includes support for referencing named arguments. --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.20 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.21 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.20 Sun Aug 10 17:38:36 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Sun Aug 10 18:51:52 2003 @@ -55,8 +55,8 @@ /// void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) { if (!isLeaf()) { - for (unsigned i = 0, e = Children.size(); i != e; ++i) - Children[i]->InstantiateNonterminals(ISE); + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + getChild(i)->InstantiateNonterminals(ISE); return; } @@ -82,9 +82,10 @@ if (isLeaf()) { New = new TreePatternNode(Value); } else { - std::vector CChildren(Children.size()); - for (unsigned i = 0, e = Children.size(); i != e; ++i) - CChildren[i] = Children[i]->clone(); + std::vector > CChildren; + CChildren.reserve(Children.size()); + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + CChildren.push_back(std::make_pair(getChild(i)->clone(),getChildName(i))); New = new TreePatternNode(Operator, CChildren); } New->setType(Type); @@ -97,11 +98,10 @@ OS << "(" << N.getType() << ":"; OS << N.getOperator()->getName(); - const std::vector &Children = N.getChildren(); - if (!Children.empty()) { - OS << " " << *Children[0]; - for (unsigned i = 1, e = Children.size(); i != e; ++i) - OS << ", " << *Children[i]; + if (N.getNumChildren() != 0) { + OS << " " << *N.getChild(0); + for (unsigned i = 1, e = N.getNumChildren(); i != e; ++i) + OS << ", " << *N.getChild(i); } return OS << ")"; } @@ -133,13 +133,15 @@ // Check to see if we have a top-level (set) of a register. if (Tree->getOperator()->getName() == "set") { - assert(Tree->getChildren().size() == 2 && "Set with != 2 arguments?"); + assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?"); if (!Tree->getChild(0)->isLeaf()) error("Arg #0 of set should be a register or register class!"); Result = Tree->getChild(0)->getValueRecord(); Tree = Tree->getChild(1); } } + + calculateArgs(Tree, ""); } void Pattern::error(const std::string &Msg) const { @@ -152,6 +154,19 @@ throw M + TheRecord->getName() + ": " + Msg; } +/// calculateArgs - Compute the list of all of the arguments to this pattern, +/// which are the non-void leaf nodes in this pattern. +/// +void Pattern::calculateArgs(TreePatternNode *N, const std::string &Name) { + if (N->isLeaf() || N->getNumChildren() == 0) { + if (N->getType() != MVT::isVoid) + Args.push_back(std::make_pair(N, Name)); + } else { + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) + calculateArgs(N->getChild(i), N->getChildName(i)); + } +} + /// getIntrinsicType - Check to see if the specified record has an intrinsic /// type which should be applied to it. This infer the type of register /// references from the register file information, for example. @@ -199,12 +214,13 @@ if (!ISE.getNodeTypes().count(Operator)) error("Unrecognized node '" + Operator->getName() + "'!"); - std::vector Children; + std::vector > Children; for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { Init *Arg = Dag->getArg(i); if (DagInit *DI = dynamic_cast(Arg)) { - Children.push_back(ParseTreePattern(DI)); + Children.push_back(std::make_pair(ParseTreePattern(DI), + Dag->getArgName(i))); } else if (DefInit *DefI = dynamic_cast(Arg)) { Record *R = DefI->getDef(); // Direct reference to a leaf DagNode? Turn it into a DagNode if its own. @@ -213,9 +229,10 @@ std::vector >())); --i; // Revisit this node... } else { - Children.push_back(new TreePatternNode(DefI)); + Children.push_back(std::make_pair(new TreePatternNode(DefI), + Dag->getArgName(i))); // If it's a regclass or something else known, set the type. - Children.back()->setType(getIntrinsicType(R)); + Children.back().first->setType(getIntrinsicType(R)); } } else { Arg->dump(); @@ -248,17 +265,16 @@ // Check to see if we can infer anything about the argument types from the // return types... - const std::vector &Children = N->getChildren(); - if (Children.size() != NT.ArgTypes.size()) + if (N->getNumChildren() != NT.ArgTypes.size()) error("Incorrect number of children for " + Operator->getName() + " node!"); - for (unsigned i = 0, e = Children.size(); i != e; ++i) { - TreePatternNode *Child = Children[i]; + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); AnyUnset |= InferTypes(Child, MadeChange); switch (NT.ArgTypes[i]) { case NodeType::Arg0: - MadeChange |= Child->updateNodeType(Children[0]->getType(), + MadeChange |= Child->updateNodeType(N->getChild(0)->getType(), TheRecord->getName()); break; case NodeType::Val: @@ -279,7 +295,7 @@ MadeChange |= N->updateNodeType(MVT::isVoid, TheRecord->getName()); break; case NodeType::Arg0: - MadeChange |= N->updateNodeType(Children[0]->getType(), + MadeChange |= N->updateNodeType(N->getChild(0)->getType(), TheRecord->getName()); break; @@ -647,10 +663,9 @@ OS << "\n" << Indent << "// Operand matching costs...\n"; std::set ComputedValues; // Avoid duplicate computations... for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { - const std::vector &Children = - Patterns[i].second->getChildren(); - for (unsigned c = 0, e = Children.size(); c != e; ++c) { - TreePatternNode *N = Children[c]; + TreePatternNode *NParent = Patterns[i].second; + for (unsigned c = 0, e = NParent->getNumChildren(); c != e; ++c) { + TreePatternNode *N = NParent->getChild(c); if (N->isLeaf()) { Record *VR = N->getValueRecord(); const std::string &LeafName = VR->getName(); @@ -820,6 +835,60 @@ } } +/// PrintExpanderOperand - Print out Arg as part of the instruction emission +/// process for the expander pattern P. This argument may be referencing some +/// values defined in P, or may just be physical register references or +/// something like that. If PrintArg is true, we are printing out arguments to +/// the BuildMI call. If it is false, we are printing the result register +/// name. +void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg, + const std::string &NameVar, + Record *ArgDecl, + Pattern *P, bool PrintArg, + std::ostream &OS) { + if (DefInit *DI = dynamic_cast(Arg)) { + Record *Arg = DI->getDef(); + if (Arg->isSubClassOf("Register")) { + // This is a physical register reference... make sure that the instruction + // requested a register! + if (!ArgDecl->isSubClassOf("RegisterClass")) + P->error("Argument mismatch for instruction pattern!"); + + // FIXME: This should check to see if the register is in the specified + // register class! + if (PrintArg) OS << ".addReg("; + OS << getQualifiedName(Arg); + if (PrintArg) OS << ")"; + return; + } else if (Arg->isSubClassOf("RegisterClass")) { + // If this is a symbolic register class reference, we must be using a + // named value. + if (NameVar.empty()) P->error("Did not specify WHICH register to pass!"); + if (Arg != ArgDecl) P->error("Instruction pattern mismatch!"); + + if (PrintArg) OS << ".addReg("; + OS << NameVar; + if (PrintArg) OS << ")"; + return; + } + P->error("Unknown operand type '" + Arg->getName() + "' to expander!"); + } + P->error("Unknown operand type to expander!"); +} + +static std::string getArgName(Pattern *P, const std::string &ArgName, + const std::vector > &Operands) { + assert(P->getNumArgs() == Operands.size() &&"Argument computation mismatch!"); + if (ArgName.empty()) return ""; + + for (unsigned i = 0, e = P->getNumArgs(); i != e; ++i) + if (P->getArgName(i) == ArgName) + return Operands[i].second + "->Val"; + P->error("Pattern does not define a value named $" + ArgName + "!"); + return ""; +} + + void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. ReadNodeTypes(); @@ -1074,6 +1143,7 @@ // pattern that this is... switch (P->getPatternType()) { case Pattern::Instruction: + // Instruction patterns just emit a single MachineInstr, using BuildMI OS << " BuildMI(MBB, " << Target.getName() << "::" << P->getRecord()->getName() << ", " << Operands.size(); if (P->getResult()) OS << ", NewReg"; @@ -1089,10 +1159,49 @@ OS << ".addZImm(" << Operands[i].second << "->Val)"; } OS << ";\n"; - break; - case Pattern::Expander: + case Pattern::Expander: { + // Expander patterns emit one machine instr for each instruction in + // the list of instructions expanded to. + ListInit *Insts = P->getRecord()->getValueAsListInit("Result"); + for (unsigned IN = 0, e = Insts->getSize(); IN != e; ++IN) { + DagInit *DIInst = dynamic_cast(Insts->getElement(IN)); + if (!DIInst) P->error("Result list must contain instructions!"); + Pattern *InstPat = getPattern(DIInst->getNodeType()); + if (!InstPat || InstPat->getPatternType() != Pattern::Instruction) + P->error("Instruction list must contain Instruction patterns!"); + + bool hasResult = InstPat->getResult() != 0; + if (InstPat->getNumArgs() != DIInst->getNumArgs()-hasResult) { + P->error("Incorrect number of arguments specified for inst '" + + InstPat->getRecord()->getName() + "' in result list!"); + } + + // Start emission of the instruction... + OS << " BuildMI(MBB, " << Target.getName() << "::" + << InstPat->getRecord()->getName() << ", " + << DIInst->getNumArgs()-hasResult; + // Emit register result if necessary.. + if (Record *R = InstPat->getResult()) { + std::string ArgNameVal = + getArgName(P, DIInst->getArgName(0), Operands); + PrintExpanderOperand(DIInst->getArg(0), ArgNameVal, + R, P, false, OS << ", "); + } + OS << ")"; + + for (unsigned i = hasResult, e = DIInst->getNumArgs(); i != e; ++i){ + std::string ArgNameVal = + getArgName(P, DIInst->getArgName(i), Operands); + + PrintExpanderOperand(DIInst->getArg(i), ArgNameVal, + InstPat->getArgRec(i-hasResult), P, true, OS); + } + + OS << ";\n"; + } break; + } default: assert(0 && "Reduction of this type of pattern not implemented!"); } Index: llvm/utils/TableGen/InstrSelectorEmitter.h diff -u llvm/utils/TableGen/InstrSelectorEmitter.h:1.13 llvm/utils/TableGen/InstrSelectorEmitter.h:1.14 --- llvm/utils/TableGen/InstrSelectorEmitter.h:1.13 Sun Aug 10 14:50:51 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.h Sun Aug 10 18:51:52 2003 @@ -57,13 +57,14 @@ /// Children - If this is not a leaf (Operator != 0), this is the subtrees /// that we contain. - std::vector Children; + std::vector > Children; /// Value - If this node is a leaf, this indicates what the thing is. /// Init *Value; public: - TreePatternNode(Record *o, const std::vector &c) + TreePatternNode(Record *o, const std::vector > &c) : Operator(o), Type(MVT::Other), Children(c), Value(0) {} TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {} @@ -76,14 +77,16 @@ bool isLeaf() const { return Operator == 0; } - const std::vector &getChildren() const { - assert(Operator != 0 && "This is a leaf node!"); - return Children; - } unsigned getNumChildren() const { return Children.size(); } TreePatternNode *getChild(unsigned c) const { + assert(Operator != 0 && "This is a leaf node!"); assert(c < Children.size() && "Child access out of range!"); - return getChildren()[c]; + return Children[c].first; + } + const std::string &getChildName(unsigned c) const { + assert(Operator != 0 && "This is a leaf node!"); + assert(c < Children.size() && "Child access out of range!"); + return Children[c].second; } Init *getValue() const { @@ -151,6 +154,10 @@ /// bool Resolved; + /// Args - This is a list of all of the arguments to this pattern, which are + /// the non-void leaf nodes in this pattern. + std::vector > Args; + /// ISE - the instruction selector emitter coordinating this madness. /// InstrSelectorEmitter &ISE; @@ -164,7 +171,9 @@ /// Pattern - Constructor used for cloning nonterminal patterns Pattern(TreePatternNode *tree, Record *rec, bool res, InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0), - TheRecord(rec), Resolved(res), ISE(ise){} + TheRecord(rec), Resolved(res), ISE(ise) { + calculateArgs(Tree, ""); + } /// getPatternType - Return what flavor of Record this pattern originated from /// @@ -181,6 +190,19 @@ /// Record *getRecord() const { return TheRecord; } + unsigned getNumArgs() const { return Args.size(); } + TreePatternNode *getArg(unsigned i) const { + assert(i < Args.size() && "Argument reference out of range!"); + return Args[i].first; + } + Record *getArgRec(unsigned i) const { + return getArg(i)->getValueRecord(); + } + const std::string &getArgName(unsigned i) const { + assert(i < Args.size() && "Argument reference out of range!"); + return Args[i].second; + } + bool isResolved() const { return Resolved; } /// InferAllTypes - Runs the type inference engine on the current pattern, @@ -211,6 +233,7 @@ void dump() const; private: + void calculateArgs(TreePatternNode *N, const std::string &Name); MVT::ValueType getIntrinsicType(Record *R) const; TreePatternNode *ParseTreePattern(DagInit *DI); bool InferTypes(TreePatternNode *N, bool &MadeChange); @@ -338,6 +361,16 @@ void EmitMatchCosters(std::ostream &OS, const std::vector > &Patterns, const std::string &VarPrefix, unsigned Indent); + + /// PrintExpanderOperand - Print out Arg as part of the instruction emission + /// process for the expander pattern P. This argument may be referencing some + /// values defined in P, or may just be physical register references or + /// something like that. If PrintArg is true, we are printing out arguments + /// to the BuildMI call. If it is false, we are printing the result register + /// name. + void PrintExpanderOperand(Init *Arg, const std::string &NameVar, + Record *ArgDecl, Pattern *P, + bool PrintArg, std::ostream &OS); }; #endif From lattner at cs.uiuc.edu Sun Aug 10 18:58:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 18:58:03 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/InstrSelectorEmitter.cpp Record.h Message-ID: <200308102239.RAA14276@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: InstrSelectorEmitter.cpp updated: 1.19 -> 1.20 Record.h updated: 1.35 -> 1.36 --- Log message: Implement autopromotion of leaf trees from arguments to nodes of their own, making it easier to write patterns without lots of extraneous parens --- Diffs of the changes: Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.19 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.20 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.19 Sun Aug 10 17:14:13 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Sun Aug 10 17:38:36 2003 @@ -167,19 +167,20 @@ return MVT::Other; } - throw "Error: Unknown value used: " + R->getName(); + error("Unknown value used: " + R->getName()); + return MVT::Other; } -TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) { - Record *Operator = DI->getNodeType(); +TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) { + Record *Operator = Dag->getNodeType(); if (Operator->isSubClassOf("ValueType")) { // If the operator is a ValueType, then this must be "type cast" of a leaf // node. - if (DI->getNumArgs() != 1) + if (Dag->getNumArgs() != 1) error("Type cast only valid for a leaf node!"); - Init *Arg = DI->getArg(0); + Init *Arg = Dag->getArg(0); TreePatternNode *New; if (DefInit *DI = dynamic_cast(Arg)) { New = new TreePatternNode(DI); @@ -200,14 +201,22 @@ std::vector Children; - for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { - Init *Arg = DI->getArg(i); + for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { + Init *Arg = Dag->getArg(i); if (DagInit *DI = dynamic_cast(Arg)) { Children.push_back(ParseTreePattern(DI)); - } else if (DefInit *DI = dynamic_cast(Arg)) { - Children.push_back(new TreePatternNode(DI)); - // If it's a regclass or something else known, set the type. - Children.back()->setType(getIntrinsicType(DI->getDef())); + } else if (DefInit *DefI = dynamic_cast(Arg)) { + Record *R = DefI->getDef(); + // Direct reference to a leaf DagNode? Turn it into a DagNode if its own. + if (R->isSubClassOf("DagNode")) { + Dag->setArg(i, new DagInit(R, + std::vector >())); + --i; // Revisit this node... + } else { + Children.push_back(new TreePatternNode(DefI)); + // If it's a regclass or something else known, set the type. + Children.back()->setType(getIntrinsicType(R)); + } } else { Arg->dump(); error("Unknown leaf value for tree pattern!"); @@ -524,8 +533,15 @@ // Loop over all of the patterns, adding them to the ComputableValues map for (std::map::iterator I = Patterns.begin(), E = Patterns.end(); I != E; ++I) - if (I->second->isResolved()) - ComputableValues.addPattern(I->second); + if (I->second->isResolved()) { + // We don't want to add patterns like R32 = R32. This is a hack working + // around a special case of a general problem, but for now we explicitly + // forbid these patterns. They can never match anyway. + Pattern *P = I->second; + if (!P->getResult() || !P->getTree()->isLeaf() || + P->getResult() != P->getTree()->getValueRecord()) + ComputableValues.addPattern(P); + } } #if 0 Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.35 llvm/utils/TableGen/Record.h:1.36 --- llvm/utils/TableGen/Record.h:1.35 Sun Aug 10 17:14:13 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 10 17:38:36 2003 @@ -619,6 +619,11 @@ return ArgNames[Num]; } + void setArg(unsigned Num, Init *I) { + assert(Num < Args.size() && "Arg number out of range!"); + Args[Num] = I; + } + virtual void print(std::ostream &OS) const; }; From lattner at cs.uiuc.edu Sun Aug 10 18:59:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 18:59:00 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l FileParser.y Message-ID: <200308102204.RAA06638@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.11 -> 1.12 FileParser.y updated: 1.20 -> 1.21 --- Log message: Recognize $foo as a variable --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.11 llvm/utils/TableGen/FileLexer.l:1.12 --- llvm/utils/TableGen/FileLexer.l:1.11 Mon Aug 4 15:08:28 2003 +++ llvm/utils/TableGen/FileLexer.l Sun Aug 10 17:04:25 2003 @@ -166,6 +166,8 @@ {Identifier} { Filelval.StrVal = new std::string(yytext, yytext+yyleng); return ID; } +${Identifier} { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng); + return VARNAME; } {StringVal} { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1); return STRVAL; } Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.20 llvm/utils/TableGen/FileParser.y:1.21 --- llvm/utils/TableGen/FileParser.y:1.20 Mon Aug 4 15:44:43 2003 +++ llvm/utils/TableGen/FileParser.y Sun Aug 10 17:04:25 2003 @@ -171,7 +171,7 @@ %token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN %token INTVAL -%token ID STRVAL CODEFRAGMENT +%token ID VARNAME STRVAL CODEFRAGMENT %type Type %type ClassInst DefInst Object ObjectBody ClassID From lattner at cs.uiuc.edu Sun Aug 10 18:59:14 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 10 18:59:14 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y InstrSelectorEmitter.cpp Record.cpp Record.h Message-ID: <200308102214.RAA11026@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.21 -> 1.22 InstrSelectorEmitter.cpp updated: 1.18 -> 1.19 Record.cpp updated: 1.27 -> 1.28 Record.h updated: 1.34 -> 1.35 --- Log message: Implement correct parsing, representation, and printing of DAG argument names Implements testcase TableGen/TreeNames.td --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.21 llvm/utils/TableGen/FileParser.y:1.22 --- llvm/utils/TableGen/FileParser.y:1.21 Sun Aug 10 17:04:25 2003 +++ llvm/utils/TableGen/FileParser.y Sun Aug 10 17:14:13 2003 @@ -161,12 +161,12 @@ int IntVal; RecTy *Ty; Init *Initializer; - std::vector *DagValueList; std::vector *FieldList; std::vector*BitList; Record *Rec; SubClassRefTy *SubClassRef; std::vector *SubClassList; + std::vector > *DagValueList; }; %token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN @@ -183,7 +183,7 @@ %type DagArgList DagArgListNE %type ValueList ValueListNE %type BitList OptBitList RBitList -%type Declaration OptID +%type Declaration OptID OptVarName %start File %% @@ -282,16 +282,26 @@ delete $2; delete $3; }; -DagArgListNE : Value { - $$ = new std::vector(); - $$->push_back($1); +OptVarName : /* empty */ { + $$ = new std::string(); } - | DagArgListNE ',' Value { - $1->push_back($3); + | ':' VARNAME { + $$ = $2; + }; + +DagArgListNE : Value OptVarName { + $$ = new std::vector >(); + $$->push_back(std::make_pair($1, *$2)); + delete $2; + } + | DagArgListNE ',' Value OptVarName { + $1->push_back(std::make_pair($3, *$4)); + delete $4; + $$ = $1; }; DagArgList : /*empty*/ { - $$ = new std::vector(); + $$ = new std::vector >(); } | DagArgListNE { $$ = $1; }; Index: llvm/utils/TableGen/InstrSelectorEmitter.cpp diff -u llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.18 llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.19 --- llvm/utils/TableGen/InstrSelectorEmitter.cpp:1.18 Sun Aug 10 16:54:43 2003 +++ llvm/utils/TableGen/InstrSelectorEmitter.cpp Sun Aug 10 17:14:13 2003 @@ -172,15 +172,14 @@ TreePatternNode *Pattern::ParseTreePattern(DagInit *DI) { Record *Operator = DI->getNodeType(); - const std::vector &Args = DI->getArgs(); if (Operator->isSubClassOf("ValueType")) { // If the operator is a ValueType, then this must be "type cast" of a leaf // node. - if (Args.size() != 1) + if (DI->getNumArgs() != 1) error("Type cast only valid for a leaf node!"); - Init *Arg = Args[0]; + Init *Arg = DI->getArg(0); TreePatternNode *New; if (DefInit *DI = dynamic_cast(Arg)) { New = new TreePatternNode(DI); @@ -201,8 +200,8 @@ std::vector Children; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - Init *Arg = Args[i]; + for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { + Init *Arg = DI->getArg(i); if (DagInit *DI = dynamic_cast(Arg)) { Children.push_back(ParseTreePattern(DI)); } else if (DefInit *DI = dynamic_cast(Arg)) { Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.27 llvm/utils/TableGen/Record.cpp:1.28 --- llvm/utils/TableGen/Record.cpp:1.27 Thu Aug 7 01:00:43 2003 +++ llvm/utils/TableGen/Record.cpp Sun Aug 10 17:14:13 2003 @@ -438,8 +438,11 @@ OS << "(" << NodeTypeDef->getName(); if (Args.size()) { OS << " " << *Args[0]; - for (unsigned i = 1, e = Args.size(); i != e; ++i) + if (!ArgNames[0].empty()) OS << ":$" << ArgNames[0]; + for (unsigned i = 1, e = Args.size(); i != e; ++i) { OS << ", " << *Args[i]; + if (!ArgNames[i].empty()) OS << ":$" << ArgNames[i]; + } } OS << ")"; } Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.34 llvm/utils/TableGen/Record.h:1.35 --- llvm/utils/TableGen/Record.h:1.34 Thu Aug 7 14:41:59 2003 +++ llvm/utils/TableGen/Record.h Sun Aug 10 17:14:13 2003 @@ -591,9 +591,16 @@ class DagInit : public Init { Record *NodeTypeDef; std::vector Args; + std::vector ArgNames; public: - DagInit(Record *D, std::vector &a) : NodeTypeDef(D) { - Args.swap(a); // DESTRUCTIVELY take the arguments + DagInit(Record *D, const std::vector > &args) + : NodeTypeDef(D) { + Args.reserve(args.size()); + ArgNames.reserve(args.size()); + for (unsigned i = 0, e = args.size(); i != e; ++i) { + Args.push_back(args[i].first); + ArgNames.push_back(args[i].second); + } } virtual Init *convertInitializerTo(RecTy *Ty) { @@ -601,7 +608,16 @@ } Record *getNodeType() const { return NodeTypeDef; } - const std::vector &getArgs() const { return Args; } + + unsigned getNumArgs() const { return Args.size(); } + Init *getArg(unsigned Num) const { + assert(Num < Args.size() && "Arg number out of range!"); + return Args[Num]; + } + const std::string &getArgName(unsigned Num) const { + assert(Num < ArgNames.size() && "Arg number out of range!"); + return ArgNames[Num]; + } virtual void print(std::ostream &OS) const; };