From evan.cheng at apple.com Mon Mar 6 00:09:08 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 6 Mar 2006 00:09:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603060609.AAA05994@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.16 -> 1.17 --- Log message: Remove SUnit::Priority1: it is re-calculated on demand as number of live range to be generated. --- Diffs of the changes: (+25 -35) ScheduleDAGList.cpp | 60 +++++++++++++++++++++------------------------------- 1 files changed, 25 insertions(+), 35 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.16 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.17 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.16 Sun Mar 5 18:22:00 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Mar 6 00:08:54 2006 @@ -44,8 +44,7 @@ int NumSuccsLeft; // # of succs not scheduled. int NumChainPredsLeft; // # of chain preds not scheduled. int NumChainSuccsLeft; // # of chain succs not scheduled. - int Priority1; // Scheduling priority 1. - int Priority2; // Scheduling priority 2. + int SethiUllman; // Sethi Ullman number. bool isTwoAddress; // Is a two-address instruction. bool isDefNUseOperand; // Is a def&use operand. unsigned Latency; // Node latency. @@ -56,7 +55,7 @@ SUnit(SDNode *node) : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), - Priority1(INT_MIN), Priority2(INT_MIN), + SethiUllman(INT_MIN), isTwoAddress(false), isDefNUseOperand(false), Latency(0), CycleBound(0), Slot(0), Next(NULL) {} @@ -81,8 +80,7 @@ std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n"; std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n"; std::cerr << " Latency : " << Latency << "\n"; - std::cerr << " Priority : " << Priority1 << " , " - << Priority2 << "\n"; + std::cerr << " SethiUllman : " << SethiUllman << "\n"; if (Preds.size() != 0) { std::cerr << " Predecessors:\n"; @@ -140,10 +138,11 @@ RBonus++; } - int LPriority1 = left ->Priority1 - LBonus; - int RPriority1 = right->Priority1 - RBonus; - int LPriority2 = left ->Priority2 + LBonus; - int RPriority2 = right->Priority2 + RBonus; + // Priority1 is just the number of live range genned. + int LPriority1 = left ->NumPredsLeft - LBonus; + int RPriority1 = right->NumPredsLeft - RBonus; + int LPriority2 = left ->SethiUllman + LBonus; + int RPriority2 = right->SethiUllman + RBonus; // Favor floaters (i.e. node with no non-passive predecessors): // e.g. MOV32ri. @@ -155,7 +154,7 @@ else if (LPriority1 == RPriority1) if (LPriority2 < RPriority2) return true; - else if (LPriority1 == RPriority1) + else if (LPriority2 == RPriority2) if (left->CycleBound > right->CycleBound) return true; @@ -249,10 +248,9 @@ // interrupt model (drain vs. freeze). PredSU->CycleBound = std::max(PredSU->CycleBound, CurrCycle + PredSU->Latency); - if (!isChain) { + if (!isChain) PredSU->NumSuccsLeft--; - PredSU->Priority1++; - } else + else PredSU->NumChainSuccsLeft--; #ifndef NDEBUG @@ -281,10 +279,9 @@ // interrupt model (drain vs. freeze). SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurrCycle + SuccSU->Latency); - if (!isChain) { + if (!isChain) SuccSU->NumPredsLeft--; - SuccSU->Priority1++; // FIXME: ?? - } else + else SuccSU->NumChainPredsLeft--; #ifndef NDEBUG @@ -316,7 +313,6 @@ E1 = SU->Preds.end(); I1 != E1; ++I1) { ReleasePred(Available, *I1); SU->NumPredsLeft--; - SU->Priority1--; } for (std::set::iterator I2 = SU->ChainPreds.begin(), E2 = SU->ChainPreds.end(); I2 != E2; ++I2) @@ -341,7 +337,6 @@ E1 = SU->Succs.end(); I1 != E1; ++I1) { ReleaseSucc(Available, *I1); SU->NumSuccsLeft--; - SU->Priority1--; // FIXME: what is this?? } for (std::set::iterator I2 = SU->ChainSuccs.begin(), E2 = SU->ChainSuccs.end(); I2 != E2; ++I2) @@ -501,39 +496,34 @@ } -/// CalcNodePriority - Priority1 is just the number of live range genned - -/// number of live range killed. Priority2 is the Sethi Ullman number. It -/// returns Priority2 since it is calculated recursively. -/// Smaller number is the higher priority for Priority2. Reverse is true for -/// Priority1. +/// CalcNodePriority - Priority is the Sethi Ullman number. +/// Smaller number is the higher priority. int ScheduleDAGList::CalcNodePriority(SUnit *SU) { - if (SU->Priority2 != INT_MIN) - return SU->Priority2; - - SU->Priority1 = SU->NumPredsLeft - SU->NumSuccsLeft; + if (SU->SethiUllman != INT_MIN) + return SU->SethiUllman; if (SU->Preds.size() == 0) { - SU->Priority2 = 1; + SU->SethiUllman = 1; } else { int Extra = 0; for (std::set::iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { SUnit *PredSU = *I; - int PredPriority = CalcNodePriority(PredSU); - if (PredPriority > SU->Priority2) { - SU->Priority2 = PredPriority; + int PredSethiUllman = CalcNodePriority(PredSU); + if (PredSethiUllman > SU->SethiUllman) { + SU->SethiUllman = PredSethiUllman; Extra = 0; - } else if (PredPriority == SU->Priority2) + } else if (PredSethiUllman == SU->SethiUllman) Extra++; } if (SU->Node->getOpcode() != ISD::TokenFactor) - SU->Priority2 += Extra; + SU->SethiUllman += Extra; else - SU->Priority2 = (Extra == 1) ? 0 : Extra-1; + SU->SethiUllman = (Extra == 1) ? 0 : Extra-1; } - return SU->Priority2; + return SU->SethiUllman; } /// CalculatePriorities - Calculate priorities of all scheduling units. From reid at x10sys.com Mon Mar 6 00:38:32 2006 From: reid at x10sys.com (Reid Spencer) Date: Mon, 6 Mar 2006 00:38:32 -0600 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.cpp Message-ID: <200603060638.AAA06109@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.cpp updated: 1.29 -> 1.30 --- Log message: Make sure command line options are parsed before we try to add the LibPath (-L options) to TheLinker. Problem noticed by Wink Saville. --- Diffs of the changes: (+4 -4) llvm-ld.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.29 llvm/tools/llvm-ld/llvm-ld.cpp:1.30 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.29 Mon Jan 9 21:14:40 2006 +++ llvm/tools/llvm-ld/llvm-ld.cpp Mon Mar 6 00:38:19 2006 @@ -406,14 +406,14 @@ progname = sys::Path(argv[0]).getBasename(); Linker TheLinker(progname, OutputFilename, Verbose); - // Set up the library paths for the Linker - TheLinker.addPaths(LibPaths); - TheLinker.addSystemPaths(); - // Parse the command line options cl::ParseCommandLineOptions(argc, argv, " llvm linker\n"); sys::PrintStackTraceOnErrorSignal(); + // Set up the library paths for the Linker + TheLinker.addPaths(LibPaths); + TheLinker.addSystemPaths(); + // Remove any consecutive duplicates of the same library... Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), Libraries.end()); From evan.cheng at apple.com Mon Mar 6 01:31:57 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 6 Mar 2006 01:31:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603060731.BAA06442@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.17 -> 1.18 --- Log message: Remove some code that doesn't make sense --- Diffs of the changes: (+5 -12) ScheduleDAGList.cpp | 17 +++++------------ 1 files changed, 5 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.17 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.18 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.17 Mon Mar 6 00:08:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Mar 6 01:31:44 2006 @@ -120,8 +120,6 @@ /// Sorting functions for the Available queue. struct ls_rr_sort : public std::binary_function { bool operator()(const SUnit* left, const SUnit* right) const { - bool LFloater = (left ->Preds.size() == 0); - bool RFloater = (right->Preds.size() == 0); int LBonus = (int)left ->isDefNUseOperand; int RBonus = (int)right->isDefNUseOperand; @@ -144,19 +142,14 @@ int LPriority2 = left ->SethiUllman + LBonus; int RPriority2 = right->SethiUllman + RBonus; - // Favor floaters (i.e. node with no non-passive predecessors): - // e.g. MOV32ri. - if (!LFloater && RFloater) + if (LPriority1 > RPriority1) return true; - else if (LFloater == RFloater) - if (LPriority1 > RPriority1) + else if (LPriority1 == RPriority1) + if (LPriority2 < RPriority2) return true; - else if (LPriority1 == RPriority1) - if (LPriority2 < RPriority2) + else if (LPriority2 == RPriority2) + if (left->CycleBound > right->CycleBound) return true; - else if (LPriority2 == RPriority2) - if (left->CycleBound > right->CycleBound) - return true; return false; } From lattner at cs.uiuc.edu Mon Mar 6 11:58:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 11:58:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603061758.LAA15476@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.18 -> 1.19 --- Log message: update file comment --- Diffs of the changes: (+8 -3) ScheduleDAGList.cpp | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.18 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.19 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.18 Mon Mar 6 01:31:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Mar 6 11:58:04 2006 @@ -7,9 +7,14 @@ // //===----------------------------------------------------------------------===// // -// This implements a simple two pass scheduler. The first pass attempts to push -// backward any lengthy instructions and critical paths. The second pass packs -// instructions into semi-optimal time slots. +// This implements bottom-up and top-down list schedulers, using standard +// algorithms. The basic approach uses a priority queue of available nodes to +// schedule. One at a time, nodes are taken from the priority queue (thus in +// priority order), checked for legality to schedule, and emitted if legal. +// +// Nodes may not be legal to schedule either due to structural hazards (e.g. +// pipeline or resource constraints) or because an input to the instruction has +// not completed execution. // //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Mon Mar 6 12:09:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 12:09:51 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Applications/JM/ldecod/Makefile Message-ID: <200603061809.MAA15646@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Applications/JM/ldecod: Makefile updated: 1.1 -> 1.2 --- Log message: fix objdir != srcdir testing --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/MultiSource/Applications/JM/ldecod/Makefile diff -u llvm-test/MultiSource/Applications/JM/ldecod/Makefile:1.1 llvm-test/MultiSource/Applications/JM/ldecod/Makefile:1.2 --- llvm-test/MultiSource/Applications/JM/ldecod/Makefile:1.1 Sat Feb 11 04:33:22 2006 +++ llvm-test/MultiSource/Applications/JM/ldecod/Makefile Mon Mar 6 12:09:38 2006 @@ -3,6 +3,6 @@ CPPFLAGS = -D __USE_LARGEFILE64 -D _FILE_OFFSET_BITS=64 LDFLAGS = -lm $(TOOLLINKOPTS) -RUN_OPTIONS = -i data/test.264 -o data/test_dec.yuv -r data/test_rec.yuv +RUN_OPTIONS = -i $(PROJ_SRC_DIR)/data/test.264 -o $(PROJ_SRC_DIR)/data/test_dec.yuv -r $(PROJ_SRC_DIR)/data/test_rec.yuv include ../../../Makefile.multisrc From evan.cheng at apple.com Mon Mar 6 13:53:23 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 6 Mar 2006 13:53:23 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CFP2000/177.mesa/Makefile Message-ID: <200603061953.NAA16123@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CFP2000/177.mesa: Makefile updated: 1.7 -> 1.8 --- Log message: Increase default problem size to something reasonable. --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/External/SPEC/CFP2000/177.mesa/Makefile diff -u llvm-test/External/SPEC/CFP2000/177.mesa/Makefile:1.7 llvm-test/External/SPEC/CFP2000/177.mesa/Makefile:1.8 --- llvm-test/External/SPEC/CFP2000/177.mesa/Makefile:1.7 Mon Sep 6 22:37:34 2004 +++ llvm-test/External/SPEC/CFP2000/177.mesa/Makefile Mon Mar 6 13:53:11 2006 @@ -4,7 +4,7 @@ ifdef LARGE_PROBLEM_SIZE RUN_OPTIONS := -frames 500 else -RUN_OPTIONS := -frames 10 +RUN_OPTIONS := -frames 100 endif RUN_OPTIONS += -meshfile mesa.in -ppmfile mesa.ppm From evan.cheng at apple.com Mon Mar 6 13:59:15 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 6 Mar 2006 13:59:15 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CFP2000/179.art/Makefile Message-ID: <200603061959.NAA16148@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CFP2000/179.art: Makefile updated: 1.5 -> 1.6 --- Log message: Bump default problem size to something that takes ~3 sec range. --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/External/SPEC/CFP2000/179.art/Makefile diff -u llvm-test/External/SPEC/CFP2000/179.art/Makefile:1.5 llvm-test/External/SPEC/CFP2000/179.art/Makefile:1.6 --- llvm-test/External/SPEC/CFP2000/179.art/Makefile:1.5 Mon Sep 6 22:41:14 2004 +++ llvm-test/External/SPEC/CFP2000/179.art/Makefile Mon Mar 6 13:59:04 2006 @@ -3,7 +3,7 @@ ifdef LARGE_PROBLEM_SIZE RUN_OPTIONS = -scanfile c756hel.in -trainfile1 a10.img -stride 2 -startx 134 -starty 220 -endx 184 -endy 240 -objects 3 else -RUN_OPTIONS = -scanfile c756hel.in -trainfile1 a10.img -stride 2 -startx 134 -starty 220 -endx 139 -endy 225 -objects 1 +RUN_OPTIONS = -scanfile c756hel.in -trainfile1 a10.img -stride 2 -startx 134 -starty 220 -endx 154 -endy 230 -objects 3 endif #STDIN_FILENAME = $(RUN_TYPE).in From lattner at cs.uiuc.edu Mon Mar 6 14:18:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 14:18:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200603062018.OAA16284@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.449 -> 1.450 --- Log message: Teach instcombine to increase the alignment of memset/memcpy/memmove when the pointer is known to come from either a global variable, alloca or malloc. This allows us to compile this: P = malloc(28); memset(P, 0, 28); into explicit stores on PPC instead of a memset call. --- Diffs of the changes: (+74 -3) InstructionCombining.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 74 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.449 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.450 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.449 Sat Mar 4 18:22:33 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 6 14:18:44 2006 @@ -5264,6 +5264,60 @@ return 0; } +/// GetKnownAlignment - If the specified pointer has an alignment that we can +/// determine, return it, otherwise return 0. +static unsigned GetKnownAlignment(Value *V, TargetData *TD) { + if (GlobalVariable *GV = dyn_cast(V)) { + unsigned Align = GV->getAlignment(); + if (Align == 0 && TD) + Align = TD->getTypeAlignment(GV->getType()->getElementType()); + return Align; + } else if (AllocationInst *AI = dyn_cast(V)) { + unsigned Align = AI->getAlignment(); + if (Align == 0 && TD) { + if (isa(AI)) + Align = TD->getTypeAlignment(AI->getType()->getElementType()); + else if (isa(AI)) { + // Malloc returns maximally aligned memory. + Align = TD->getTypeAlignment(AI->getType()->getElementType()); + Align = std::max(Align, (unsigned)TD->getTypeAlignment(Type::DoubleTy)); + Align = std::max(Align, (unsigned)TD->getTypeAlignment(Type::LongTy)); + } + } + return Align; + } else if (CastInst *CI = dyn_cast(V)) { + if (isa(CI->getOperand(0)->getType())) + return GetKnownAlignment(CI->getOperand(0), TD); + return 0; + } else if (GetElementPtrInst *GEPI = dyn_cast(V)) { + unsigned BaseAlignment = GetKnownAlignment(GEPI->getOperand(0), TD); + if (BaseAlignment == 0) return 0; + + // If all indexes are zero, it is just the alignment of the base pointer. + bool AllZeroOperands = true; + for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i) + if (!isa(GEPI->getOperand(i)) || + !cast(GEPI->getOperand(i))->isNullValue()) { + AllZeroOperands = false; + break; + } + if (AllZeroOperands) + return BaseAlignment; + + // Otherwise, if the base alignment is >= the alignment we expect for the + // base pointer type, then we know that the resultant pointer is aligned at + // least as much as its type requires. + if (!TD) return 0; + + const Type *BasePtrTy = GEPI->getOperand(0)->getType(); + if (TD->getTypeAlignment(cast(BasePtrTy)->getElementType()) + <= BaseAlignment) + return TD->getTypeAlignment(GEPI->getType()->getElementType()); + return 0; + } + return 0; +} + /// visitCallInst - CallInst simplification. This mostly only handles folding /// of intrinsic instructions. For normal calls, it allows visitCallSite to do @@ -5282,8 +5336,6 @@ if (Constant *NumBytes = dyn_cast(MI->getLength())) { if (NumBytes->isNullValue()) return EraseInstFromFunction(CI); - // FIXME: Increase alignment here. - if (ConstantInt *CI = dyn_cast(NumBytes)) if (CI->getRawValue() == 1) { // Replace the instruction with just byte operations. We would @@ -5295,7 +5347,7 @@ // If we have a memmove and the source operation is a constant global, // then the source and dest pointers can't alias, so we can change this // into a call to memcpy. - if (MemMoveInst *MMI = dyn_cast(II)) + if (MemMoveInst *MMI = dyn_cast(II)) { if (GlobalVariable *GVSrc = dyn_cast(MMI->getSource())) if (GVSrc->isConstant()) { Module *M = CI.getParent()->getParent()->getParent(); @@ -5310,7 +5362,26 @@ CI.setOperand(0, MemCpy); Changed = true; } + } + // If we can determine a pointer alignment that is bigger than currently + // set, update the alignment. + if (isa(MI) || isa(MI)) { + unsigned Alignment1 = GetKnownAlignment(MI->getOperand(1), TD); + unsigned Alignment2 = GetKnownAlignment(MI->getOperand(2), TD); + unsigned Align = std::min(Alignment1, Alignment2); + if (MI->getAlignment()->getRawValue() < Align) { + MI->setAlignment(ConstantUInt::get(Type::UIntTy, Align)); + Changed = true; + } + } else if (isa(MI)) { + unsigned Alignment = GetKnownAlignment(MI->getDest(), TD); + if (MI->getAlignment()->getRawValue() < Alignment) { + MI->setAlignment(ConstantUInt::get(Type::UIntTy, Alignment)); + Changed = true; + } + } + if (Changed) return II; } else if (DbgStopPointInst *SPI = dyn_cast(II)) { // If this stoppoint is at the same source location as the previous From lattner at cs.uiuc.edu Mon Mar 6 14:41:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 14:41:57 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Applications/JM/ldecod/global.h Message-ID: <200603062041.OAA16536@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Applications/JM/ldecod: global.h updated: 1.1 -> 1.2 --- Log message: Don't overflow filename buffers. grr. --- Diffs of the changes: (+4 -4) global.h | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm-test/MultiSource/Applications/JM/ldecod/global.h diff -u llvm-test/MultiSource/Applications/JM/ldecod/global.h:1.1 llvm-test/MultiSource/Applications/JM/ldecod/global.h:1.2 --- llvm-test/MultiSource/Applications/JM/ldecod/global.h:1.1 Sat Feb 11 04:33:22 2006 +++ llvm-test/MultiSource/Applications/JM/ldecod/global.h Mon Mar 6 14:41:44 2006 @@ -654,9 +654,9 @@ // input parameters from configuration file struct inp_par { - char infile[100]; //!< H.264 inputfile - char outfile[100]; //!< Decoded YUV 4:2:0 output - char reffile[100]; //!< Optional YUV 4:2:0 reference file for SNR measurement + char infile[1000]; //!< H.264 inputfile + char outfile[1000]; //!< Decoded YUV 4:2:0 output + char reffile[1000]; //!< Optional YUV 4:2:0 reference file for SNR measurement int FileFormat; //!< File format of the Input file, PAR_OF_ANNEXB or PAR_OF_RTP int ref_offset; int poc_scale; @@ -666,7 +666,7 @@ unsigned long R_decoder; //!< Decoder Rate in HRD Model unsigned long B_decoder; //!< Decoder Buffer size in HRD model unsigned long F_decoder; //!< Decoder Initial buffer fullness in HRD model - char LeakyBucketParamFile[100]; //!< LeakyBucketParamFile + char LeakyBucketParamFile[1000]; //!< LeakyBucketParamFile #endif // picture error concealment From lattner at cs.uiuc.edu Mon Mar 6 17:52:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 17:52:50 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/2006-03-06-C++RecurseCrash.cpp Message-ID: <200603062352.RAA17975@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: 2006-03-06-C++RecurseCrash.cpp added (r1.1) --- Log message: new regression test --- Diffs of the changes: (+24 -0) 2006-03-06-C++RecurseCrash.cpp | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+) Index: llvm/test/Regression/C++Frontend/2006-03-06-C++RecurseCrash.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/2006-03-06-C++RecurseCrash.cpp:1.1 *** /dev/null Mon Mar 6 17:52:47 2006 --- llvm/test/Regression/C++Frontend/2006-03-06-C++RecurseCrash.cpp Mon Mar 6 17:52:37 2006 *************** *** 0 **** --- 1,24 ---- + // %llvmgcc %s -S -o - + namespace std { + class exception { }; + + class type_info { + public: + virtual ~type_info(); + }; + + } + + namespace __cxxabiv1 { + class __si_class_type_info : public std::type_info { + ~__si_class_type_info(); + }; + } + + class recursive_init: public std::exception { + public: + virtual ~recursive_init() throw (); + }; + + recursive_init::~recursive_init() throw() { } + From lattner at cs.uiuc.edu Mon Mar 6 19:29:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 19:29:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200603070129.TAA18531@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.450 -> 1.451 --- Log message: Teach the alignment handling code to look through constant expr casts and GEPs --- Diffs of the changes: (+12 -4) InstructionCombining.cpp | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.450 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.451 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.450 Mon Mar 6 14:18:44 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 6 19:28:57 2006 @@ -5285,11 +5285,17 @@ } } return Align; - } else if (CastInst *CI = dyn_cast(V)) { + } else if (isa(V) || + (isa(V) && + cast(V)->getOpcode() == Instruction::Cast)) { + User *CI = cast(V); if (isa(CI->getOperand(0)->getType())) return GetKnownAlignment(CI->getOperand(0), TD); return 0; - } else if (GetElementPtrInst *GEPI = dyn_cast(V)) { + } else if (isa(V) || + (isa(V) && + cast(V)->getOpcode()==Instruction::GetElementPtr)) { + User *GEPI = cast(V); unsigned BaseAlignment = GetKnownAlignment(GEPI->getOperand(0), TD); if (BaseAlignment == 0) return 0; @@ -5311,8 +5317,10 @@ const Type *BasePtrTy = GEPI->getOperand(0)->getType(); if (TD->getTypeAlignment(cast(BasePtrTy)->getElementType()) - <= BaseAlignment) - return TD->getTypeAlignment(GEPI->getType()->getElementType()); + <= BaseAlignment) { + const Type *GEPTy = GEPI->getType(); + return TD->getTypeAlignment(cast(GEPTy)->getElementType()); + } return 0; } return 0; From evan.cheng at apple.com Mon Mar 6 20:03:10 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 6 Mar 2006 20:03:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86ATTAsmPrinter.h X86AsmPrinter.cpp X86AsmPrinter.h X86ISelLowering.cpp X86InstrInfo.td X86IntelAsmPrinter.cpp X86IntelAsmPrinter.h Message-ID: <200603070203.UAA18780@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.28 -> 1.29 X86ATTAsmPrinter.h updated: 1.8 -> 1.9 X86AsmPrinter.cpp updated: 1.167 -> 1.168 X86AsmPrinter.h updated: 1.11 -> 1.12 X86ISelLowering.cpp updated: 1.102 -> 1.103 X86InstrInfo.td updated: 1.251 -> 1.252 X86IntelAsmPrinter.cpp updated: 1.21 -> 1.22 X86IntelAsmPrinter.h updated: 1.9 -> 1.10 --- Log message: Enable Dwarf debugging info. --- Diffs of the changes: (+83 -6) X86ATTAsmPrinter.cpp | 14 +++++++++++++- X86ATTAsmPrinter.h | 2 +- X86AsmPrinter.cpp | 6 ++++++ X86AsmPrinter.h | 38 ++++++++++++++++++++++++++++++++++++-- X86ISelLowering.cpp | 4 +++- X86InstrInfo.td | 13 +++++++++++++ X86IntelAsmPrinter.cpp | 10 ++++++++++ X86IntelAsmPrinter.h | 2 +- 8 files changed, 83 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.28 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.29 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.28 Sun Feb 26 02:28:12 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Mon Mar 6 20:02:57 2006 @@ -27,9 +27,16 @@ /// method to print assembly for each instruction. /// bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // Let PassManager know we need debug information and relay + // the MachineDebugInfo address on to DwarfWriter. + DW.SetDebugInfo(&getAnalysis()); + SetupMachineFunction(MF); O << "\n\n"; + // Emit pre-function debug information. + DW.BeginFunction(MF); + // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); @@ -81,6 +88,9 @@ if (HasDotTypeDotSizeDirective) O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; + // Emit post-function debug information. + DW.EndFunction(MF); + // We didn't modify anything. return false; } @@ -101,7 +111,9 @@ case MachineOperand::MO_SignExtendedImmed: case MachineOperand::MO_UnextendedImmed: - O << '$' << (int)MO.getImmedValue(); + if (!Modifier || strcmp(Modifier, "debug") != 0) + O << '$'; + O << (int)MO.getImmedValue(); return; case MachineOperand::MO_MachineBasicBlock: { MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); Index: llvm/lib/Target/X86/X86ATTAsmPrinter.h diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.8 llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.9 --- llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.8 Tue Feb 21 20:26:30 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.h Mon Mar 6 20:02:57 2006 @@ -21,7 +21,7 @@ namespace x86 { struct X86ATTAsmPrinter : public X86SharedAsmPrinter { - X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM) + X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM) : X86SharedAsmPrinter(O, TM) { } virtual const char *getPassName() const { Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.167 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.168 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.167 Wed Feb 22 23:25:02 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Mon Mar 6 20:02:57 2006 @@ -75,6 +75,9 @@ default: break; } + // Emit initial debug information. + DW.BeginModule(M); + return AsmPrinter::doInitialization(M); } @@ -187,6 +190,9 @@ } } + // Emit initial debug information. + DW.EndModule(M); + AsmPrinter::doFinalization(M); return false; // success } Index: llvm/lib/Target/X86/X86AsmPrinter.h diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.11 llvm/lib/Target/X86/X86AsmPrinter.h:1.12 --- llvm/lib/Target/X86/X86AsmPrinter.h:1.11 Sat Feb 25 03:56:50 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.h Mon Mar 6 20:02:57 2006 @@ -18,6 +18,8 @@ #include "X86.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/ADT/Statistic.h" #include @@ -27,14 +29,46 @@ extern Statistic<> EmittedInsts; +/// X86DwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X +/// +struct X86DwarfWriter : public DwarfWriter { + // Ctor. +X86DwarfWriter(std::ostream &o, AsmPrinter *ap) + : DwarfWriter(o, ap) + { + needsSet = true; + DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev"; + DwarfInfoSection = ".section __DWARFA,__debug_info"; + DwarfLineSection = ".section __DWARFA,__debug_line"; + DwarfFrameSection = ".section __DWARFA,__debug_frame"; + DwarfPubNamesSection = ".section __DWARFA,__debug_pubnames"; + DwarfPubTypesSection = ".section __DWARFA,__debug_pubtypes"; + DwarfStrSection = ".section __DWARFA,__debug_str"; + DwarfLocSection = ".section __DWARFA,__debug_loc"; + DwarfARangesSection = ".section __DWARFA,__debug_aranges"; + DwarfRangesSection = ".section __DWARFA,__debug_ranges"; + DwarfMacInfoSection = ".section __DWARFA,__debug_macinfo"; + TextSection = ".text"; + DataSection = ".data"; + } +}; + struct X86SharedAsmPrinter : public AsmPrinter { + X86DwarfWriter DW; + X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM), forDarwin(false) { } + : AsmPrinter(O, TM), DW(O, this), forDarwin(false) { } bool doInitialization(Module &M); bool doFinalization(Module &M); - bool forDarwin; // FIXME: eliminate. + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + bool forDarwin; // FIXME: eliminate. // Necessary for Darwin to print out the apprioriate types of linker stubs std::set FnStubs, GVStubs, LinkOnceStubs; Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.102 llvm/lib/Target/X86/X86ISelLowering.cpp:1.103 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.102 Sat Mar 4 23:08:37 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Mar 6 20:02:57 2006 @@ -168,7 +168,9 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); + // FIXME - use subtarget debug flags + if (!TM.getSubtarget().isTargetDarwin()) + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.251 llvm/lib/Target/X86/X86InstrInfo.td:1.252 --- llvm/lib/Target/X86/X86InstrInfo.td:1.251 Thu Mar 2 18:19:44 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Mar 6 20:02:57 2006 @@ -2353,6 +2353,19 @@ [(set R32:$dst, 0)]>; //===----------------------------------------------------------------------===// +// DWARF Pseudo Instructions +// + +def DWARF_LOC : I<0, Pseudo, (ops i32imm:$line, i32imm:$col, i32imm:$file), + "; .loc $file, $line, $col", + [(dwarf_loc (i32 imm:$line), (i32 imm:$col), + (i32 imm:$file))]>; + +def DWARF_LABEL : I<0, Pseudo, (ops i32imm:$id), + "\nLdebug_loc${id:debug}:", + [(dwarf_label (i32 imm:$id))]>; + +//===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.21 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.22 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.21 Sun Feb 26 02:28:12 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Mon Mar 6 20:02:57 2006 @@ -26,9 +26,16 @@ /// method to print assembly for each instruction. /// bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // Let PassManager know we need debug information and relay + // the MachineDebugInfo address on to DwarfWriter. + DW.SetDebugInfo(&getAnalysis()); + SetupMachineFunction(MF); O << "\n\n"; + // Emit pre-function debug information. + DW.BeginFunction(MF); + // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); @@ -56,6 +63,9 @@ } } + // Emit post-function debug information. + DW.EndFunction(MF); + // We didn't modify anything. return false; } Index: llvm/lib/Target/X86/X86IntelAsmPrinter.h diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.9 llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.10 --- llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.9 Tue Feb 21 20:26:30 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.h Mon Mar 6 20:02:57 2006 @@ -23,7 +23,7 @@ namespace x86 { struct X86IntelAsmPrinter : public X86SharedAsmPrinter { - X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) + X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) : X86SharedAsmPrinter(O, TM) { } virtual const char *getPassName() const { From evan.cheng at apple.com Mon Mar 6 20:23:39 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 6 Mar 2006 20:23:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86AsmPrinter.h X86IntelAsmPrinter.cpp Message-ID: <200603070223.UAA18879@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.29 -> 1.30 X86AsmPrinter.cpp updated: 1.168 -> 1.169 X86AsmPrinter.h updated: 1.12 -> 1.13 X86IntelAsmPrinter.cpp updated: 1.22 -> 1.23 --- Log message: - Emit subsections_via_symbols for Darwin. - Conditionalize Dwarf debugging output (Darwin only for now). --- Diffs of the changes: (+41 -20) X86ATTAsmPrinter.cpp | 20 +++++++++++++------- X86AsmPrinter.cpp | 19 ++++++++++++++----- X86AsmPrinter.h | 2 +- X86IntelAsmPrinter.cpp | 20 +++++++++++++------- 4 files changed, 41 insertions(+), 20 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.29 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.30 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.29 Mon Mar 6 20:02:57 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Mon Mar 6 20:23:26 2006 @@ -27,15 +27,19 @@ /// method to print assembly for each instruction. /// bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - // Let PassManager know we need debug information and relay - // the MachineDebugInfo address on to DwarfWriter. - DW.SetDebugInfo(&getAnalysis()); + // if (forDarwin) { + // Let PassManager know we need debug information and relay + // the MachineDebugInfo address on to DwarfWriter. + DW.SetDebugInfo(&getAnalysis()); + // } SetupMachineFunction(MF); O << "\n\n"; - // Emit pre-function debug information. - DW.BeginFunction(MF); + if (forDarwin) { + // Emit pre-function debug information. + DW.BeginFunction(MF); + } // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); @@ -88,8 +92,10 @@ if (HasDotTypeDotSizeDirective) O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; - // Emit post-function debug information. - DW.EndFunction(MF); + if (forDarwin) { + // Emit post-function debug information. + DW.EndFunction(MF); + } // We didn't modify anything. return false; Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.168 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.169 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.168 Mon Mar 6 20:02:57 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Mon Mar 6 20:23:26 2006 @@ -75,8 +75,10 @@ default: break; } - // Emit initial debug information. - DW.BeginModule(M); + if (forDarwin) { + // Emit initial debug information. + DW.BeginModule(M); + } return AsmPrinter::doInitialization(M); } @@ -188,10 +190,17 @@ O << "\t.indirect_symbol " << *i << "\n"; O << "\t.long\t0\n"; } - } - // Emit initial debug information. - DW.EndModule(M); + // Emit initial debug information. + DW.EndModule(M); + + // Funny Darwin hack: This flag tells the linker that no global symbols + // contain code that falls through to other global symbols (e.g. the obvious + // implementation of multiple entry points). If this doesn't occur, the + // linker can safely perform dead code stripping. Since LLVM never generates + // code that does this, it is always safe to set. + O << "\t.subsections_via_symbols\n"; + } AsmPrinter::doFinalization(M); return false; // success Index: llvm/lib/Target/X86/X86AsmPrinter.h diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.12 llvm/lib/Target/X86/X86AsmPrinter.h:1.13 --- llvm/lib/Target/X86/X86AsmPrinter.h:1.12 Mon Mar 6 20:02:57 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.h Mon Mar 6 20:23:26 2006 @@ -68,7 +68,7 @@ MachineFunctionPass::getAnalysisUsage(AU); } - bool forDarwin; // FIXME: eliminate. + bool forDarwin; // FIXME: eliminate. // Necessary for Darwin to print out the apprioriate types of linker stubs std::set FnStubs, GVStubs, LinkOnceStubs; Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.22 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.23 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.22 Mon Mar 6 20:02:57 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Mon Mar 6 20:23:26 2006 @@ -26,15 +26,19 @@ /// method to print assembly for each instruction. /// bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - // Let PassManager know we need debug information and relay - // the MachineDebugInfo address on to DwarfWriter. - DW.SetDebugInfo(&getAnalysis()); + if (forDarwin) { + // Let PassManager know we need debug information and relay + // the MachineDebugInfo address on to DwarfWriter. + DW.SetDebugInfo(&getAnalysis()); + } SetupMachineFunction(MF); O << "\n\n"; - // Emit pre-function debug information. - DW.BeginFunction(MF); + if (forDarwin) { + // Emit pre-function debug information. + DW.BeginFunction(MF); + } // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); @@ -63,8 +67,10 @@ } } - // Emit post-function debug information. - DW.EndFunction(MF); + if (forDarwin) { + // Emit post-function debug information. + DW.EndFunction(MF); + } // We didn't modify anything. return false; From lattner at cs.uiuc.edu Mon Mar 6 20:46:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 20:46:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603070246.UAA19026@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.13 -> 1.14 --- Log message: add a note --- Diffs of the changes: (+11 -0) README.txt | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.13 llvm/lib/Target/README.txt:1.14 --- llvm/lib/Target/README.txt:1.13 Sun Mar 5 14:00:08 2006 +++ llvm/lib/Target/README.txt Mon Mar 6 20:46:26 2006 @@ -106,3 +106,14 @@ Shrink: (setlt (loadi32 P), 0) -> (setlt (loadi8 Phi), 0) //===---------------------------------------------------------------------===// + +Reassociate is missing this: + +int test(int X, int Y) { + return (X+X+Y+Y); // (X+Y) << 1; +} + +it needs to turn the shifts into multiplies to get it. + +//===---------------------------------------------------------------------===// + From jeffc at jolt-lang.org Mon Mar 6 20:58:26 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Mon, 6 Mar 2006 20:58:26 -0600 Subject: [llvm-commits] CVS: llvm/win32/Support/Support.vcproj Message-ID: <200603070258.UAA19125@zion.cs.uiuc.edu> Changes in directory llvm/win32/Support: Support.vcproj updated: 1.14 -> 1.15 --- Log message: Keep VC++ building. --- Diffs of the changes: (+6 -0) Support.vcproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/win32/Support/Support.vcproj diff -u llvm/win32/Support/Support.vcproj:1.14 llvm/win32/Support/Support.vcproj:1.15 --- llvm/win32/Support/Support.vcproj:1.14 Sun Jan 29 22:07:07 2006 +++ llvm/win32/Support/Support.vcproj Mon Mar 6 20:58:13 2006 @@ -128,6 +128,9 @@ RelativePath="..\..\lib\Support\Debug.cpp"> + + + + Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.68 -> 1.69 --- Log message: add a note --- Diffs of the changes: (+14 -0) README.txt | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.68 llvm/lib/Target/PowerPC/README.txt:1.69 --- llvm/lib/Target/PowerPC/README.txt:1.68 Wed Mar 1 00:36:20 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon Mar 6 22:42:59 2006 @@ -452,3 +452,17 @@ srwi r3, r2, 24 blr +===-------------------------------------------------------------------------=== + +On the G5, logical CR operations are more expensive in their three +address form: ops that read/write the same register are half as expensive as +those that read from two registers that are different from their destination. + +We should model this with two separate instructions. The isel should generate +the "two address" form of the instructions. When the register allocator +detects that it needs to insert a copy due to the two-addresness of the CR +logical op, it will invoke PPCInstrInfo::convertToThreeAddress. At this point +we can convert to the "three address" instruction, to save code space. + +This only matters when we start generating cr logical ops. + From lattner at cs.uiuc.edu Mon Mar 6 23:40:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 6 Mar 2006 23:40:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603070540.XAA21910@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.19 -> 1.20 --- Log message: Fix some formatting, when looking for hazards, prefer target nodes over things like copyfromreg. --- Diffs of the changes: (+15 -7) ScheduleDAGList.cpp | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.19 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.20 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.19 Mon Mar 6 11:58:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Mar 6 23:40:43 2006 @@ -435,19 +435,27 @@ bool HasNoopHazards = false; do { - SUnit *CurrNode = Available.top(); + SUnit *CurNode = Available.top(); Available.pop(); - HazardRecognizer::HazardType HT = - HazardRec.getHazardType(CurrNode->Node); + + // Get the node represented by this SUnit. + SDNode *N = CurNode->Node; + // If this is a pseudo op, like copyfromreg, look to see if there is a + // real target node flagged to it. If so, use the target node. + for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); + N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i) + N = CurNode->FlaggedNodes[i]; + + HazardRecognizer::HazardType HT = HazardRec.getHazardType(N); if (HT == HazardRecognizer::NoHazard) { - FoundNode = CurrNode; + FoundNode = CurNode; break; } // Remember if this is a noop hazard. HasNoopHazards |= HT == HazardRecognizer::NoopHazard; - NotReady.push_back(CurrNode); + NotReady.push_back(CurNode); } while (!Available.empty()); // Add the nodes that aren't ready back onto the available list. @@ -463,14 +471,14 @@ } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. - DEBUG(std::cerr << "*** Advancing cycle, no work to do"); + DEBUG(std::cerr << "*** Advancing cycle, no work to do\n"); HazardRec.AdvanceCycle(); ++NumStalls; } else { // Otherwise, we have no instructions to issue and we have instructions // that will fault if we don't do this right. This is the case for // processors without pipeline interlocks and other cases. - DEBUG(std::cerr << "*** Emitting noop"); + DEBUG(std::cerr << "*** Emitting noop\n"); HazardRec.EmitNoop(); Sequence.push_back(0); // NULL SUnit* -> noop ++NumNoops; From lattner at cs.uiuc.edu Tue Mar 7 00:33:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 00:33:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp PPCHazardRecognizers.h PPCISelDAGToDAG.cpp Message-ID: <200603070633.AAA23362@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp added (r1.1) PPCHazardRecognizers.h added (r1.1) PPCISelDAGToDAG.cpp updated: 1.161 -> 1.162 --- Log message: Implement a very very simple hazard recognizer for LSU rejects and ctr set/read flushes --- Diffs of the changes: (+292 -2) PPCHazardRecognizers.cpp | 203 +++++++++++++++++++++++++++++++++++++++++++++++ PPCHazardRecognizers.h | 79 ++++++++++++++++++ PPCISelDAGToDAG.cpp | 12 ++ 3 files changed, 292 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -c /dev/null llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.1 *** /dev/null Tue Mar 7 00:32:58 2006 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 00:32:48 2006 *************** *** 0 **** --- 1,203 ---- + //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements hazard recognizers for scheduling on PowerPC processors. + // + //===----------------------------------------------------------------------===// + + #define DEBUG_TYPE "sched" + #include "PPCHazardRecognizers.h" + #include "PPC.h" + #include "llvm/Support/Debug.h" + #include + using namespace llvm; + + + //===----------------------------------------------------------------------===// + // PowerPC 970 Hazard Recognizer + // + // FIXME: This is missing some significant cases: + // 0. Handling of instructions that must be the first/last in a group. + // 1. Modeling of microcoded instructions. + // 2. Handling of cracked instructions. + // 3. Handling of serialized operations. + // 4. Handling of the esoteric cases in "Resource-based Instruction Grouping", + // e.g. integer divides that only execute in the second slot. + // + // Note: on the PPC970, logical CR operations are more expensive in their three + // address form: ops that read/write the same register are half as expensive as + // + + void PPCHazardRecognizer970::EndDispatchGroup() { + DEBUG(std::cerr << "=== Start of dispatch group\n"); + // Pipeline units. + NumFXU = NumLSU = NumFPU = 0; + HasCR = HasVALU = HasVPERM = false; + NumIssued = 0; + + // Structural hazard info. + HasCTRSet = false; + StorePtr1 = StorePtr2 = SDOperand(); + StoreSize = 0; + } + + + PPCHazardRecognizer970::PPC970InstrType + PPCHazardRecognizer970::GetInstrType(unsigned Opcode) { + if (Opcode < ISD::BUILTIN_OP_END) + return PseudoInst; + Opcode -= ISD::BUILTIN_OP_END; + + switch (Opcode) { + case PPC::FMRSD: return PseudoInst; // Usually coallesced away. + case PPC::BCTRL: + case PPC::BL: + case PPC::BLA: + return BR; + case PPC::LFS: + case PPC::LWZ: + return LSU_LD; + case PPC::STFD: + return LSU_ST; + case PPC::FADDS: + case PPC::FCTIWZ: + return FPU; + } + + return FXU; + } + + + /// StartBasicBlock - Initiate a new dispatch group. + void PPCHazardRecognizer970::StartBasicBlock() { + EndDispatchGroup(); + } + + /// isLoadOfStoredAddress - If we have a load from the previously stored pointer + /// as indicated by StorePtr1/StorePtr2/StoreSize, return true. + bool PPCHazardRecognizer970:: + isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const { + // Handle exact and commuted addresses. + if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2) + return true; + if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2) + return true; + + // Okay, we don't have an exact match, if this is an indexed offset, see if we + // have overlap (which happens during fp->int conversion for example). + if (StorePtr2 == Ptr2) { + if (ConstantSDNode *StoreOffset = dyn_cast(StorePtr1)) + if (ConstantSDNode *LoadOffset = dyn_cast(Ptr1)) { + // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check to + // see if the load and store actually overlap. + int StoreOffs = StoreOffset->getValue(); + int LoadOffs = LoadOffset->getValue(); + if (StoreOffs < LoadOffs) { + if (int(StoreOffs+StoreSize) > LoadOffs) return true; + } else { + if (int(LoadOffs+LoadSize) > StoreOffs) return true; + } + } + } + return false; + } + + /// getHazardType - We return hazard for any non-branch instruction that would + /// terminate terminate the dispatch group. We turn NoopHazard for any + /// instructions that wouldn't terminate the dispatch group that would cause a + /// pipeline flush. + HazardRecognizer::HazardType PPCHazardRecognizer970:: + getHazardType(SDNode *Node) { + PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); + if (InstrType == PseudoInst) return NoHazard; + unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; + + switch (InstrType) { + default: assert(0 && "Unknown instruction type!"); + case FXU: if (NumFXU == 2) return Hazard; + case LSU_ST: + case LSU_LD: if (NumLSU == 2) return Hazard; + case FPU: if (NumFPU == 2) return Hazard; + case CR: if (HasCR) return Hazard; + case VALU: if (HasVALU) return Hazard; + case VPERM: if (HasVPERM) return Hazard; + case BR: break; + } + + // We can only issue a branch as the last instruction in a group. + if (NumIssued == 4 && InstrType != BR) + return Hazard; + + // Do not allow MTCTR and BCTRL to be in the same dispatch group. + if (HasCTRSet && Opcode == PPC::BCTRL) + return NoopHazard; + + // If this is a load following a store, make sure it's not to the same or + // overlapping address. + if (InstrType == LSU_LD && StoreSize) { + unsigned LoadSize; + switch (Opcode) { + default: assert(0 && "Unknown load!"); + case PPC::LFS: + case PPC::LWZ: LoadSize = 4; break; + } + + if (isLoadOfStoredAddress(LoadSize, + Node->getOperand(0), Node->getOperand(1))) + return NoopHazard; + } + + return NoHazard; + } + + void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) { + PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); + if (InstrType == PseudoInst) return; + unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; + + // Update structural hazard information. + if (Opcode == PPC::MTCTR) HasCTRSet = true; + + // Track the address stored to. + if (InstrType == LSU_ST) { + StorePtr1 = Node->getOperand(1); + StorePtr2 = Node->getOperand(2); + switch (Opcode) { + default: assert(0 && "Unknown store instruction!"); + case PPC::STFD: StoreSize = 8; break; + } + } + + switch (InstrType) { + default: assert(0 && "Unknown instruction type!"); + case FXU: ++NumFXU; break; + case LSU_LD: + case LSU_ST: ++NumLSU; break; + case FPU: ++NumFPU; break; + case CR: HasCR = true; break; + case VALU: HasVALU = true; break; + case VPERM: HasVPERM = true; break; + case BR: NumIssued = 4; return; // ends a d-group. + } + ++NumIssued; + + if (NumIssued == 5) + EndDispatchGroup(); + } + + void PPCHazardRecognizer970::AdvanceCycle() { + assert(NumIssued < 5 && "Illegal dispatch group!"); + ++NumIssued; + if (NumIssued == 5) + EndDispatchGroup(); + } + + void PPCHazardRecognizer970::EmitNoop() { + AdvanceCycle(); + } Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h diff -c /dev/null llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.1 *** /dev/null Tue Mar 7 00:33:01 2006 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h Tue Mar 7 00:32:48 2006 *************** *** 0 **** --- 1,79 ---- + //===-- PPCHazardRecognizers.h - PowerPC Hazard Recognizers -----*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines hazard recognizers for scheduling on PowerPC processors. + // + //===----------------------------------------------------------------------===// + + #ifndef PPCHAZRECS_H + #define PPCHAZRECS_H + + #include "llvm/CodeGen/ScheduleDAG.h" + + namespace llvm { + + /// PPCHazardRecognizer970 - This class defines a finite state automata that + /// models the dispatch logic on the PowerPC 970 (aka G5) processor. This + /// promotes good dispatch group formation and implements noop insertion to + /// avoid structural hazards that cause significant performance penalties (e.g. + /// setting the CTR register then branching through it within a dispatch group), + /// or storing then loading from the same address within a dispatch group. + class PPCHazardRecognizer970 : public HazardRecognizer { + unsigned NumIssued; // Number of insts issued, including advanced cycles. + + // Number of various types of instructions in the current dispatch group. + unsigned NumFXU; // Number of Fixed Point (integer) instructions + unsigned NumLSU; // Number of Load/Store instructions + unsigned NumFPU; // Number of Floating Point instructions + bool HasCR; // True if Condition Register instruction issued + bool HasVALU; // True if Vector Arithmetic instruction issued + bool HasVPERM; // True if Vector Permute instruction issued + + // Various things that can cause a structural hazard. + + // HasCTRSet - If the CTR register is set in this group, disallow BCTRL. + bool HasCTRSet; + + // StoredPtr - Keep track of the address of any store. If we see a load from + // the same address (or one that aliases it), disallow the store. We only + // need one pointer here, because there can only be two LSU operations and we + // only get an LSU reject if the first is a store and the second is a load. + // + // This is null if we haven't seen a store yet. We keep track of both + // operands of the store here, since we support [r+r] and [r+i] addressing. + SDOperand StorePtr1, StorePtr2; + unsigned StoreSize; + + public: + virtual void StartBasicBlock(); + virtual HazardType getHazardType(SDNode *Node); + virtual void EmitInstruction(SDNode *Node); + virtual void AdvanceCycle(); + virtual void EmitNoop(); + + private: + /// EndDispatchGroup - Called when we are finishing a new dispatch group. + /// + void EndDispatchGroup(); + + enum PPC970InstrType { + FXU, LSU_LD, LSU_ST, FPU, CR, VALU, VPERM, BR, PseudoInst + }; + + /// GetInstrType - Classify the specified powerpc opcode according to its + /// pipeline. + PPC970InstrType GetInstrType(unsigned Opcode); + + bool isLoadOfStoredAddress(unsigned LoadSize, + SDOperand Ptr1, SDOperand Ptr2) const; + }; + + } // end namespace llvm + + #endif \ No newline at end of file Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.161 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.162 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.161 Wed Mar 1 01:14:48 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Mar 7 00:32:48 2006 @@ -15,6 +15,7 @@ #include "PPC.h" #include "PPCTargetMachine.h" #include "PPCISelLowering.h" +#include "PPCHazardRecognizers.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SSARegMap.h" @@ -40,6 +41,7 @@ class PPCDAGToDAGISel : public SelectionDAGISel { PPCTargetLowering PPCLowering; unsigned GlobalBaseReg; + PPCHazardRecognizer970 PPC970HR; public: PPCDAGToDAGISel(TargetMachine &TM) : SelectionDAGISel(PPCLowering), PPCLowering(TM) {} @@ -122,13 +124,19 @@ virtual const char *getPassName() const { return "PowerPC DAG->DAG Pattern Instruction Selection"; } + + /// GetTargetHazardRecognizer - Return the hazard recognizer to use for this + /// target when scheduling the DAG. + virtual HazardRecognizer &GetTargetHazardRecognizer() { + // Should use subtarget info to pick the right hazard recognizer. For + // now, always return a PPC970 recognizer. + return PPC970HR; + } // Include the pieces autogenerated from the target description. #include "PPCGenDAGISel.inc" private: - SDOperand SelectADD_PARTS(SDOperand Op); - SDOperand SelectSUB_PARTS(SDOperand Op); SDOperand SelectSETCC(SDOperand Op); SDOperand SelectCALL(SDOperand Op); }; From lattner at cs.uiuc.edu Tue Mar 7 00:44:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 00:44:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Message-ID: <200603070644.AAA23603@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.1 -> 1.2 --- Log message: add some comments that describe what we model --- Diffs of the changes: (+18 -3) PPCHazardRecognizers.cpp | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.1 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.2 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.1 Tue Mar 7 00:32:48 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 00:44:19 2006 @@ -22,6 +22,24 @@ //===----------------------------------------------------------------------===// // PowerPC 970 Hazard Recognizer // +// This models the dispatch group formation of the PPC970 processor. Dispatch +// groups are bundles of up to five instructions that can contain up to two ALU +// (aka FXU) ops, two FPU ops, two Load/Store ops, one CR op, one VALU op, one +// VPERM op, and one BRANCH op. If the code contains more instructions in a +// sequence than the dispatch group can contain (e.g. three loads in a row) the +// processor terminates the dispatch group early, wasting execution resources. +// +// In addition to these restrictions, there are a number of other restrictions: +// some instructions, e.g. branches, are required to be the last instruction in +// a group. Additionally, only branches can issue in the 5th (last) slot. +// +// Finally, there are a number of "structural" hazards on the PPC970. These +// conditions cause large performance penalties due to misprediction, recovery, +// and replay logic that has to happen. These cases include setting a CTR and +// branching through it in the same dispatch group, and storing to an address, +// then loading from the same address within a dispatch group. To avoid these +// conditions, we insert no-op instructions when appropriate. +// // FIXME: This is missing some significant cases: // 0. Handling of instructions that must be the first/last in a group. // 1. Modeling of microcoded instructions. @@ -30,9 +48,6 @@ // 4. Handling of the esoteric cases in "Resource-based Instruction Grouping", // e.g. integer divides that only execute in the second slot. // -// Note: on the PPC970, logical CR operations are more expensive in their three -// address form: ops that read/write the same register are half as expensive as -// void PPCHazardRecognizer970::EndDispatchGroup() { DEBUG(std::cerr << "=== Start of dispatch group\n"); From lattner at cs.uiuc.edu Tue Mar 7 00:47:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 00:47:18 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200603070647.AAA23721@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.195 -> 1.196 --- Log message: Enable the td scheduler for llcbeta --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.195 llvm-test/Makefile.programs:1.196 --- llvm-test/Makefile.programs:1.195 Sun Mar 5 03:40:01 2006 +++ llvm-test/Makefile.programs Tue Mar 7 00:47:05 2006 @@ -187,7 +187,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -sched=simple +LLCBETAOPTION := -sched=list-td endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-alpha-lsmark From lattner at cs.uiuc.edu Tue Mar 7 01:15:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 01:15:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Message-ID: <200603070715.BAA24448@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.2 -> 1.3 --- Log message: add some new instructions to the classifier. With this, we correctly insert a nop into Freebench/neural, which speeds it up from 136->129s (~5.4%). --- Diffs of the changes: (+11 -0) PPCHazardRecognizers.cpp | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.2 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.3 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.2 Tue Mar 7 00:44:19 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 01:14:55 2006 @@ -41,6 +41,7 @@ // conditions, we insert no-op instructions when appropriate. // // FIXME: This is missing some significant cases: +// -1. Handle all of the instruction types in GetInstrType. // 0. Handling of instructions that must be the first/last in a group. // 1. Modeling of microcoded instructions. // 2. Handling of cracked instructions. @@ -76,12 +77,18 @@ case PPC::BLA: return BR; case PPC::LFS: + case PPC::LFD: case PPC::LWZ: + case PPC::LFSX: + case PPC::LWZX: return LSU_LD; case PPC::STFD: + case PPC::STW: return LSU_ST; case PPC::FADDS: case PPC::FCTIWZ: + case PPC::FRSP: + case PPC::FSUB: return FPU; } @@ -159,8 +166,11 @@ unsigned LoadSize; switch (Opcode) { default: assert(0 && "Unknown load!"); + case PPC::LFSX: case PPC::LFS: + case PPC::LWZX: case PPC::LWZ: LoadSize = 4; break; + case PPC::LFD: LoadSize = 8; break; } if (isLoadOfStoredAddress(LoadSize, @@ -186,6 +196,7 @@ switch (Opcode) { default: assert(0 && "Unknown store instruction!"); case PPC::STFD: StoreSize = 8; break; + case PPC::STW: StoreSize = 4; break; } } From natebegeman at mac.com Tue Mar 7 02:30:40 2006 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 7 Mar 2006 02:30:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp PPCHazardRecognizers.h Message-ID: <200603070830.CAA32593@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.3 -> 1.4 PPCHazardRecognizers.h updated: 1.1 -> 1.2 --- Log message: This kinda sorta implements "things that have to lead a dispatch group". --- Diffs of the changes: (+42 -17) PPCHazardRecognizers.cpp | 56 +++++++++++++++++++++++++++++++++-------------- PPCHazardRecognizers.h | 3 +- 2 files changed, 42 insertions(+), 17 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.3 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.4 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.3 Tue Mar 7 01:14:55 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 02:30:27 2006 @@ -54,7 +54,7 @@ DEBUG(std::cerr << "=== Start of dispatch group\n"); // Pipeline units. NumFXU = NumLSU = NumFPU = 0; - HasCR = HasVALU = HasVPERM = false; + HasCR = HasSPR = HasVALU = HasVPERM = false; NumIssued = 0; // Structural hazard info. @@ -76,6 +76,15 @@ case PPC::BL: case PPC::BLA: return BR; + case PPC::MCRF: + case PPC::MFCR: + case PPC::MFOCRF: + return CR; + case PPC::MFLR: + case PPC::MFCTR: + case PPC::MTLR: + case PPC::MTCTR: + return SPR; case PPC::LFS: case PPC::LFD: case PPC::LWZ: @@ -85,6 +94,11 @@ case PPC::STFD: case PPC::STW: return LSU_ST; + case PPC::DIVW: + case PPC::DIVWU: + case PPC::DIVD: + case PPC::DIVDU: + return FXU_FIRST; case PPC::FADDS: case PPC::FCTIWZ: case PPC::FRSP: @@ -142,16 +156,24 @@ switch (InstrType) { default: assert(0 && "Unknown instruction type!"); - case FXU: if (NumFXU == 2) return Hazard; + case FXU: + case FXU_FIRST: if (NumFXU == 2) return Hazard; case LSU_ST: - case LSU_LD: if (NumLSU == 2) return Hazard; - case FPU: if (NumFPU == 2) return Hazard; - case CR: if (HasCR) return Hazard; - case VALU: if (HasVALU) return Hazard; - case VPERM: if (HasVPERM) return Hazard; - case BR: break; + case LSU_LD: if (NumLSU == 2) return Hazard; + case FPU: if (NumFPU == 2) return Hazard; + case CR: if (HasCR) return Hazard; + case SPR: if (HasSPR) return Hazard; + case VALU: if (HasVALU) return Hazard; + case VPERM: if (HasVPERM) return Hazard; + case BR: break; } - + + // We can only issue a CR or SPR instruction, or an FXU instruction that needs + // to lead a dispatch group as the first instruction in the group. + if (NumIssued != 0 && + (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST)) + return Hazard; + // We can only issue a branch as the last instruction in a group. if (NumIssued == 4 && InstrType != BR) return Hazard; @@ -202,14 +224,16 @@ switch (InstrType) { default: assert(0 && "Unknown instruction type!"); - case FXU: ++NumFXU; break; + case FXU: + case FXU_FIRST: ++NumFXU; break; case LSU_LD: - case LSU_ST: ++NumLSU; break; - case FPU: ++NumFPU; break; - case CR: HasCR = true; break; - case VALU: HasVALU = true; break; - case VPERM: HasVPERM = true; break; - case BR: NumIssued = 4; return; // ends a d-group. + case LSU_ST: ++NumLSU; break; + case FPU: ++NumFPU; break; + case CR: HasCR = true; break; + case SPR: HasSPR = true; break; + case VALU: HasVALU = true; break; + case VPERM: HasVPERM = true; break; + case BR: NumIssued = 4; return; // ends a d-group. } ++NumIssued; Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.1 llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.2 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.1 Tue Mar 7 00:32:48 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.h Tue Mar 7 02:30:27 2006 @@ -32,6 +32,7 @@ unsigned NumLSU; // Number of Load/Store instructions unsigned NumFPU; // Number of Floating Point instructions bool HasCR; // True if Condition Register instruction issued + bool HasSPR; // True if Special-Purpose Register instruction used bool HasVALU; // True if Vector Arithmetic instruction issued bool HasVPERM; // True if Vector Permute instruction issued @@ -63,7 +64,7 @@ void EndDispatchGroup(); enum PPC970InstrType { - FXU, LSU_LD, LSU_ST, FPU, CR, VALU, VPERM, BR, PseudoInst + FXU, FXU_FIRST, LSU_LD, LSU_ST, FPU, CR, SPR, VALU, VPERM, BR, PseudoInst }; /// GetInstrType - Classify the specified powerpc opcode according to its From evan.cheng at apple.com Tue Mar 7 02:31:40 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 7 Mar 2006 02:31:40 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200603070831.CAA00392@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.174 -> 1.175 --- Log message: Don't generate silly matching code like this: if (N1.getOpcode() == ISD::ADD && ...) if (... && (N1.getNumOperands() == 1 || !isNonImmUse(N1.Val, N10.Val))) && ...) TableGen knows N1 must have more than one operand. --- Diffs of the changes: (+8 -3) DAGISelEmitter.cpp | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.174 llvm/utils/TableGen/DAGISelEmitter.cpp:1.175 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.174 Thu Feb 23 20:13:31 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Mar 7 02:31:27 2006 @@ -2006,9 +2006,14 @@ PInfo.hasProperty(SDNodeInfo::SDNPHasChain) || PInfo.hasProperty(SDNodeInfo::SDNPInFlag) || PInfo.hasProperty(SDNodeInfo::SDNPOptInFlag)) - emitCheck("(" + ParentName + ".getNumOperands() == 1 || !" + - "isNonImmUse(" + ParentName + ".Val, " + RootName + - ".Val))"); + if (PInfo.getNumOperands() > 1) { + emitCheck("!isNonImmUse(" + ParentName + ".Val, " + RootName + + ".Val)"); + } else { + emitCheck("(" + ParentName + ".getNumOperands() == 1 || !" + + "isNonImmUse(" + ParentName + ".Val, " + RootName + + ".Val))"); + } } } From jlaskey at apple.com Tue Mar 7 09:51:45 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 09:51:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200603071551.JAA17170@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.42 -> 1.43 --- Log message: Bitfield support. --- Diffs of the changes: (+14 -2) DwarfWriter.cpp | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.42 llvm/lib/CodeGen/DwarfWriter.cpp:1.43 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.42 Fri Mar 3 15:00:14 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Tue Mar 7 09:51:33 2006 @@ -1334,20 +1334,32 @@ if (CompileUnitDesc *File = MemberDesc->getFile()) { CompileUnit *FileUnit = FindCompileUnit(File); unsigned FileID = FileUnit->getID(); - int Line = TyDesc->getLine(); + int Line = MemberDesc->getLine(); Member->AddUInt(DW_AT_decl_file, 0, FileID); Member->AddUInt(DW_AT_decl_line, 0, Line); } + // FIXME - Bitfields not quite right but getting there. + uint64_t ByteSize = Size; + uint64_t ByteOffset = Offset; + if (TypeDesc *FromTy = MemberDesc->getFromType()) { Member->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); + ByteSize = FromTy->getSize(); + } + + if (ByteSize != Size) { + ByteOffset -= Offset % ByteSize; + Member->AddUInt(DW_AT_byte_size, 0, ByteSize >> 3); + Member->AddUInt(DW_AT_bit_size, 0, Size % ByteSize); + Member->AddUInt(DW_AT_bit_offset, 0, Offset - ByteOffset); } // Add computation for offset. DIEBlock *Block = new DIEBlock(); Block->AddUInt(DW_FORM_data1, DW_OP_plus_uconst); - Block->AddUInt(DW_FORM_udata, Offset >> 3); + Block->AddUInt(DW_FORM_udata, ByteOffset >> 3); Block->ComputeSize(*this); Member->AddBlock(DW_AT_data_member_location, 0, Block); From lattner at cs.uiuc.edu Tue Mar 7 10:19:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 10:19:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp PPCHazardRecognizers.h Message-ID: <200603071619.KAA17508@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.4 -> 1.5 PPCHazardRecognizers.h updated: 1.2 -> 1.3 --- Log message: add a couple more load/store instrs, add a newline to the end of file. --- Diffs of the changes: (+17 -2) PPCHazardRecognizers.cpp | 16 +++++++++++++++- PPCHazardRecognizers.h | 3 ++- 2 files changed, 17 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.4 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.5 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.4 Tue Mar 7 02:30:27 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 10:19:46 2006 @@ -90,9 +90,16 @@ case PPC::LWZ: case PPC::LFSX: case PPC::LWZX: + case PPC::LBZ: + case PPC::LHA: + case PPC::LHZ: + case PPC::LWZU: return LSU_LD; case PPC::STFD: case PPC::STW: + case PPC::STB: + case PPC::STH: + case PPC::STWU: return LSU_ST; case PPC::DIVW: case PPC::DIVWU: @@ -188,6 +195,10 @@ unsigned LoadSize; switch (Opcode) { default: assert(0 && "Unknown load!"); + case PPC::LBZ: LoadSize = 1; break; + case PPC::LHA: + case PPC::LHZ: LoadSize = 2; break; + case PPC::LWZU: case PPC::LFSX: case PPC::LFS: case PPC::LWZX: @@ -217,8 +228,11 @@ StorePtr2 = Node->getOperand(2); switch (Opcode) { default: assert(0 && "Unknown store instruction!"); - case PPC::STFD: StoreSize = 8; break; + case PPC::STB: StoreSize = 1; break; + case PPC::STH: StoreSize = 2; break; + case PPC::STWU: case PPC::STW: StoreSize = 4; break; + case PPC::STFD: StoreSize = 8; break; } } Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.2 llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.3 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.2 Tue Mar 7 02:30:27 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.h Tue Mar 7 10:19:46 2006 @@ -77,4 +77,5 @@ } // end namespace llvm -#endif \ No newline at end of file +#endif + From lattner at cs.uiuc.edu Tue Mar 7 10:27:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 10:27:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Message-ID: <200603071627.KAA17593@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.5 -> 1.6 --- Log message: add another missing store. --- Diffs of the changes: (+2 -0) PPCHazardRecognizers.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.5 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.6 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.5 Tue Mar 7 10:19:46 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 10:26:48 2006 @@ -95,6 +95,7 @@ case PPC::LHZ: case PPC::LWZU: return LSU_LD; + case PPC::STFS: case PPC::STFD: case PPC::STW: case PPC::STB: @@ -230,6 +231,7 @@ default: assert(0 && "Unknown store instruction!"); case PPC::STB: StoreSize = 1; break; case PPC::STH: StoreSize = 2; break; + case PPC::STFS: case PPC::STWU: case PPC::STW: StoreSize = 4; break; case PPC::STFD: StoreSize = 8; break; From lattner at cs.uiuc.edu Tue Mar 7 11:56:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 11:56:44 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll Message-ID: <200603071756.LAA18427@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstantMerge: 2006-03-07-DontMergeDiffSections.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+15 -0) 2006-03-07-DontMergeDiffSections.ll | 15 +++++++++++++++ 1 files changed, 15 insertions(+) Index: llvm/test/Regression/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll diff -c /dev/null llvm/test/Regression/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll:1.1 *** /dev/null Tue Mar 7 11:56:41 2006 --- llvm/test/Regression/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll Tue Mar 7 11:56:31 2006 *************** *** 0 **** --- 1,15 ---- + ; RUN: llvm-as < %s | opt -constmerge | llvm-dis | grep foo + ; RUN: llvm-as < %s | opt -constmerge | llvm-dis | grep bar + + ; Don't merge constants in different sections. + + %G1 = internal constant int 1, section "foo" + %G2 = internal constant int 1, section "bar" + %G3 = internal constant int 1, section "bar" + + void %test(int** %P1, int **%P2, int **%P3) { + store int* %G1, int** %P1 + store int* %G2, int** %P2 + store int* %G3, int** %P3 + ret void + } From lattner at cs.uiuc.edu Tue Mar 7 11:57:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 11:57:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ConstantMerge.cpp Message-ID: <200603071757.LAA18438@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ConstantMerge.cpp updated: 1.30 -> 1.31 --- Log message: Fix ConstantMerge/2006-03-07-DontMergeDiffSections.ll, a problem Jim hypotheticalized about, where we would incorrectly merge two globals in different sections. --- Diffs of the changes: (+14 -11) ConstantMerge.cpp | 25 ++++++++++++++----------- 1 files changed, 14 insertions(+), 11 deletions(-) Index: llvm/lib/Transforms/IPO/ConstantMerge.cpp diff -u llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.30 llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.31 --- llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.30 Thu Apr 21 18:39:37 2005 +++ llvm/lib/Transforms/IPO/ConstantMerge.cpp Tue Mar 7 11:56:59 2006 @@ -39,7 +39,9 @@ ModulePass *llvm::createConstantMergePass() { return new ConstantMerge(); } bool ConstantMerge::runOnModule(Module &M) { - std::map CMap; + // Map unique constant/section pairs to globals. We don't want to merge + // globals in different sections. + std::map, GlobalVariable*> CMap; // Replacements - This vector contains a list of replacements to perform. std::vector > Replacements; @@ -56,23 +58,24 @@ // because doing so may cause initializers of other globals to be rewritten, // invalidating the Constant* pointers in CMap. // - for (Module::global_iterator GV = M.global_begin(), E = M.global_end(); GV != E; ++GV) - // Only process constants with initializers + for (Module::global_iterator GV = M.global_begin(), E = M.global_end(); + GV != E; ++GV) + // Only process constants with initializers. if (GV->isConstant() && GV->hasInitializer()) { Constant *Init = GV->getInitializer(); - // Check to see if the initializer is already known... - std::map::iterator I = CMap.find(Init); + // Check to see if the initializer is already known. + GlobalVariable *&Slot = CMap[std::make_pair(Init, GV->getSection())]; - if (I == CMap.end()) { // Nope, add it to the map - CMap.insert(I, std::make_pair(Init, GV)); + if (Slot == 0) { // Nope, add it to the map. + Slot = GV; } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the canonical version. - Replacements.push_back(std::make_pair(GV, I->second)); - } else if (I->second->hasInternalLinkage()) { + Replacements.push_back(std::make_pair(GV, Slot)); + } else if (GV->hasInternalLinkage()) { // Make all uses of the duplicate constant use the canonical version. - Replacements.push_back(std::make_pair(I->second, GV)); - I->second = GV; + Replacements.push_back(std::make_pair(Slot, GV)); + Slot = GV; } } From jlaskey at apple.com Tue Mar 7 14:54:00 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 14:54:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineDebugInfo.cpp Message-ID: <200603072054.OAA19435@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineDebugInfo.cpp updated: 1.23 -> 1.24 --- Log message: Switch to using a numeric id for anchors. --- Diffs of the changes: (+28 -12) MachineDebugInfo.cpp | 40 ++++++++++++++++++++++++++++------------ 1 files changed, 28 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.23 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.24 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.23 Fri Mar 3 09:06:57 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Tue Mar 7 14:53:47 2006 @@ -53,7 +53,7 @@ std::vector FieldTypes; FieldTypes.push_back(Type::UIntTy); - FieldTypes.push_back(PointerType::get(Type::SByteTy)); + FieldTypes.push_back(Type::UIntTy); // Get the GlobalVariable root. GlobalVariable *UseRoot = M.getGlobalVariable(RootName, @@ -539,11 +539,11 @@ AnchorDesc::AnchorDesc() : DebugInfoDesc(DW_TAG_anchor) -, Name("") +, AnchorTag(0) {} -AnchorDesc::AnchorDesc(const std::string &N) +AnchorDesc::AnchorDesc(AnchoredDesc *D) : DebugInfoDesc(DW_TAG_anchor) -, Name(N) +, AnchorTag(D->getTag()) {} // Implement isa/cast/dyncast. @@ -562,13 +562,26 @@ void AnchorDesc::ApplyToFields(DIVisitor *Visitor) { DebugInfoDesc::ApplyToFields(Visitor); - Visitor->Apply(Name); + Visitor->Apply(AnchorTag); } -/// getDescString - Return a string used to compose global names and labels. -/// +/// getDescString - Return a string used to compose global names and labels. A +/// A global variable name needs to be defined for each debug descriptor that is +/// anchored. NOTE: that each global variable name here also needs to be added +/// to the list of names left external in the internalizer. +/// ExternalNames.insert("llvm.dbg.compile_units"); +/// ExternalNames.insert("llvm.dbg.global_variables"); +/// ExternalNames.insert("llvm.dbg.subprograms"); const char *AnchorDesc::getDescString() const { - return Name.c_str(); + switch (AnchorTag) { + case DW_TAG_compile_unit: return CompileUnitDesc::AnchorString; + case DW_TAG_variable: return GlobalVariableDesc::AnchorString; + case DW_TAG_subprogram: return SubprogramDesc::AnchorString; + default: break; + } + + assert(0 && "Tag does not have a case for anchor string"); + return ""; } /// getTypeString - Return a string used to label this descriptors type. @@ -581,7 +594,7 @@ void AnchorDesc::dump() { std::cerr << getDescString() << " " << "Tag(" << getTag() << "), " - << "Name(" << Name << ")\n"; + << "AnchorTag(" << AnchorTag << ")\n"; } #endif @@ -649,8 +662,9 @@ /// getAnchorString - Return a string used to label this descriptor's anchor. /// +const char *CompileUnitDesc::AnchorString = "llvm.dbg.compile_units"; const char *CompileUnitDesc::getAnchorString() const { - return "llvm.dbg.compile_units"; + return AnchorString; } #ifndef NDEBUG @@ -1014,8 +1028,9 @@ /// getAnchorString - Return a string used to label this descriptor's anchor. /// +const char *GlobalVariableDesc::AnchorString = "llvm.dbg.global_variables"; const char *GlobalVariableDesc::getAnchorString() const { - return "llvm.dbg.global_variables"; + return AnchorString; } #ifndef NDEBUG @@ -1063,8 +1078,9 @@ /// getAnchorString - Return a string used to label this descriptor's anchor. /// +const char *SubprogramDesc::AnchorString = "llvm.dbg.subprograms"; const char *SubprogramDesc::getAnchorString() const { - return "llvm.dbg.subprograms"; + return AnchorString; } #ifndef NDEBUG From jlaskey at apple.com Tue Mar 7 14:54:01 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 14:54:01 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603072054.OAA19443@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.27 -> 1.28 --- Log message: Switch to using a numeric id for anchors. --- Diffs of the changes: (+14 -4) MachineDebugInfo.h | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.27 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.28 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.27 Fri Mar 3 09:06:56 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Tue Mar 7 14:53:47 2006 @@ -142,16 +142,18 @@ //===----------------------------------------------------------------------===// /// AnchorDesc - Descriptors of this class act as markers for identifying /// descriptors of certain groups. +class AnchoredDesc; class AnchorDesc : public DebugInfoDesc { -private: - std::string Name; // Anchor type string. +private: + unsigned AnchorTag; // Tag number of descriptors anchored + // by this object. public: AnchorDesc(); - AnchorDesc(const std::string &N); + AnchorDesc(AnchoredDesc *D); // Accessors - const std::string &getName() const { return Name; } + unsigned getAnchorTag() const { return AnchorTag; } // Implement isa/cast/dyncast. static bool classof(const AnchorDesc *) { return true; } @@ -198,6 +200,10 @@ //===--------------------------------------------------------------------===// // Subclasses should supply the following virtual methods. + /// getAnchorString - Return a string used to label descriptor's anchor. + /// + virtual const char *getAnchorString() const = 0; + /// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. /// virtual void ApplyToFields(DIVisitor *Visitor); @@ -217,6 +223,7 @@ public: CompileUnitDesc(); + // Accessors unsigned getDebugVersion() const { return DebugVersion; } unsigned getLanguage() const { return Language; } @@ -252,6 +259,7 @@ /// getAnchorString - Return a string used to label this descriptor's anchor. /// + static const char *AnchorString; virtual const char *getAnchorString() const; #ifndef NDEBUG @@ -553,6 +561,7 @@ /// getAnchorString - Return a string used to label this descriptor's anchor. /// + static const char *AnchorString; virtual const char *getAnchorString() const; #ifndef NDEBUG @@ -591,6 +600,7 @@ /// getAnchorString - Return a string used to label this descriptor's anchor. /// + static const char *AnchorString; virtual const char *getAnchorString() const; #ifndef NDEBUG From jlaskey at apple.com Tue Mar 7 14:54:01 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 14:54:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Internalize.cpp Message-ID: <200603072054.OAA19439@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Internalize.cpp updated: 1.31 -> 1.32 --- Log message: Switch to using a numeric id for anchors. --- Diffs of the changes: (+4 -3) Internalize.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/IPO/Internalize.cpp diff -u llvm/lib/Transforms/IPO/Internalize.cpp:1.31 llvm/lib/Transforms/IPO/Internalize.cpp:1.32 --- llvm/lib/Transforms/IPO/Internalize.cpp:1.31 Sun Jan 22 17:32:06 2006 +++ llvm/lib/Transforms/IPO/Internalize.cpp Tue Mar 7 14:53:47 2006 @@ -112,9 +112,10 @@ ExternalNames.insert("llvm.used"); // Never internalize anchors used by the debugger, else the debugger won't - // find them. - ExternalNames.insert("llvm.dbg.translation_units"); - ExternalNames.insert("llvm.dbg.globals"); + // find them. (see MachineDebugInfo.) + ExternalNames.insert("llvm.dbg.compile_units"); + ExternalNames.insert("llvm.dbg.global_variables"); + ExternalNames.insert("llvm.dbg.subprograms"); // Mark all global variables with initializers as internal as well. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); From jlaskey at apple.com Tue Mar 7 16:00:49 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 16:00:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp MachineDebugInfo.cpp Message-ID: <200603072200.QAA19959@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.57 -> 1.58 MachineDebugInfo.cpp updated: 1.24 -> 1.25 --- Log message: Use "llvm.metadata" section for debug globals. Filter out these globals in the asm printer. --- Diffs of the changes: (+9 -2) AsmPrinter.cpp | 8 ++++++-- MachineDebugInfo.cpp | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.57 llvm/lib/CodeGen/AsmPrinter.cpp:1.58 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.57 Thu Mar 2 20:04:29 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue Mar 7 16:00:35 2006 @@ -131,8 +131,12 @@ /// special global used by LLVM. If so, emit it and return true, otherwise /// do nothing and return false. bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { - assert(GV->hasInitializer() && GV->hasAppendingLinkage() && - "Not a special LLVM global!"); + // Ignore debug and non-emitted data. + if (GV->getSection() == "llvm.metadata") return true; + + if (!GV->hasAppendingLinkage()) return false; + + assert(GV->hasInitializer() && "Not a special LLVM global!"); if (GV->getName() == "llvm.used") return true; // No need to emit this at all. Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.24 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.25 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.24 Tue Mar 7 14:53:47 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Tue Mar 7 16:00:35 2006 @@ -350,6 +350,7 @@ GlobalValue::InternalLinkage, CA, "llvm.dbg.array", SR.getModule()); + CAGV->setSection("llvm.metadata"); Constant *CAE = ConstantExpr::getCast(CAGV, EmptyTy); Elements.push_back(CAE); } @@ -1193,6 +1194,7 @@ GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true, GlobalVariable::InternalLinkage, ConstStr, "str", M); + StrGV->setSection("llvm.metadata"); // Convert to generic string pointer. Slot = ConstantExpr::getCast(StrGV, getStrPtrType()); return Slot; @@ -1214,6 +1216,7 @@ // Create the GlobalVariable early to prevent infinite recursion. GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(), NULL, DD->getDescString(), M); + GV->setSection("llvm.metadata"); // Insert new GlobalVariable in DescGlobals map. Slot = GV; From jlaskey at apple.com Tue Mar 7 16:00:50 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 16:00:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200603072200.QAA19963@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.156 -> 1.157 --- Log message: Use "llvm.metadata" section for debug globals. Filter out these globals in the asm printer. --- Diffs of the changes: (+1 -1) PPCAsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.156 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.157 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.156 Fri Feb 24 14:27:40 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Mar 7 16:00:35 2006 @@ -564,7 +564,7 @@ if (!I->hasInitializer()) continue; // External global require no code // Check to see if this is a special global used by LLVM, if so, emit it. - if (I->hasAppendingLinkage() && EmitSpecialLLVMGlobal(I)) + if (EmitSpecialLLVMGlobal(I)) continue; std::string name = Mang->getValueName(I); From jlaskey at apple.com Tue Mar 7 16:00:50 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 16:00:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200603072200.QAA19967@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.169 -> 1.170 --- Log message: Use "llvm.metadata" section for debug globals. Filter out these globals in the asm printer. --- Diffs of the changes: (+1 -1) X86AsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.169 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.170 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.169 Mon Mar 6 20:23:26 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Tue Mar 7 16:00:35 2006 @@ -92,7 +92,7 @@ if (!I->hasInitializer()) continue; // External global require no code // Check to see if this is a special global used by LLVM, if so, emit it. - if (I->hasAppendingLinkage() && EmitSpecialLLVMGlobal(I)) + if (EmitSpecialLLVMGlobal(I)) continue; std::string name = Mang->getValueName(I); From lattner at cs.uiuc.edu Tue Mar 7 16:14:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 16:14:11 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile Message-ID: <200603072214.QAA20207@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/CoyoteBench: Makefile updated: 1.1 -> 1.2 --- Log message: link with libstdc++ to let fftbench work with the new frontend --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile diff -u llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile:1.1 llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile:1.2 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile:1.1 Sat Mar 4 16:35:18 2006 +++ llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile Tue Mar 7 16:13:57 2006 @@ -1,5 +1,5 @@ LEVEL = ../../.. -LDFLAGS += -lm +LDFLAGS += -lm -lstdc++ include $(LEVEL)/SingleSource/Makefile.singlesrc From lattner at cs.uiuc.edu Tue Mar 7 16:33:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 16:33:12 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/attribute_constructor.c Message-ID: <200603072233.QAA20831@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: attribute_constructor.c added (r1.1) --- Log message: new testcase that should have been added long ago. --- Diffs of the changes: (+6 -0) attribute_constructor.c | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Regression/CFrontend/attribute_constructor.c diff -c /dev/null llvm/test/Regression/CFrontend/attribute_constructor.c:1.1 *** /dev/null Tue Mar 7 16:33:10 2006 --- llvm/test/Regression/CFrontend/attribute_constructor.c Tue Mar 7 16:33:00 2006 *************** *** 0 **** --- 1,6 ---- + // RUN: %llvmgcc %s -c -o - | llvm-dis | grep llvm.global_ctors + + void foo() __attribute__((constructor)); + void foo() { + bar(); + } From lattner at cs.uiuc.edu Tue Mar 7 16:58:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 16:58:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200603072258.QAA21949@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.253 -> 1.254 --- Log message: Two things: 1. Don't emit debug info, or other llvm.metadata to the .cbe.c file. 2. Mark static ctors/dtors as such, so that bugpoint works on C++ code compiled with the new CFE. --- Diffs of the changes: (+89 -12) Writer.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 89 insertions(+), 12 deletions(-) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.253 llvm/lib/Target/CBackend/Writer.cpp:1.254 --- llvm/lib/Target/CBackend/Writer.cpp:1.253 Mon Feb 13 16:22:42 2006 +++ llvm/lib/Target/CBackend/Writer.cpp Tue Mar 7 16:58:23 2006 @@ -797,7 +797,7 @@ // directives to cater to specific compilers as need be. // static void generateCompilerSpecificCode(std::ostream& Out) { - // Alloca is hard to get, and we don't want to include stdlib.h here... + // Alloca is hard to get, and we don't want to include stdlib.h here. Out << "/* get a declaration for alloca */\n" << "#if defined(__CYGWIN__)\n" << "extern void *_alloca(unsigned long);\n" @@ -885,6 +885,8 @@ << "#define LLVM_INFF __builtin_inff() /* Float */\n" << "#define LLVM_PREFETCH(addr,rw,locality) " "__builtin_prefetch(addr,rw,locality)\n" + << "#define __ATTRIBUTE_CTOR__ __attribute__((constructor))\n" + << "#define __ATTRIBUTE_DTOR__ __attribute__((destructor))\n" << "#else\n" << "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n" << "#define LLVM_NANF(NanStr) 0.0F /* Float */\n" @@ -893,6 +895,8 @@ << "#define LLVM_INF ((double)0.0) /* Double */\n" << "#define LLVM_INFF 0.0F /* Float */\n" << "#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */\n" + << "#define __ATTRIBUTE_CTOR__\n" + << "#define __ATTRIBUTE_DTOR__\n" << "#endif\n\n"; // Output target-specific code that should be inserted into main. @@ -908,6 +912,53 @@ } +/// FindStaticTors - Given a static ctor/dtor list, unpack its contents into +/// the StaticTors set. +static void FindStaticTors(GlobalVariable *GV, std::set &StaticTors){ + ConstantArray *InitList = dyn_cast(GV->getInitializer()); + if (!InitList) return; + + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + + if (CS->getOperand(1)->isNullValue()) + return; // Found a null terminator, exit printing. + Constant *FP = CS->getOperand(1); + if (ConstantExpr *CE = dyn_cast(FP)) + if (CE->getOpcode() == Instruction::Cast) + FP = CE->getOperand(0); + if (Function *F = dyn_cast(FP)) + StaticTors.insert(F); + } +} + +enum SpecialGlobalClass { + NotSpecial = 0, + GlobalCtors, GlobalDtors, + NotPrinted +}; + +/// getGlobalVariableClass - If this is a global that is specially recognized +/// by LLVM, return a code that indicates how we should handle it. +static SpecialGlobalClass getGlobalVariableClass(const GlobalVariable *GV) { + // If this is a global ctors/dtors list, handle it now. + if (GV->hasAppendingLinkage() && GV->use_empty()) { + if (GV->getName() == "llvm.global_ctors") + return GlobalCtors; + else if (GV->getName() == "llvm.global_dtors") + return GlobalDtors; + } + + // Otherwise, it it is other metadata, don't print it. This catches things + // like debug information. + if (GV->getSection() == "llvm.metadata") + return NotPrinted; + + return NotSpecial; +} + + bool CWriter::doInitialization(Module &M) { // Initialize TheModule = &M; @@ -918,6 +969,22 @@ Mang = new Mangler(M); Mang->markCharUnacceptable('.'); + // Keep track of which functions are static ctors/dtors so they can have + // an attribute added to their prototypes. + std::set StaticCtors, StaticDtors; + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + switch (getGlobalVariableClass(I)) { + default: break; + case GlobalCtors: + FindStaticTors(I, StaticCtors); + break; + case GlobalDtors: + FindStaticTors(I, StaticDtors); + break; + } + } + // get declaration for alloca Out << "/* Provide Declarations */\n"; Out << "#include \n"; // Varargs support @@ -955,20 +1022,22 @@ } // Function declarations + Out << "\n/* Function Declarations */\n"; Out << "double fmod(double, double);\n"; // Support for FP rem Out << "float fmodf(float, float);\n"; - if (!M.empty()) { - Out << "\n/* Function Declarations */\n"; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - // Don't print declarations for intrinsic functions. - if (!I->getIntrinsicID() && - I->getName() != "setjmp" && I->getName() != "longjmp") { - printFunctionSignature(I, true); - if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; - if (I->hasLinkOnceLinkage()) Out << " __ATTRIBUTE_WEAK__"; - Out << ";\n"; - } + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { + // Don't print declarations for intrinsic functions. + if (!I->getIntrinsicID() && + I->getName() != "setjmp" && I->getName() != "longjmp") { + printFunctionSignature(I, true); + if (I->hasWeakLinkage() || I->hasLinkOnceLinkage()) + Out << " __ATTRIBUTE_WEAK__"; + if (StaticCtors.count(I)) + Out << " __ATTRIBUTE_CTOR__"; + if (StaticDtors.count(I)) + Out << " __ATTRIBUTE_DTOR__"; + Out << ";\n"; } } @@ -978,6 +1047,10 @@ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isExternal()) { + // Ignore special globals, such as debug info. + if (getGlobalVariableClass(I)) + continue; + if (I->hasInternalLinkage()) Out << "static "; else @@ -998,6 +1071,10 @@ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isExternal()) { + // Ignore special globals, such as debug info. + if (getGlobalVariableClass(I)) + continue; + if (I->hasInternalLinkage()) Out << "static "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); From evan.cheng at apple.com Tue Mar 7 17:29:52 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 7 Mar 2006 17:29:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200603072329.RAA22644@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.103 -> 1.104 --- Log message: Use rep/stosl; and Count 0x3; rep/stosb for memset with 4 byte aligned dest. and variable value. Similarly for memcpy. --- Diffs of the changes: (+72 -12) X86ISelLowering.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 72 insertions(+), 12 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.103 llvm/lib/Target/X86/X86ISelLowering.cpp:1.104 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.103 Mon Mar 6 20:02:57 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Mar 7 17:29:39 2006 @@ -1711,7 +1711,7 @@ // If not DWORD aligned, call memset if size is less than the threshold. // It knows how to align to the right boundary first. if ((Align & 3) != 0 || - !(I && I->getValue() >= Subtarget->getMinRepStrSizeThreshold())) { + (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) { MVT::ValueType IntPtr = getPointerTy(); const Type *IntPtrTy = getTargetData().getIntPtrType(); std::vector > Args; @@ -1730,6 +1730,7 @@ SDOperand Count; ConstantSDNode *ValC = dyn_cast(Op.getOperand(2)); unsigned BytesLeft = 0; + bool TwoRepStos = false; if (ValC) { unsigned ValReg; unsigned Val = ValC->getValue() & 255; @@ -1745,8 +1746,14 @@ break; case 0: // DWORD aligned AVT = MVT::i32; - Count = DAG.getConstant(I->getValue() / 4, MVT::i32); - BytesLeft = I->getValue() % 4; + if (I) { + Count = DAG.getConstant(I->getValue() / 4, MVT::i32); + BytesLeft = I->getValue() % 4; + } else { + Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3), + DAG.getConstant(2, MVT::i8)); + TwoRepStos = true; + } Val = (Val << 8) | Val; Val = (Val << 16) | Val; ValReg = X86::EAX; @@ -1772,10 +1779,33 @@ InFlag = Chain.getValue(1); Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag); InFlag = Chain.getValue(1); - Chain = DAG.getNode(X86ISD::REP_STOS, MVT::Other, Chain, - DAG.getValueType(AVT), InFlag); - if (BytesLeft) { + std::vector Tys; + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(DAG.getValueType(AVT)); + Ops.push_back(InFlag); + Chain = DAG.getNode(X86ISD::REP_STOS, Tys, Ops); + + if (TwoRepStos) { + InFlag = Chain.getValue(1); + Count = Op.getOperand(3); + MVT::ValueType CVT = Count.getValueType(); + SDOperand Left = DAG.getNode(ISD::AND, CVT, Count, + DAG.getConstant(3, CVT)); + Chain = DAG.getCopyToReg(Chain, X86::ECX, Left, InFlag); + InFlag = Chain.getValue(1); + Tys.clear(); + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + Ops.clear(); + Ops.push_back(Chain); + Ops.push_back(DAG.getValueType(MVT::i8)); + Ops.push_back(InFlag); + Chain = DAG.getNode(X86ISD::REP_STOS, Tys, Ops); + } else if (BytesLeft) { // Issue stores for the last 1 - 3 bytes. SDOperand Value; unsigned Val = ValC->getValue() & 255; @@ -1813,7 +1843,7 @@ // If not DWORD aligned, call memcpy if size is less than the threshold. // It knows how to align to the right boundary first. if ((Align & 3) != 0 || - !(I && I->getValue() >= Subtarget->getMinRepStrSizeThreshold())) { + (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) { MVT::ValueType IntPtr = getPointerTy(); const Type *IntPtrTy = getTargetData().getIntPtrType(); std::vector > Args; @@ -1829,6 +1859,7 @@ MVT::ValueType AVT; SDOperand Count; unsigned BytesLeft = 0; + bool TwoRepMovs = false; switch (Align & 3) { case 2: // WORD aligned AVT = MVT::i16; @@ -1837,8 +1868,14 @@ break; case 0: // DWORD aligned AVT = MVT::i32; - Count = DAG.getConstant(I->getValue() / 4, MVT::i32); - BytesLeft = I->getValue() % 4; + if (I) { + Count = DAG.getConstant(I->getValue() / 4, MVT::i32); + BytesLeft = I->getValue() % 4; + } else { + Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3), + DAG.getConstant(2, MVT::i8)); + TwoRepMovs = true; + } break; default: // Byte aligned AVT = MVT::i8; @@ -1853,10 +1890,33 @@ InFlag = Chain.getValue(1); Chain = DAG.getCopyToReg(Chain, X86::ESI, Op.getOperand(2), InFlag); InFlag = Chain.getValue(1); - Chain = DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain, - DAG.getValueType(AVT), InFlag); - if (BytesLeft) { + std::vector Tys; + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(DAG.getValueType(AVT)); + Ops.push_back(InFlag); + Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, Ops); + + if (TwoRepMovs) { + InFlag = Chain.getValue(1); + Count = Op.getOperand(3); + MVT::ValueType CVT = Count.getValueType(); + SDOperand Left = DAG.getNode(ISD::AND, CVT, Count, + DAG.getConstant(3, CVT)); + Chain = DAG.getCopyToReg(Chain, X86::ECX, Left, InFlag); + InFlag = Chain.getValue(1); + Tys.clear(); + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + Ops.clear(); + Ops.push_back(Chain); + Ops.push_back(DAG.getValueType(MVT::i8)); + Ops.push_back(InFlag); + Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, Ops); + } else if (BytesLeft) { // Issue loads and stores for the last 1 - 3 bytes. unsigned Offset = I->getValue() - BytesLeft; SDOperand DstAddr = Op.getOperand(1); From evan.cheng at apple.com Tue Mar 7 17:34:37 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 7 Mar 2006 17:34:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200603072334.RAA22677@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.252 -> 1.253 --- Log message: X86ISD::REP_STOS and X86ISD::REP_MOVS now produces a flag. --- Diffs of the changes: (+2 -2) X86InstrInfo.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.252 llvm/lib/Target/X86/X86InstrInfo.td:1.253 --- llvm/lib/Target/X86/X86InstrInfo.td:1.252 Mon Mar 6 20:02:57 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Mar 7 17:34:23 2006 @@ -112,9 +112,9 @@ [SDNPHasChain]>; def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, - [SDNPHasChain, SDNPInFlag]>; + [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, - [SDNPHasChain, SDNPInFlag]>; + [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, [SDNPHasChain, SDNPOutFlag]>; From lattner at cs.uiuc.edu Tue Mar 7 18:26:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 18:26:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200603080026.SAA23111@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.69 -> 1.70 --- Log message: add a note --- Diffs of the changes: (+41 -0) README.txt | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.69 llvm/lib/Target/PowerPC/README.txt:1.70 --- llvm/lib/Target/PowerPC/README.txt:1.69 Mon Mar 6 22:42:59 2006 +++ llvm/lib/Target/PowerPC/README.txt Tue Mar 7 18:25:47 2006 @@ -466,3 +466,44 @@ This only matters when we start generating cr logical ops. +===-------------------------------------------------------------------------=== + +We should compile these two functions to the same thing: + +#include +void f(int a, int b, int *P) { + *P = (a-b)>=0?(a-b):(b-a); +} +void g(int a, int b, int *P) { + *P = abs(a-b); +} + +Further, they should compile to something better than: + +_g: + subf r2, r4, r3 + subfic r3, r2, 0 + cmpwi cr0, r2, -1 + bgt cr0, LBB2_2 ; entry +LBB2_1: ; entry + mr r2, r3 +LBB2_2: ; entry + stw r2, 0(r5) + blr + +GCC produces: + +_g: + subf r4,r4,r3 + srawi r2,r4,31 + xor r0,r2,r4 + subf r0,r2,r0 + stw r0,0(r5) + blr + +... which is much nicer. + +This theoretically may help improve twolf slightly (used in dimbox.c:142?). + +===-------------------------------------------------------------------------=== + From lattner at cs.uiuc.edu Tue Mar 7 19:05:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 19:05:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200603080105.TAA24642@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ScalarReplAggregates.cpp updated: 1.36 -> 1.37 --- Log message: Fix a miscompilation of 188.ammp with the new CFE. 188.ammp is accessing arrays out of range in a horrible way, but we shouldn't break it anyway. Details in the comments. --- Diffs of the changes: (+19 -3) ScalarReplAggregates.cpp | 22 +++++++++++++++++++--- 1 files changed, 19 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.36 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.37 --- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.36 Tue Jan 24 13:36:27 2006 +++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Mar 7 19:05:29 2006 @@ -289,7 +289,7 @@ GetElementPtrInst *GEPI = cast(User); gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI); - // The GEP is safe to transform if it is of the form GEP , 0, + // The GEP is not safe to transform if not of the form "GEP , 0, ". if (I == E || I.getOperand() != Constant::getNullValue(I.getOperand()->getType())) return 0; @@ -308,13 +308,29 @@ if (cast(GEPI->getOperand(2))->getRawValue() >= NumElements) return 0; + // We cannot scalar repl this level of the array unless any array + // sub-indices are in-range constants. In particular, consider: + // A[0][i]. We cannot know that the user isn't doing invalid things like + // allowing i to index an out-of-range subscript that accesses A[1]. + // + // Scalar replacing *just* the outer index of the array is probably not + // going to be a win anyway, so just give up. + for (++I; I != E && isa(*I); ++I) { + const ArrayType *SubArrayTy = cast(*I); + uint64_t NumElements = SubArrayTy->getNumElements(); + if (!isa(I.getOperand())) return 0; + if (cast(I.getOperand())->getRawValue() >= NumElements) + return 0; + } + } else { // If this is an array index and the index is not constant, we cannot // promote... that is unless the array has exactly one or two elements in // it, in which case we CAN promote it, but we have to canonicalize this // out if this is the only problem. - if (NumElements == 1 || NumElements == 2) - return AllUsersAreLoads(GEPI) ? 1 : 0; // Canonicalization required! + if ((NumElements == 1 || NumElements == 2) && + AllUsersAreLoads(GEPI)) + return 1; // Canonicalization required! return 0; } } From jlaskey at apple.com Tue Mar 7 20:07:15 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 7 Mar 2006 20:07:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineDebugInfo.cpp Message-ID: <200603080207.UAA24990@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineDebugInfo.cpp updated: 1.25 -> 1.26 --- Log message: libstdc++-v3 was failing to build. Needed to handle composite types with empty members (running into a zero initializer.) --- Diffs of the changes: (+8 -5) MachineDebugInfo.cpp | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.25 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.26 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.25 Tue Mar 7 16:00:35 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Tue Mar 7 20:07:02 2006 @@ -263,12 +263,15 @@ virtual void Apply(std::vector &Field) { Constant *C = CI->getOperand(I++); GlobalVariable *GV = getGlobalVariable(C); - ConstantArray *CA = cast(GV->getInitializer()); Field.resize(0); - for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) { - GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); - DebugInfoDesc *DE = DR.Deserialize(GVE); - Field.push_back(DE); + // Have to be able to deal with the empty array case (zero initializer) + if (!GV->hasInitializer()) return; + if (ConstantArray *CA = dyn_cast(GV->getInitializer())) { + for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) { + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + DebugInfoDesc *DE = DR.Deserialize(GVE); + Field.push_back(DE); + } } } }; From lattner at cs.uiuc.edu Tue Mar 7 22:25:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:25:07 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h SelectionDAGISel.h Message-ID: <200603080425.WAA25847@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.14 -> 1.15 SelectionDAGISel.h updated: 1.10 -> 1.11 --- Log message: Change the interface for getting a target HazardRecognizer to be more clean. --- Diffs of the changes: (+6 -9) ScheduleDAG.h | 9 +++------ SelectionDAGISel.h | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.14 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.15 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.14 Sun Mar 5 18:20:29 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Tue Mar 7 22:24:56 2006 @@ -57,10 +57,6 @@ NoopHazard, // This instruction can't be emitted, and needs noops. }; - /// StartBasicBlock - This is called when a new basic block is started. - /// - virtual void StartBasicBlock() {} - /// getHazardType - Return the hazard type of emitting this node. There are /// three possible results. Either: /// * NoHazard: it is legal to issue this instruction on this cycle. @@ -410,10 +406,11 @@ MachineBasicBlock *BB); /// createTDListDAGScheduler - This creates a top-down list scheduler with - /// the specified hazard recognizer. + /// the specified hazard recognizer. This takes ownership of the hazard + /// recognizer and deletes it when done. ScheduleDAG* createTDListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB, - HazardRecognizer &HR); + HazardRecognizer *HR); } #endif Index: llvm/include/llvm/CodeGen/SelectionDAGISel.h diff -u llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.10 llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.11 --- llvm/include/llvm/CodeGen/SelectionDAGISel.h:1.10 Sun Mar 5 18:20:29 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGISel.h Tue Mar 7 22:24:56 2006 @@ -62,9 +62,9 @@ return true; } - /// GetTargetHazardRecognizer - Return the hazard recognizer to use for this - /// target when scheduling the DAG. - virtual HazardRecognizer &GetTargetHazardRecognizer(); + /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer + /// to use for this target when scheduling the DAG. + virtual HazardRecognizer *CreateTargetHazardRecognizer(); protected: /// Pick a safe ordering and emit instructions for each target node in the From lattner at cs.uiuc.edu Tue Mar 7 22:25:56 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:25:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp SelectionDAGISel.cpp Message-ID: <200603080425.WAA25934@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.72 -> 1.73 ScheduleDAGList.cpp updated: 1.20 -> 1.21 SelectionDAGISel.cpp updated: 1.181 -> 1.182 --- Log message: Change the interface for getting a target HazardRecognizer to be more clean. --- Diffs of the changes: (+15 -18) ScheduleDAG.cpp | 2 +- ScheduleDAGList.cpp | 23 +++++++++++------------ SelectionDAGISel.cpp | 8 +++----- 3 files changed, 15 insertions(+), 18 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.72 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.73 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.72 Sun Mar 5 17:51:47 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Tue Mar 7 22:25:44 2006 @@ -14,9 +14,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sched" +#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.20 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.21 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.20 Mon Mar 6 23:40:43 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Mar 7 22:25:44 2006 @@ -178,7 +178,7 @@ bool isBottomUp; /// HazardRec - The hazard recognizer to use. - HazardRecognizer &HazardRec; + HazardRecognizer *HazardRec; typedef std::priority_queue, ls_rr_sort> AvailableQueueTy; @@ -186,7 +186,7 @@ public: ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, - HazardRecognizer &HR) + HazardRecognizer *HR) : ScheduleDAG(listSchedulingBURR, dag, bb, tm), CurrCycle(0), HeadSUnit(NULL), TailSUnit(NULL), isBottomUp(isbottomup), HazardRec(HR) { @@ -199,6 +199,7 @@ delete SU; SU = NextSU; } + delete HazardRec; } void Schedule(); @@ -413,12 +414,10 @@ // Available queue. AvailableQueueTy Available; - HazardRec.StartBasicBlock(); - // Emit the entry node first. SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; ScheduleNodeTopDown(Available, Entry); - HazardRec.EmitInstruction(Entry->Node); + HazardRec->EmitInstruction(Entry->Node); // All leaves to Available queue. for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { @@ -446,7 +445,7 @@ N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i) N = CurNode->FlaggedNodes[i]; - HazardRecognizer::HazardType HT = HazardRec.getHazardType(N); + HazardRecognizer::HazardType HT = HazardRec->getHazardType(N); if (HT == HazardRecognizer::NoHazard) { FoundNode = CurNode; break; @@ -467,19 +466,19 @@ // If we found a node to schedule, do it now. if (FoundNode) { ScheduleNodeTopDown(Available, FoundNode); - HazardRec.EmitInstruction(FoundNode->Node); + HazardRec->EmitInstruction(FoundNode->Node); } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. DEBUG(std::cerr << "*** Advancing cycle, no work to do\n"); - HazardRec.AdvanceCycle(); + HazardRec->AdvanceCycle(); ++NumStalls; } else { // Otherwise, we have no instructions to issue and we have instructions // that will fault if we don't do this right. This is the case for // processors without pipeline interlocks and other cases. DEBUG(std::cerr << "*** Emitting noop\n"); - HazardRec.EmitNoop(); + HazardRec->EmitNoop(); Sequence.push_back(0); // NULL SUnit* -> noop ++NumNoops; } @@ -691,14 +690,14 @@ llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB) { - HazardRecognizer HR; - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, HR); + return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, + new HazardRecognizer()); } /// createTDListDAGScheduler - This creates a top-down list scheduler with the /// specified hazard recognizer. ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB, - HazardRecognizer &HR) { + HazardRecognizer *HR) { return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, HR); } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.181 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.182 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.181 Sun Mar 5 18:22:00 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Mar 7 22:25:44 2006 @@ -2474,17 +2474,15 @@ SL = createBURRListDAGScheduler(DAG, BB); break; case listSchedulingTD: - SL = createTDListDAGScheduler(DAG, BB, GetTargetHazardRecognizer()); + SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer()); break; } BB = SL->Run(); delete SL; } -HazardRecognizer &SelectionDAGISel:: -GetTargetHazardRecognizer() { - static HazardRecognizer DefaultRecognizer; - return DefaultRecognizer; +HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() { + return new HazardRecognizer(); } /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated From lattner at cs.uiuc.edu Tue Mar 7 22:26:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:26:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp PPCHazardRecognizers.h PPCISelDAGToDAG.cpp Message-ID: <200603080426.WAA25948@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.6 -> 1.7 PPCHazardRecognizers.h updated: 1.3 -> 1.4 PPCISelDAGToDAG.cpp updated: 1.162 -> 1.163 --- Log message: Change the interface for getting a target HazardRecognizer to be more clean. --- Diffs of the changes: (+8 -11) PPCHazardRecognizers.cpp | 10 ++++------ PPCHazardRecognizers.h | 2 +- PPCISelDAGToDAG.cpp | 7 +++---- 3 files changed, 8 insertions(+), 11 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.6 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.7 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.6 Tue Mar 7 10:26:48 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Mar 7 22:25:59 2006 @@ -50,6 +50,10 @@ // e.g. integer divides that only execute in the second slot. // +PPCHazardRecognizer970::PPCHazardRecognizer970() { + EndDispatchGroup(); +} + void PPCHazardRecognizer970::EndDispatchGroup() { DEBUG(std::cerr << "=== Start of dispatch group\n"); // Pipeline units. @@ -117,12 +121,6 @@ return FXU; } - -/// StartBasicBlock - Initiate a new dispatch group. -void PPCHazardRecognizer970::StartBasicBlock() { - EndDispatchGroup(); -} - /// isLoadOfStoredAddress - If we have a load from the previously stored pointer /// as indicated by StorePtr1/StorePtr2/StoreSize, return true. bool PPCHazardRecognizer970:: Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.3 llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.4 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.3 Tue Mar 7 10:19:46 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.h Tue Mar 7 22:25:59 2006 @@ -52,7 +52,7 @@ unsigned StoreSize; public: - virtual void StartBasicBlock(); + PPCHazardRecognizer970(); virtual HazardType getHazardType(SDNode *Node); virtual void EmitInstruction(SDNode *Node); virtual void AdvanceCycle(); Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.162 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.163 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.162 Tue Mar 7 00:32:48 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Mar 7 22:25:59 2006 @@ -41,7 +41,6 @@ class PPCDAGToDAGISel : public SelectionDAGISel { PPCTargetLowering PPCLowering; unsigned GlobalBaseReg; - PPCHazardRecognizer970 PPC970HR; public: PPCDAGToDAGISel(TargetMachine &TM) : SelectionDAGISel(PPCLowering), PPCLowering(TM) {} @@ -125,12 +124,12 @@ return "PowerPC DAG->DAG Pattern Instruction Selection"; } - /// GetTargetHazardRecognizer - Return the hazard recognizer to use for this + /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for this /// target when scheduling the DAG. - virtual HazardRecognizer &GetTargetHazardRecognizer() { + virtual HazardRecognizer *CreateTargetHazardRecognizer() { // Should use subtarget info to pick the right hazard recognizer. For // now, always return a PPC970 recognizer. - return PPC970HR; + return new PPCHazardRecognizer970(); } // Include the pieces autogenerated from the target description. From lattner at cs.uiuc.edu Tue Mar 7 22:38:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:38:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp ScheduleDAGList.cpp Message-ID: <200603080438.WAA26121@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.311 -> 1.312 ScheduleDAGList.cpp updated: 1.21 -> 1.22 --- Log message: remove "Slot", it is dead --- Diffs of the changes: (+56 -34) LegalizeDAG.cpp | 27 ++++++++++++++++++++-- ScheduleDAGList.cpp | 63 +++++++++++++++++++++++++--------------------------- 2 files changed, 56 insertions(+), 34 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.311 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.312 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.311 Sat Mar 4 23:09:38 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Mar 7 22:37:58 2006 @@ -1795,10 +1795,33 @@ case TargetLowering::Custom: Tmp1 = TLI.LowerOperation(Result, DAG); if (Tmp1.Val) Result = Tmp1; - break; + break; case TargetLowering::Legal: break; case TargetLowering::Expand: - // Floating point mod -> fmod libcall. + // If this target supports fabs/fneg natively, do this efficiently. + if (TLI.isOperationLegal(ISD::FABS, Tmp1.getValueType()) && + TLI.isOperationLegal(ISD::FNEG, Tmp1.getValueType())) { + // Get the sign bit of the RHS. + MVT::ValueType IVT = + Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64; + SDOperand SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2); + SignBit = DAG.getSetCC(TLI.getSetCCResultTy(), + SignBit, DAG.getConstant(0, IVT), ISD::SETLT); + // Get the absolute value of the result. + SDOperand AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1); + // Select between the nabs and abs value based on the sign bit of + // the input. + Result = DAG.getNode(ISD::SELECT, AbsVal.getValueType(), SignBit, + DAG.getNode(ISD::FNEG, AbsVal.getValueType(), + AbsVal), + AbsVal); + Result = LegalizeOp(Result); + break; + } + + // Otherwise, do bitwise ops! + + // copysign -> copysignf/copysign libcall. const char *FnName; if (Node->getValueType(0) == MVT::f32) { FnName = "copysignf"; Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.21 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.22 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.21 Tue Mar 7 22:25:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Mar 7 22:37:58 2006 @@ -20,7 +20,6 @@ #define DEBUG_TYPE "sched" #include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" @@ -36,36 +35,36 @@ Statistic<> NumNoops ("scheduler", "Number of noops inserted"); Statistic<> NumStalls("scheduler", "Number of pipeline stalls"); -/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or a -/// group of nodes flagged together. -struct SUnit { - SDNode *Node; // Representative node. - std::vector FlaggedNodes; // All nodes flagged to Node. - std::set Preds; // All real predecessors. - std::set ChainPreds; // All chain predecessors. - std::set Succs; // All real successors. - std::set ChainSuccs; // All chain successors. - int NumPredsLeft; // # of preds not scheduled. - int NumSuccsLeft; // # of succs not scheduled. - int NumChainPredsLeft; // # of chain preds not scheduled. - int NumChainSuccsLeft; // # of chain succs not scheduled. - int SethiUllman; // Sethi Ullman number. - bool isTwoAddress; // Is a two-address instruction. - bool isDefNUseOperand; // Is a def&use operand. - unsigned Latency; // Node latency. - unsigned CycleBound; // Upper/lower cycle to be scheduled at. - unsigned Slot; // Cycle node is scheduled at. - SUnit *Next; - - SUnit(SDNode *node) - : Node(node), NumPredsLeft(0), NumSuccsLeft(0), + /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or a + /// group of nodes flagged together. + struct SUnit { + SDNode *Node; // Representative node. + std::vector FlaggedNodes; // All nodes flagged to Node. + std::set Preds; // All real predecessors. + std::set ChainPreds; // All chain predecessors. + std::set Succs; // All real successors. + std::set ChainSuccs; // All chain successors. + int NumPredsLeft; // # of preds not scheduled. + int NumSuccsLeft; // # of succs not scheduled. + int NumChainPredsLeft; // # of chain preds not scheduled. + int NumChainSuccsLeft; // # of chain succs not scheduled. + int SethiUllman; // Sethi Ullman number. + bool isTwoAddress; // Is a two-address instruction. + bool isDefNUseOperand; // Is a def&use operand. + unsigned Latency; // Node latency. + unsigned CycleBound; // Upper/lower cycle to be scheduled at. + SUnit *Next; + + SUnit(SDNode *node) + : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), SethiUllman(INT_MIN), isTwoAddress(false), isDefNUseOperand(false), - Latency(0), CycleBound(0), Slot(0), Next(NULL) {} - - void dump(const SelectionDAG *G, bool All=true) const; -}; + Latency(0), CycleBound(0), Next(NULL) {} + + void dump(const SelectionDAG *G, bool All=true) const; + }; +} void SUnit::dump(const SelectionDAG *G, bool All) const { std::cerr << "SU: "; @@ -122,6 +121,7 @@ } } +namespace { /// Sorting functions for the Available queue. struct ls_rr_sort : public std::binary_function { bool operator()(const SUnit* left, const SUnit* right) const { @@ -159,8 +159,10 @@ return false; } }; +} // end anonymous namespace +namespace { /// ScheduleDAGList - List scheduler. class ScheduleDAGList : public ScheduleDAG { private: @@ -219,7 +221,7 @@ void BuildSchedUnits(); void EmitSchedule(); }; -} // end namespace +} // end anonymous namespace HazardRecognizer::~HazardRecognizer() {} @@ -305,7 +307,6 @@ DEBUG(SU->dump(&DAG, false)); Sequence.push_back(SU); - SU->Slot = CurrCycle; // Bottom up: release predecessors for (std::set::iterator I1 = SU->Preds.begin(), @@ -329,7 +330,6 @@ DEBUG(SU->dump(&DAG, false)); Sequence.push_back(SU); - SU->Slot = CurrCycle; // Bottom up: release successors. for (std::set::iterator I1 = SU->Succs.begin(), @@ -384,7 +384,6 @@ // Add entry node last if (DAG.getEntryNode().Val != DAG.getRoot().Val) { SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; - Entry->Slot = CurrCycle; Sequence.push_back(Entry); } From lattner at cs.uiuc.edu Tue Mar 7 22:39:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:39:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200603080439.WAA26231@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.312 -> 1.313 --- Log message: revert the previous patch, didn't mean to check it in yet --- Diffs of the changes: (+2 -25) LegalizeDAG.cpp | 27 ++------------------------- 1 files changed, 2 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.312 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.313 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.312 Tue Mar 7 22:37:58 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Mar 7 22:39:05 2006 @@ -1795,33 +1795,10 @@ case TargetLowering::Custom: Tmp1 = TLI.LowerOperation(Result, DAG); if (Tmp1.Val) Result = Tmp1; - break; + break; case TargetLowering::Legal: break; case TargetLowering::Expand: - // If this target supports fabs/fneg natively, do this efficiently. - if (TLI.isOperationLegal(ISD::FABS, Tmp1.getValueType()) && - TLI.isOperationLegal(ISD::FNEG, Tmp1.getValueType())) { - // Get the sign bit of the RHS. - MVT::ValueType IVT = - Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64; - SDOperand SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2); - SignBit = DAG.getSetCC(TLI.getSetCCResultTy(), - SignBit, DAG.getConstant(0, IVT), ISD::SETLT); - // Get the absolute value of the result. - SDOperand AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1); - // Select between the nabs and abs value based on the sign bit of - // the input. - Result = DAG.getNode(ISD::SELECT, AbsVal.getValueType(), SignBit, - DAG.getNode(ISD::FNEG, AbsVal.getValueType(), - AbsVal), - AbsVal); - Result = LegalizeOp(Result); - break; - } - - // Otherwise, do bitwise ops! - - // copysign -> copysignf/copysign libcall. + // Floating point mod -> fmod libcall. const char *FnName; if (Node->getValueType(0) == MVT::f32) { FnName = "copysignf"; From lattner at cs.uiuc.edu Tue Mar 7 22:41:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:41:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603080441.WAA26349@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.22 -> 1.23 --- Log message: Shrinkify some fields, fit to 80 columns --- Diffs of the changes: (+11 -11) ScheduleDAGList.cpp | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.22 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.23 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.22 Tue Mar 7 22:37:58 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Mar 7 22:41:06 2006 @@ -35,8 +35,8 @@ Statistic<> NumNoops ("scheduler", "Number of noops inserted"); Statistic<> NumStalls("scheduler", "Number of pipeline stalls"); - /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or a - /// group of nodes flagged together. + /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or + /// a group of nodes flagged together. struct SUnit { SDNode *Node; // Representative node. std::vector FlaggedNodes; // All nodes flagged to Node. @@ -44,14 +44,14 @@ std::set ChainPreds; // All chain predecessors. std::set Succs; // All real successors. std::set ChainSuccs; // All chain successors. - int NumPredsLeft; // # of preds not scheduled. - int NumSuccsLeft; // # of succs not scheduled. - int NumChainPredsLeft; // # of chain preds not scheduled. - int NumChainSuccsLeft; // # of chain succs not scheduled. + short NumPredsLeft; // # of preds not scheduled. + short NumSuccsLeft; // # of succs not scheduled. + short NumChainPredsLeft; // # of chain preds not scheduled. + short NumChainSuccsLeft; // # of chain succs not scheduled. int SethiUllman; // Sethi Ullman number. - bool isTwoAddress; // Is a two-address instruction. - bool isDefNUseOperand; // Is a def&use operand. - unsigned Latency; // Node latency. + bool isTwoAddress : 1; // Is a two-address instruction. + bool isDefNUseOperand : 1; // Is a def&use operand. + unsigned short Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. SUnit *Next; @@ -247,7 +247,7 @@ // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound, CurrCycle + PredSU->Latency); + PredSU->CycleBound = std::max(PredSU->CycleBound,CurrCycle + PredSU->Latency); if (!isChain) PredSU->NumSuccsLeft--; @@ -278,7 +278,7 @@ // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the // interrupt model (drain vs. freeze). - SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurrCycle + SuccSU->Latency); + SuccSU->CycleBound = std::max(SuccSU->CycleBound,CurrCycle + SuccSU->Latency); if (!isChain) SuccSU->NumPredsLeft--; From lattner at cs.uiuc.edu Tue Mar 7 22:54:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 22:54:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603080454.WAA26544@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.23 -> 1.24 --- Log message: switch from an explicitly managed list of SUnits to a simple vector of sunits --- Diffs of the changes: (+28 -35) ScheduleDAGList.cpp | 63 +++++++++++++++++++++++----------------------------- 1 files changed, 28 insertions(+), 35 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.23 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.24 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.23 Tue Mar 7 22:41:06 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Mar 7 22:54:34 2006 @@ -53,14 +53,13 @@ bool isDefNUseOperand : 1; // Is a def&use operand. unsigned short Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. - SUnit *Next; SUnit(SDNode *node) : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), SethiUllman(INT_MIN), isTwoAddress(false), isDefNUseOperand(false), - Latency(0), CycleBound(0), Next(NULL) {} + Latency(0), CycleBound(0) {} void dump(const SelectionDAG *G, bool All=true) const; }; @@ -172,8 +171,9 @@ std::vector Sequence; // Current scheduling cycle. unsigned CurrCycle; - // First and last SUnit created. - SUnit *HeadSUnit, *TailSUnit; + + // The scheduling units. + std::vector SUnits; /// isBottomUp - This is true if the scheduling problem is bottom-up, false if /// it is top-down. @@ -190,17 +190,10 @@ const TargetMachine &tm, bool isbottomup, HazardRecognizer *HR) : ScheduleDAG(listSchedulingBURR, dag, bb, tm), - CurrCycle(0), HeadSUnit(NULL), TailSUnit(NULL), isBottomUp(isbottomup), - HazardRec(HR) { + CurrCycle(0), isBottomUp(isbottomup), HazardRec(HR) { } ~ScheduleDAGList() { - SUnit *SU = HeadSUnit; - while (SU) { - SUnit *NextSU = SU->Next; - delete SU; - SU = NextSU; - } delete HazardRec; } @@ -228,15 +221,8 @@ /// NewSUnit - Creates a new SUnit and return a ptr to it. SUnit *ScheduleDAGList::NewSUnit(SDNode *N) { - SUnit *CurrSUnit = new SUnit(N); - - if (HeadSUnit == NULL) - HeadSUnit = CurrSUnit; - if (TailSUnit != NULL) - TailSUnit->Next = CurrSUnit; - TailSUnit = CurrSUnit; - - return CurrSUnit; + SUnits.push_back(N); + return &SUnits.back(); } /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to @@ -394,11 +380,11 @@ #ifndef NDEBUG // Verify that all SUnits were scheduled. bool AnyNotSched = false; - for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { - if (SU->NumSuccsLeft != 0 || SU->NumChainSuccsLeft != 0) { + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + if (SUnits[i].NumSuccsLeft != 0 || SUnits[i].NumChainSuccsLeft != 0) { if (!AnyNotSched) std::cerr << "*** List scheduling failed! ***\n"; - SU->dump(&DAG); + SUnits[i].dump(&DAG); std::cerr << "has not been scheduled!\n"; AnyNotSched = true; } @@ -419,10 +405,11 @@ HazardRec->EmitInstruction(Entry->Node); // All leaves to Available queue. - for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // It is available if it has no predecessors. - if ((SU->Preds.size() + SU->ChainPreds.size()) == 0 && SU != Entry) - Available.push(SU); + if ((SUnits[i].Preds.size() + SUnits[i].ChainPreds.size()) == 0 && + &SUnits[i] != Entry) + Available.push(&SUnits[i]); } // While Available queue is not empty, grab the node with the highest @@ -486,11 +473,11 @@ #ifndef NDEBUG // Verify that all SUnits were scheduled. bool AnyNotSched = false; - for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { - if (SU->NumPredsLeft != 0 || SU->NumChainPredsLeft != 0) { + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + if (SUnits[i].NumPredsLeft != 0 || SUnits[i].NumChainPredsLeft != 0) { if (!AnyNotSched) std::cerr << "*** List scheduling failed! ***\n"; - SU->dump(&DAG); + SUnits[i].dump(&DAG); std::cerr << "has not been scheduled!\n"; AnyNotSched = true; } @@ -532,16 +519,21 @@ /// CalculatePriorities - Calculate priorities of all scheduling units. void ScheduleDAGList::CalculatePriorities() { - for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // FIXME: assumes uniform latency for now. - SU->Latency = 1; - (void)CalcNodePriority(SU); - DEBUG(SU->dump(&DAG)); + SUnits[i].Latency = 1; + (void)CalcNodePriority(&SUnits[i]); + DEBUG(SUnits[i].dump(&DAG)); DEBUG(std::cerr << "\n"); } } void ScheduleDAGList::BuildSchedUnits() { + // Reserve entries in the vector for each of the SUnits we are creating. This + // ensure that reallocation of the vector won't happen, so SUnit*'s won't get + // invalidated. + SUnits.reserve(NodeCount); + // Pass 1: create the SUnit's. for (unsigned i = 0, NC = NodeCount; i < NC; i++) { NodeInfo *NI = &Info[i]; @@ -576,7 +568,8 @@ } // Pass 2: add the preds, succs, etc. - for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + SUnit *SU = &SUnits[i]; SDNode *N = SU->Node; NodeInfo *NI = getNI(N); From lattner at cs.uiuc.edu Tue Mar 7 23:18:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 7 Mar 2006 23:18:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603080518.XAA26793@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.24 -> 1.25 --- Log message: Split the priority function computation and priority queue management out of the ScheduleDAGList class into a new SchedulingPriorityQueue class. --- Diffs of the changes: (+152 -115) ScheduleDAGList.cpp | 267 +++++++++++++++++++++++++++++----------------------- 1 files changed, 152 insertions(+), 115 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.24 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.25 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.24 Tue Mar 7 22:54:34 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue Mar 7 23:18:27 2006 @@ -48,18 +48,17 @@ short NumSuccsLeft; // # of succs not scheduled. short NumChainPredsLeft; // # of chain preds not scheduled. short NumChainSuccsLeft; // # of chain succs not scheduled. - int SethiUllman; // Sethi Ullman number. bool isTwoAddress : 1; // Is a two-address instruction. bool isDefNUseOperand : 1; // Is a def&use operand. unsigned short Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. + unsigned NodeNum; // Entry # of node in the node vector. - SUnit(SDNode *node) + SUnit(SDNode *node, unsigned nodenum) : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), - SethiUllman(INT_MIN), isTwoAddress(false), isDefNUseOperand(false), - Latency(0), CycleBound(0) {} + Latency(0), CycleBound(0), NodeNum(nodenum) {} void dump(const SelectionDAG *G, bool All=true) const; }; @@ -83,7 +82,6 @@ std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n"; std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n"; std::cerr << " Latency : " << Latency << "\n"; - std::cerr << " SethiUllman : " << SethiUllman << "\n"; if (Preds.size() != 0) { std::cerr << " Predecessors:\n"; @@ -121,44 +119,137 @@ } namespace { -/// Sorting functions for the Available queue. -struct ls_rr_sort : public std::binary_function { - bool operator()(const SUnit* left, const SUnit* right) const { - int LBonus = (int)left ->isDefNUseOperand; - int RBonus = (int)right->isDefNUseOperand; - - // Special tie breaker: if two nodes share a operand, the one that - // use it as a def&use operand is preferred. - if (left->isTwoAddress && !right->isTwoAddress) { - SDNode *DUNode = left->Node->getOperand(0).Val; - if (DUNode->isOperand(right->Node)) - LBonus++; - } - if (!left->isTwoAddress && right->isTwoAddress) { - SDNode *DUNode = right->Node->getOperand(0).Val; - if (DUNode->isOperand(left->Node)) - RBonus++; - } - - // Priority1 is just the number of live range genned. - int LPriority1 = left ->NumPredsLeft - LBonus; - int RPriority1 = right->NumPredsLeft - RBonus; - int LPriority2 = left ->SethiUllman + LBonus; - int RPriority2 = right->SethiUllman + RBonus; + class SchedulingPriorityQueue; + + /// Sorting functions for the Available queue. + struct ls_rr_sort : public std::binary_function { + SchedulingPriorityQueue *SPQ; + ls_rr_sort(SchedulingPriorityQueue *spq) : SPQ(spq) {} + ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} + + bool operator()(const SUnit* left, const SUnit* right) const; + }; +} // end anonymous namespace - if (LPriority1 > RPriority1) +namespace { + class SchedulingPriorityQueue { + // SUnits - The SUnits for the current graph. + std::vector &SUnits; + + // SethiUllmanNumbers - The SethiUllman number for each node. + std::vector SethiUllmanNumbers; + + std::priority_queue, ls_rr_sort> Queue; + public: + SchedulingPriorityQueue(std::vector &sunits) + : SUnits(sunits), Queue(ls_rr_sort(this)) { + // Calculate node priorities. + CalculatePriorities(); + } + + unsigned getSethiUllmanNumber(unsigned NodeNum) const { + assert(NodeNum < SethiUllmanNumbers.size()); + return SethiUllmanNumbers[NodeNum]; + } + + bool empty() const { return Queue.empty(); } + + void push(SUnit *U) { + Queue.push(U); + } + SUnit *pop() { + SUnit *V = Queue.top(); + Queue.pop(); + return V; + } + private: + void CalculatePriorities(); + int CalcNodePriority(SUnit *SU); + }; +} + +bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { + unsigned LeftNum = left->NodeNum; + unsigned RightNum = right->NodeNum; + + int LBonus = (int)left ->isDefNUseOperand; + int RBonus = (int)right->isDefNUseOperand; + + // Special tie breaker: if two nodes share a operand, the one that + // use it as a def&use operand is preferred. + if (left->isTwoAddress && !right->isTwoAddress) { + SDNode *DUNode = left->Node->getOperand(0).Val; + if (DUNode->isOperand(right->Node)) + LBonus++; + } + if (!left->isTwoAddress && right->isTwoAddress) { + SDNode *DUNode = right->Node->getOperand(0).Val; + if (DUNode->isOperand(left->Node)) + RBonus++; + } + + // Priority1 is just the number of live range genned. + int LPriority1 = left ->NumPredsLeft - LBonus; + int RPriority1 = right->NumPredsLeft - RBonus; + int LPriority2 = SPQ->getSethiUllmanNumber(LeftNum) + LBonus; + int RPriority2 = SPQ->getSethiUllmanNumber(RightNum) + RBonus; + + if (LPriority1 > RPriority1) + return true; + else if (LPriority1 == RPriority1) + if (LPriority2 < RPriority2) return true; - else if (LPriority1 == RPriority1) - if (LPriority2 < RPriority2) + else if (LPriority2 == RPriority2) + if (left->CycleBound > right->CycleBound) return true; - else if (LPriority2 == RPriority2) - if (left->CycleBound > right->CycleBound) - return true; + + return false; +} + - return false; +/// CalcNodePriority - Priority is the Sethi Ullman number. +/// Smaller number is the higher priority. +int SchedulingPriorityQueue::CalcNodePriority(SUnit *SU) { + int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; + if (SethiUllmanNumber != INT_MIN) + return SethiUllmanNumber; + + if (SU->Preds.size() == 0) { + SethiUllmanNumber = 1; + } else { + int Extra = 0; + for (std::set::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) { + SUnit *PredSU = *I; + int PredSethiUllman = CalcNodePriority(PredSU); + if (PredSethiUllman > SethiUllmanNumber) { + SethiUllmanNumber = PredSethiUllman; + Extra = 0; + } else if (PredSethiUllman == SethiUllmanNumber) + Extra++; + } + + if (SU->Node->getOpcode() != ISD::TokenFactor) + SethiUllmanNumber += Extra; + else + SethiUllmanNumber = (Extra == 1) ? 0 : Extra-1; } -}; -} // end anonymous namespace + + return SethiUllmanNumber; +} + +/// CalculatePriorities - Calculate priorities of all scheduling units. +void SchedulingPriorityQueue::CalculatePriorities() { + SethiUllmanNumbers.assign(SUnits.size(), INT_MIN); + + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + // FIXME: assumes uniform latency for now. + SUnits[i].Latency = 1; + (void)CalcNodePriority(&SUnits[i]); + } +} + + namespace { @@ -182,9 +273,6 @@ /// HazardRec - The hazard recognizer to use. HazardRecognizer *HazardRec; - typedef std::priority_queue, ls_rr_sort> - AvailableQueueTy; - public: ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, @@ -203,14 +291,14 @@ private: SUnit *NewSUnit(SDNode *N); - void ReleasePred(AvailableQueueTy &Avail,SUnit *PredSU, bool isChain = false); - void ReleaseSucc(AvailableQueueTy &Avail,SUnit *SuccSU, bool isChain = false); - void ScheduleNodeBottomUp(AvailableQueueTy &Avail, SUnit *SU); - void ScheduleNodeTopDown(AvailableQueueTy &Avail, SUnit *SU); - int CalcNodePriority(SUnit *SU); - void CalculatePriorities(); - void ListScheduleTopDown(); - void ListScheduleBottomUp(); + void ReleasePred(SchedulingPriorityQueue &Avail, + SUnit *PredSU, bool isChain = false); + void ReleaseSucc(SchedulingPriorityQueue &Avail, + SUnit *SuccSU, bool isChain = false); + void ScheduleNodeBottomUp(SchedulingPriorityQueue &Avail, SUnit *SU); + void ScheduleNodeTopDown(SchedulingPriorityQueue &Avail, SUnit *SU); + void ListScheduleTopDown(SchedulingPriorityQueue &Available); + void ListScheduleBottomUp(SchedulingPriorityQueue &Available); void BuildSchedUnits(); void EmitSchedule(); }; @@ -221,13 +309,13 @@ /// NewSUnit - Creates a new SUnit and return a ptr to it. SUnit *ScheduleDAGList::NewSUnit(SDNode *N) { - SUnits.push_back(N); + SUnits.push_back(SUnit(N, SUnits.size())); return &SUnits.back(); } /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleasePred(AvailableQueueTy &Available, +void ScheduleDAGList::ReleasePred(SchedulingPriorityQueue &Available, SUnit *PredSU, bool isChain) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written @@ -258,7 +346,7 @@ /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleaseSucc(AvailableQueueTy &Available, +void ScheduleDAGList::ReleaseSucc(SchedulingPriorityQueue &Available, SUnit *SuccSU, bool isChain) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written @@ -287,7 +375,7 @@ /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeBottomUp(AvailableQueueTy &Available, +void ScheduleDAGList::ScheduleNodeBottomUp(SchedulingPriorityQueue &Available, SUnit *SU) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG, false)); @@ -310,7 +398,7 @@ /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeTopDown(AvailableQueueTy &Available, +void ScheduleDAGList::ScheduleNodeTopDown(SchedulingPriorityQueue &Available, SUnit *SU) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG, false)); @@ -338,10 +426,7 @@ /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up /// schedulers. -void ScheduleDAGList::ListScheduleBottomUp() { - // Available queue. - AvailableQueueTy Available; - +void ScheduleDAGList::ListScheduleBottomUp(SchedulingPriorityQueue &Available) { // Add root to Available queue. Available.push(SUnitMap[DAG.getRoot().Val]); @@ -349,13 +434,11 @@ // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; while (!Available.empty()) { - SUnit *CurrNode = Available.top(); - Available.pop(); + SUnit *CurrNode = Available.pop(); while (!isReady(CurrNode, CurrCycle)) { NotReady.push_back(CurrNode); - CurrNode = Available.top(); - Available.pop(); + CurrNode = Available.pop(); } // Add the nodes that aren't ready back onto the available list. @@ -395,10 +478,7 @@ /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. -void ScheduleDAGList::ListScheduleTopDown() { - // Available queue. - AvailableQueueTy Available; - +void ScheduleDAGList::ListScheduleTopDown(SchedulingPriorityQueue &Available) { // Emit the entry node first. SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; ScheduleNodeTopDown(Available, Entry); @@ -420,8 +500,7 @@ bool HasNoopHazards = false; do { - SUnit *CurNode = Available.top(); - Available.pop(); + SUnit *CurNode = Available.pop(); // Get the node represented by this SUnit. SDNode *N = CurNode->Node; @@ -487,47 +566,6 @@ } -/// CalcNodePriority - Priority is the Sethi Ullman number. -/// Smaller number is the higher priority. -int ScheduleDAGList::CalcNodePriority(SUnit *SU) { - if (SU->SethiUllman != INT_MIN) - return SU->SethiUllman; - - if (SU->Preds.size() == 0) { - SU->SethiUllman = 1; - } else { - int Extra = 0; - for (std::set::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) { - SUnit *PredSU = *I; - int PredSethiUllman = CalcNodePriority(PredSU); - if (PredSethiUllman > SU->SethiUllman) { - SU->SethiUllman = PredSethiUllman; - Extra = 0; - } else if (PredSethiUllman == SU->SethiUllman) - Extra++; - } - - if (SU->Node->getOpcode() != ISD::TokenFactor) - SU->SethiUllman += Extra; - else - SU->SethiUllman = (Extra == 1) ? 0 : Extra-1; - } - - return SU->SethiUllman; -} - -/// CalculatePriorities - Calculate priorities of all scheduling units. -void ScheduleDAGList::CalculatePriorities() { - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - // FIXME: assumes uniform latency for now. - SUnits[i].Latency = 1; - (void)CalcNodePriority(&SUnits[i]); - DEBUG(SUnits[i].dump(&DAG)); - DEBUG(std::cerr << "\n"); - } -} - void ScheduleDAGList::BuildSchedUnits() { // Reserve entries in the vector for each of the SUnits we are creating. This // ensure that reallocation of the vector won't happen, so SUnit*'s won't get @@ -662,15 +700,14 @@ // Build scheduling units. BuildSchedUnits(); - - // Calculate node priorities. - CalculatePriorities(); - + + SchedulingPriorityQueue PQ(SUnits); + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) - ListScheduleBottomUp(); + ListScheduleBottomUp(PQ); else - ListScheduleTopDown(); + ListScheduleTopDown(PQ); DEBUG(std::cerr << "*** Final schedule ***\n"); DEBUG(dump()); From duraid at octopus.com.au Wed Mar 8 00:18:58 2006 From: duraid at octopus.com.au (Duraid Madina) Date: Wed, 8 Mar 2006 00:18:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64InstrInfo.td Message-ID: <200603080618.AAA27045@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64InstrInfo.td updated: 1.46 -> 1.47 --- Log message: doo de doo --- Diffs of the changes: (+158 -148) IA64InstrInfo.td | 306 ++++++++++++++++++++++++++++--------------------------- 1 files changed, 158 insertions(+), 148 deletions(-) Index: llvm/lib/Target/IA64/IA64InstrInfo.td diff -u llvm/lib/Target/IA64/IA64InstrInfo.td:1.46 llvm/lib/Target/IA64/IA64InstrInfo.td:1.47 --- llvm/lib/Target/IA64/IA64InstrInfo.td:1.46 Sat Feb 11 01:32:15 2006 +++ llvm/lib/Target/IA64/IA64InstrInfo.td Wed Mar 8 00:18:46 2006 @@ -26,6 +26,16 @@ [SDNPHasChain, SDNPOptInFlag]>; //===--------- +// Instruction types + +class isA { bit A=1; } // I or M unit +class isM { bit M=1; } // M unit +class isI { bit I=1; } // I unit +class isB { bit B=1; } // B unit +class isF { bit F=1; } // F unit +class isLX { bit LX=1; } // I/B + +//===--------- def u2imm : Operand; def u6imm : Operand; @@ -105,48 +115,48 @@ def ADD : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "add $dst = $src1, $src2", - [(set GR:$dst, (add GR:$src1, GR:$src2))]>; + [(set GR:$dst, (add GR:$src1, GR:$src2))]>, isA; def ADD1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "add $dst = $src1, $src2, 1", - [(set GR:$dst, (add (add GR:$src1, GR:$src2), 1))]>; + [(set GR:$dst, (add (add GR:$src1, GR:$src2), 1))]>, isA; def ADDS : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm), "adds $dst = $imm, $src1", - [(set GR:$dst, (add GR:$src1, immSExt14:$imm))]>; + [(set GR:$dst, (add GR:$src1, immSExt14:$imm))]>, isA; def MOVL : AForm_DAG<0x03, 0x0b, (ops GR:$dst, s64imm:$imm), "movl $dst = $imm", - [(set GR:$dst, imm64:$imm)]>; + [(set GR:$dst, imm64:$imm)]>, isLX; def ADDL_GA : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, globaladdress:$imm), "addl $dst = $imm, $src1", - []>; + []>, isA; // hmm def ADDL_EA : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, calltarget:$imm), "addl $dst = $imm, $src1", - []>; + []>, isA; def SUB : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "sub $dst = $src1, $src2", - [(set GR:$dst, (sub GR:$src1, GR:$src2))]>; + [(set GR:$dst, (sub GR:$src1, GR:$src2))]>, isA; def SUB1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "sub $dst = $src1, $src2, 1", - [(set GR:$dst, (add (sub GR: $src1, GR:$src2), -1))]>; + [(set GR:$dst, (add (sub GR: $src1, GR:$src2), -1))]>, isA; let isTwoAddress = 1 in { def TPCADDIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s22imm:$imm, PR:$qp), - "($qp) add $dst = $imm, $dst">; + "($qp) add $dst = $imm, $dst">, isA; def TPCADDS : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm, PR:$qp), "($qp) adds $dst = $imm, $dst", - []>; + []>, isA; def TPCMPIMM8NE : AForm<0x03, 0x0b, (ops PR:$dst, PR:$src1, s22imm:$imm, GR:$src2, PR:$qp), - "($qp) cmp.ne $dst , p0 = $imm, $src2">; + "($qp) cmp.ne $dst , p0 = $imm, $src2">, isA; } // zero extend a bool (predicate reg) into an integer reg @@ -155,66 +165,66 @@ // normal sign/zero-extends def SXT1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt1 $dst = $src", - [(set GR:$dst, (sext_inreg GR:$src, i8))]>; + [(set GR:$dst, (sext_inreg GR:$src, i8))]>, isI; def ZXT1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt1 $dst = $src", - [(set GR:$dst, (and GR:$src, 255))]>; + [(set GR:$dst, (and GR:$src, 255))]>, isI; def SXT2 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt2 $dst = $src", - [(set GR:$dst, (sext_inreg GR:$src, i16))]>; + [(set GR:$dst, (sext_inreg GR:$src, i16))]>, isI; def ZXT2 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt2 $dst = $src", - [(set GR:$dst, (and GR:$src, 65535))]>; + [(set GR:$dst, (and GR:$src, 65535))]>, isI; def SXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt4 $dst = $src", - [(set GR:$dst, (sext_inreg GR:$src, i32))]>; + [(set GR:$dst, (sext_inreg GR:$src, i32))]>, isI; def ZXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt4 $dst = $src", - [(set GR:$dst, (and GR:$src, is32ones))]>; + [(set GR:$dst, (and GR:$src, is32ones))]>, isI; // fixme: shrs vs shru? def MIX1L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "mix1.l $dst = $src1, $src2", [(set GR:$dst, (or (and GR:$src1, isMIX1Lable), - (and (srl GR:$src2, (i64 8)), isMIX1Lable)))]>; + (and (srl GR:$src2, (i64 8)), isMIX1Lable)))]>, isI; def MIX2L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "mix2.l $dst = $src1, $src2", [(set GR:$dst, (or (and GR:$src1, isMIX2Lable), - (and (srl GR:$src2, (i64 16)), isMIX2Lable)))]>; + (and (srl GR:$src2, (i64 16)), isMIX2Lable)))]>, isI; def MIX4L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "mix4.l $dst = $src1, $src2", [(set GR:$dst, (or (and GR:$src1, isMIX4Lable), - (and (srl GR:$src2, (i64 32)), isMIX4Lable)))]>; + (and (srl GR:$src2, (i64 32)), isMIX4Lable)))]>, isI; def MIX1R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "mix1.r $dst = $src1, $src2", [(set GR:$dst, (or (and (shl GR:$src1, (i64 8)), isMIX1Rable), - (and GR:$src2, isMIX1Rable)))]>; + (and GR:$src2, isMIX1Rable)))]>, isI; def MIX2R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "mix2.r $dst = $src1, $src2", [(set GR:$dst, (or (and (shl GR:$src1, (i64 16)), isMIX2Rable), - (and GR:$src2, isMIX2Rable)))]>; + (and GR:$src2, isMIX2Rable)))]>, isI; def MIX4R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "mix4.r $dst = $src1, $src2", [(set GR:$dst, (or (and (shl GR:$src1, (i64 32)), isMIX4Rable), - (and GR:$src2, isMIX4Rable)))]>; + (and GR:$src2, isMIX4Rable)))]>, isI; def GETFSIGD : AForm_DAG<0x03, 0x0b, (ops GR:$dst, FP:$src), "getf.sig $dst = $src", - []>; + []>, isM; def SETFSIGD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, GR:$src), "setf.sig $dst = $src", - []>; + []>, isM; def XMALD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "xma.l $dst = $src1, $src2, $src3", - []>; + []>, isF; def XMAHD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "xma.h $dst = $src1, $src2, $src3", - []>; + []>, isF; def XMAHUD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "xma.hu $dst = $src1, $src2, $src3", - []>; + []>, isF; // pseudocode for integer multiplication def : Pat<(mul GR:$src1, GR:$src2), @@ -232,94 +242,94 @@ def AND : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "and $dst = $src1, $src2", - [(set GR:$dst, (and GR:$src1, GR:$src2))]>; + [(set GR:$dst, (and GR:$src1, GR:$src2))]>, isA; def ANDCM : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "andcm $dst = $src1, $src2", - [(set GR:$dst, (and GR:$src1, (not GR:$src2)))]>; + [(set GR:$dst, (and GR:$src1, (not GR:$src2)))]>, isA; // TODO: and/andcm/or/xor/add/sub/shift immediate forms def OR : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "or $dst = $src1, $src2", - [(set GR:$dst, (or GR:$src1, GR:$src2))]>; + [(set GR:$dst, (or GR:$src1, GR:$src2))]>, isA; def pOR : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2, PR:$qp), - "($qp) or $dst = $src1, $src2">; + "($qp) or $dst = $src1, $src2">, isA; // the following are all a bit unfortunate: we throw away the complement // of the compare! def CMPEQ : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.eq $dst, p0 = $src1, $src2", - [(set PR:$dst, (seteq GR:$src1, GR:$src2))]>; + [(set PR:$dst, (seteq GR:$src1, GR:$src2))]>, isA; def CMPGT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.gt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setgt GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setgt GR:$src1, GR:$src2))]>, isA; def CMPGE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.ge $dst, p0 = $src1, $src2", - [(set PR:$dst, (setge GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setge GR:$src1, GR:$src2))]>, isA; def CMPLT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.lt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setlt GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setlt GR:$src1, GR:$src2))]>, isA; def CMPLE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.le $dst, p0 = $src1, $src2", - [(set PR:$dst, (setle GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setle GR:$src1, GR:$src2))]>, isA; def CMPNE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.ne $dst, p0 = $src1, $src2", - [(set PR:$dst, (setne GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setne GR:$src1, GR:$src2))]>, isA; def CMPLTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.ltu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setult GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setult GR:$src1, GR:$src2))]>, isA; def CMPGTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.gtu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setugt GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setugt GR:$src1, GR:$src2))]>, isA; def CMPLEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.leu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setule GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setule GR:$src1, GR:$src2))]>, isA; def CMPGEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), "cmp.geu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setuge GR:$src1, GR:$src2))]>; + [(set PR:$dst, (setuge GR:$src1, GR:$src2))]>, isA; // and we do the whole thing again for FP compares! def FCMPEQ : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.eq $dst, p0 = $src1, $src2", - [(set PR:$dst, (seteq FP:$src1, FP:$src2))]>; + [(set PR:$dst, (seteq FP:$src1, FP:$src2))]>, isF; def FCMPGT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.gt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setgt FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setgt FP:$src1, FP:$src2))]>, isF; def FCMPGE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.ge $dst, p0 = $src1, $src2", - [(set PR:$dst, (setge FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setge FP:$src1, FP:$src2))]>, isF; def FCMPLT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.lt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setlt FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setlt FP:$src1, FP:$src2))]>, isF; def FCMPLE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.le $dst, p0 = $src1, $src2", - [(set PR:$dst, (setle FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setle FP:$src1, FP:$src2))]>, isF; def FCMPNE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.neq $dst, p0 = $src1, $src2", - [(set PR:$dst, (setne FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setne FP:$src1, FP:$src2))]>, isF; def FCMPLTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.ltu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setult FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setult FP:$src1, FP:$src2))]>, isF; def FCMPGTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.gtu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setugt FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setugt FP:$src1, FP:$src2))]>, isF; def FCMPLEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.leu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setule FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setule FP:$src1, FP:$src2))]>, isF; def FCMPGEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), "fcmp.geu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setuge FP:$src1, FP:$src2))]>; + [(set PR:$dst, (setuge FP:$src1, FP:$src2))]>, isF; def PCMPEQUNCR0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$qp), - "($qp) cmp.eq.unc $dst, p0 = r0, r0">; + "($qp) cmp.eq.unc $dst, p0 = r0, r0">, isA; def : Pat<(trunc GR:$src), // truncate i64 to i1 (CMPNE GR:$src, r0)>; // $src!=0? If so, PR:$dst=true let isTwoAddress=1 in { def TPCMPEQR0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$bogus, PR:$qp), - "($qp) cmp.eq $dst, p0 = r0, r0">; + "($qp) cmp.eq $dst, p0 = r0, r0">, isA; def TPCMPNER0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$bogus, PR:$qp), - "($qp) cmp.ne $dst, p0 = r0, r0">; + "($qp) cmp.ne $dst, p0 = r0, r0">, isA; } /* our pseudocode for OR on predicates is: @@ -384,46 +394,46 @@ def XOR : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "xor $dst = $src1, $src2", - [(set GR:$dst, (xor GR:$src1, GR:$src2))]>; + [(set GR:$dst, (xor GR:$src1, GR:$src2))]>, isA; def SHLADD: AForm_DAG<0x03, 0x0b, (ops GR:$dst,GR:$src1,s64imm:$imm,GR:$src2), "shladd $dst = $src1, $imm, $src2", - [(set GR:$dst, (add GR:$src2, (shl GR:$src1, isSHLADDimm:$imm)))]>; + [(set GR:$dst, (add GR:$src2, (shl GR:$src1, isSHLADDimm:$imm)))]>, isA; def SHL : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "shl $dst = $src1, $src2", - [(set GR:$dst, (shl GR:$src1, GR:$src2))]>; + [(set GR:$dst, (shl GR:$src1, GR:$src2))]>, isI; def SHRU : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "shr.u $dst = $src1, $src2", - [(set GR:$dst, (srl GR:$src1, GR:$src2))]>; + [(set GR:$dst, (srl GR:$src1, GR:$src2))]>, isI; def SHRS : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "shr $dst = $src1, $src2", - [(set GR:$dst, (sra GR:$src1, GR:$src2))]>; + [(set GR:$dst, (sra GR:$src1, GR:$src2))]>, isI; -def MOV : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "mov $dst = $src">; +def MOV : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "mov $dst = $src">, isA; def FMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "mov $dst = $src">; // XXX: there _is_ no fmov + "mov $dst = $src">, isF; // XXX: there _is_ no fmov def PMOV : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src, PR:$qp), - "($qp) mov $dst = $src">; + "($qp) mov $dst = $src">, isA; def SPILL_ALL_PREDICATES_TO_GR : AForm<0x03, 0x0b, (ops GR:$dst), - "mov $dst = pr">; + "mov $dst = pr">, isI; def FILL_ALL_PREDICATES_FROM_GR : AForm<0x03, 0x0b, (ops GR:$src), - "mov pr = $src">; + "mov pr = $src">, isI; let isTwoAddress = 1 in { def CMOV : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src2, GR:$src, PR:$qp), - "($qp) mov $dst = $src">; + "($qp) mov $dst = $src">, isA; } def PFMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src, PR:$qp), - "($qp) mov $dst = $src">; + "($qp) mov $dst = $src">, isF; let isTwoAddress = 1 in { def CFMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src2, FP:$src, PR:$qp), - "($qp) mov $dst = $src">; + "($qp) mov $dst = $src">, isF; } def SELECTINT : Pat<(select PR:$which, GR:$src1, GR:$src2), @@ -464,206 +474,206 @@ def ALLOC : AForm<0x03, 0x0b, (ops GR:$dst, i8imm:$inputs, i8imm:$locals, i8imm:$outputs, i8imm:$rotating), - "alloc $dst = ar.pfs,$inputs,$locals,$outputs,$rotating">; + "alloc $dst = ar.pfs,$inputs,$locals,$outputs,$rotating">, isM; let isTwoAddress = 1 in { def TCMPNE : AForm<0x03, 0x0b, (ops PR:$dst, PR:$src2, GR:$src3, GR:$src4), - "cmp.ne $dst, p0 = $src3, $src4">; + "cmp.ne $dst, p0 = $src3, $src4">, isA; def TPCMPEQOR : AForm<0x03, 0x0b, (ops PR:$dst, PR:$src2, GR:$src3, GR:$src4, PR:$qp), - "($qp) cmp.eq.or $dst, p0 = $src3, $src4">; + "($qp) cmp.eq.or $dst, p0 = $src3, $src4">, isA; def TPCMPNE : AForm<0x03, 0x0b, (ops PR:$dst, PR:$src2, GR:$src3, GR:$src4, PR:$qp), - "($qp) cmp.ne $dst, p0 = $src3, $src4">; + "($qp) cmp.ne $dst, p0 = $src3, $src4">, isA; def TPCMPEQ : AForm<0x03, 0x0b, (ops PR:$dst, PR:$src2, GR:$src3, GR:$src4, PR:$qp), - "($qp) cmp.eq $dst, p0 = $src3, $src4">; + "($qp) cmp.eq $dst, p0 = $src3, $src4">, isA; } def MOVSIMM14 : AForm<0x03, 0x0b, (ops GR:$dst, s14imm:$imm), - "mov $dst = $imm">; + "mov $dst = $imm">, isA; def MOVSIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, s22imm:$imm), - "mov $dst = $imm">; + "mov $dst = $imm">, isA; def MOVLIMM64 : AForm<0x03, 0x0b, (ops GR:$dst, s64imm:$imm), - "movl $dst = $imm">; + "movl $dst = $imm">, isLX; def SHLI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm), - "shl $dst = $src1, $imm">; + "shl $dst = $src1, $imm">, isI; def SHRUI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm), - "shr.u $dst = $src1, $imm">; + "shr.u $dst = $src1, $imm">, isI; def SHRSI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm), - "shr $dst = $src1, $imm">; + "shr $dst = $src1, $imm">, isI; def EXTRU : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), - "extr.u $dst = $src1, $imm1, $imm2">; + "extr.u $dst = $src1, $imm1, $imm2">, isI; def DEPZ : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), - "dep.z $dst = $src1, $imm1, $imm2">; + "dep.z $dst = $src1, $imm1, $imm2">, isI; def PCMPEQOR : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2, PR:$qp), - "($qp) cmp.eq.or $dst, p0 = $src1, $src2">; + "($qp) cmp.eq.or $dst, p0 = $src1, $src2">, isA; def PCMPEQUNC : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2, PR:$qp), - "($qp) cmp.eq.unc $dst, p0 = $src1, $src2">; + "($qp) cmp.eq.unc $dst, p0 = $src1, $src2">, isA; def PCMPNE : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2, PR:$qp), - "($qp) cmp.ne $dst, p0 = $src1, $src2">; + "($qp) cmp.ne $dst, p0 = $src1, $src2">, isA; // two destinations! def BCMPEQ : AForm<0x03, 0x0b, (ops PR:$dst1, PR:$dst2, GR:$src1, GR:$src2), - "cmp.eq $dst1, dst2 = $src1, $src2">; + "cmp.eq $dst1, dst2 = $src1, $src2">, isA; def ADDIMM14 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm), - "adds $dst = $imm, $src1">; + "adds $dst = $imm, $src1">, isA; def ADDIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s22imm:$imm), - "add $dst = $imm, $src1">; + "add $dst = $imm, $src1">, isA; def CADDIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s22imm:$imm, PR:$qp), - "($qp) add $dst = $imm, $src1">; + "($qp) add $dst = $imm, $src1">, isA; def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2), - "sub $dst = $imm, $src2">; + "sub $dst = $imm, $src2">, isA; let isStore = 1, noResults = 1 in { def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st1 [$dstPtr] = $value">; + "st1 [$dstPtr] = $value">, isM; def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st2 [$dstPtr] = $value">; + "st2 [$dstPtr] = $value">, isM; def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st4 [$dstPtr] = $value">; + "st4 [$dstPtr] = $value">, isM; def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st8 [$dstPtr] = $value">; + "st8 [$dstPtr] = $value">, isM; def STF4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), - "stfs [$dstPtr] = $value">; + "stfs [$dstPtr] = $value">, isM; def STF8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), - "stfd [$dstPtr] = $value">; + "stfd [$dstPtr] = $value">, isM; def STF_SPILL : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), - "stf.spill [$dstPtr] = $value">; + "stf.spill [$dstPtr] = $value">, isM; } let isLoad = 1 in { def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld1 $dst = [$srcPtr]">; + "ld1 $dst = [$srcPtr]">, isM; def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld2 $dst = [$srcPtr]">; + "ld2 $dst = [$srcPtr]">, isM; def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld4 $dst = [$srcPtr]">; + "ld4 $dst = [$srcPtr]">, isM; def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld8 $dst = [$srcPtr]">; + "ld8 $dst = [$srcPtr]">, isM; def LDF4 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), - "ldfs $dst = [$srcPtr]">; + "ldfs $dst = [$srcPtr]">, isM; def LDF8 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), - "ldfd $dst = [$srcPtr]">; + "ldfd $dst = [$srcPtr]">, isM; def LDF_FILL : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), - "ldf.fill $dst = [$srcPtr]">; + "ldf.fill $dst = [$srcPtr]">, isM; } def POPCNT : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "popcnt $dst = $src", - [(set GR:$dst, (ctpop GR:$src))]>; + [(set GR:$dst, (ctpop GR:$src))]>, isI; // some FP stuff: // TODO: single-precision stuff? def FADD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), "fadd $dst = $src1, $src2", - [(set FP:$dst, (fadd FP:$src1, FP:$src2))]>; + [(set FP:$dst, (fadd FP:$src1, FP:$src2))]>, isF; def FADDS: AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), - "fadd.s $dst = $src1, $src2">; + "fadd.s $dst = $src1, $src2">, isF; def FSUB : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), "fsub $dst = $src1, $src2", - [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>; + [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>, isF; def FMPY : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), "fmpy $dst = $src1, $src2", - [(set FP:$dst, (fmul FP:$src1, FP:$src2))]>; + [(set FP:$dst, (fmul FP:$src1, FP:$src2))]>, isF; def FMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "fma $dst = $src1, $src2, $src3", - [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>; + [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>, isF; def FMS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "fms $dst = $src1, $src2, $src3", - [(set FP:$dst, (fsub (fmul FP:$src1, FP:$src2), FP:$src3))]>; + [(set FP:$dst, (fsub (fmul FP:$src1, FP:$src2), FP:$src3))]>, isF; def FNMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "fnma $dst = $src1, $src2, $src3", - [(set FP:$dst, (fneg (fadd (fmul FP:$src1, FP:$src2), FP:$src3)))]>; + [(set FP:$dst, (fneg (fadd (fmul FP:$src1, FP:$src2), FP:$src3)))]>, isF; def FABS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src), "fabs $dst = $src", - [(set FP:$dst, (fabs FP:$src))]>; + [(set FP:$dst, (fabs FP:$src))]>, isF; def FNEG : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src), "fneg $dst = $src", - [(set FP:$dst, (fneg FP:$src))]>; + [(set FP:$dst, (fneg FP:$src))]>, isF; def FNEGABS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src), "fnegabs $dst = $src", - [(set FP:$dst, (fneg (fabs FP:$src)))]>; + [(set FP:$dst, (fneg (fabs FP:$src)))]>, isF; let isTwoAddress=1 in { def TCFMAS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$bogussrc, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.s1 $dst = $src1, $src2, $src3">; + "($qp) fma.s1 $dst = $src1, $src2, $src3">, isF; def TCFMADS0 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$bogussrc, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.d.s0 $dst = $src1, $src2, $src3">; + "($qp) fma.d.s0 $dst = $src1, $src2, $src3">, isF; } def CFMAS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.s1 $dst = $src1, $src2, $src3">; + "($qp) fma.s1 $dst = $src1, $src2, $src3">, isF; def CFNMAS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fnma.s1 $dst = $src1, $src2, $src3">; + "($qp) fnma.s1 $dst = $src1, $src2, $src3">, isF; def CFMADS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.d.s1 $dst = $src1, $src2, $src3">; + "($qp) fma.d.s1 $dst = $src1, $src2, $src3">, isF; def CFMADS0 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.d.s0 $dst = $src1, $src2, $src3">; + "($qp) fma.d.s0 $dst = $src1, $src2, $src3">, isF; def CFNMADS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fnma.d.s1 $dst = $src1, $src2, $src3">; + "($qp) fnma.d.s1 $dst = $src1, $src2, $src3">, isF; def FRCPAS0 : AForm<0x03, 0x0b, (ops FP:$dstFR, PR:$dstPR, FP:$src1, FP:$src2), - "frcpa.s0 $dstFR, $dstPR = $src1, $src2">; + "frcpa.s0 $dstFR, $dstPR = $src1, $src2">, isF; def FRCPAS1 : AForm<0x03, 0x0b, (ops FP:$dstFR, PR:$dstPR, FP:$src1, FP:$src2), - "frcpa.s1 $dstFR, $dstPR = $src1, $src2">; + "frcpa.s1 $dstFR, $dstPR = $src1, $src2">, isF; def XMAL : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), - "xma.l $dst = $src1, $src2, $src3">; + "xma.l $dst = $src1, $src2, $src3">, isF; def FCVTXF : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.xf $dst = $src">; + "fcvt.xf $dst = $src">, isF; def FCVTXUF : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.xuf $dst = $src">; + "fcvt.xuf $dst = $src">, isF; def FCVTXUFS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.xuf.s1 $dst = $src">; + "fcvt.xuf.s1 $dst = $src">, isF; def FCVTFX : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.fx $dst = $src">; + "fcvt.fx $dst = $src">, isF; def FCVTFXU : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.fxu $dst = $src">; + "fcvt.fxu $dst = $src">, isF; def FCVTFXTRUNC : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.fx.trunc $dst = $src">; + "fcvt.fx.trunc $dst = $src">, isF; def FCVTFXUTRUNC : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.fxu.trunc $dst = $src">; + "fcvt.fxu.trunc $dst = $src">, isF; def FCVTFXTRUNCS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.fx.trunc.s1 $dst = $src">; + "fcvt.fx.trunc.s1 $dst = $src">, isF; def FCVTFXUTRUNCS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fcvt.fxu.trunc.s1 $dst = $src">; + "fcvt.fxu.trunc.s1 $dst = $src">, isF; def FNORMD : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fnorm.d $dst = $src">; + "fnorm.d $dst = $src">, isF; def GETFD : AForm<0x03, 0x0b, (ops GR:$dst, FP:$src), - "getf.d $dst = $src">; + "getf.d $dst = $src">, isM; def SETFD : AForm<0x03, 0x0b, (ops FP:$dst, GR:$src), - "setf.d $dst = $src">; + "setf.d $dst = $src">, isM; def GETFSIG : AForm<0x03, 0x0b, (ops GR:$dst, FP:$src), - "getf.sig $dst = $src">; + "getf.sig $dst = $src">, isM; def SETFSIG : AForm<0x03, 0x0b, (ops FP:$dst, GR:$src), - "setf.sig $dst = $src">; + "setf.sig $dst = $src">, isM; // these four FP<->int conversion patterns need checking/cleaning def SINT_TO_FP : Pat<(sint_to_fp GR:$src), @@ -678,11 +688,11 @@ let isTerminator = 1, isBranch = 1, noResults = 1 in { def BRL_NOTCALL : RawForm<0x03, 0xb0, (ops i64imm:$dst), - "(p0) brl.cond.sptk $dst">; + "(p0) brl.cond.sptk $dst">, isB; def BRLCOND_NOTCALL : RawForm<0x03, 0xb0, (ops PR:$qp, i64imm:$dst), - "($qp) brl.cond.sptk $dst">; + "($qp) brl.cond.sptk $dst">, isB; def BRCOND_NOTCALL : RawForm<0x03, 0xb0, (ops PR:$qp, GR:$dst), - "($qp) br.cond.sptk $dst">; + "($qp) br.cond.sptk $dst">, isB; } let isCall = 1, noResults = 1, /* isTerminator = 1, isBranch = 1, */ @@ -703,29 +713,29 @@ out0,out1,out2,out3,out4,out5,out6,out7] in { // old pattern call def BRCALL: RawForm<0x03, 0xb0, (ops calltarget:$dst), - "br.call.sptk rp = $dst">; // FIXME: teach llvm about branch regs? + "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs? // new daggy stuff! // calls a globaladdress def BRCALL_IPREL_GA : RawForm<0x03, 0xb0, (ops calltarget:$dst), - "br.call.sptk rp = $dst">; // FIXME: teach llvm about branch regs? + "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs? // calls an externalsymbol def BRCALL_IPREL_ES : RawForm<0x03, 0xb0, (ops calltarget:$dst), - "br.call.sptk rp = $dst">; // FIXME: teach llvm about branch regs? + "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs? // calls through a function descriptor def BRCALL_INDIRECT : RawForm<0x03, 0xb0, (ops GR:$branchreg), - "br.call.sptk rp = $branchreg">; // FIXME: teach llvm about branch regs? + "br.call.sptk rp = $branchreg">, isB; // FIXME: teach llvm about branch regs? def BRLCOND_CALL : RawForm<0x03, 0xb0, (ops PR:$qp, i64imm:$dst), - "($qp) brl.cond.call.sptk $dst">; + "($qp) brl.cond.call.sptk $dst">, isB; def BRCOND_CALL : RawForm<0x03, 0xb0, (ops PR:$qp, GR:$dst), - "($qp) br.cond.call.sptk $dst">; + "($qp) br.cond.call.sptk $dst">, isB; } // Return branch: let isTerminator = 1, isReturn = 1, noResults = 1 in def RET : AForm_DAG<0x03, 0x0b, (ops), "br.ret.sptk.many rp", - [(retflag)]>; // return + [(retflag)]>, isB; // return def : Pat<(ret), (RET)>; // the evil stop bit of despair From lattner at cs.uiuc.edu Wed Mar 8 12:02:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 12:02:11 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Shootout-C++/Makefile Message-ID: <200603081802.MAA10188@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/Shootout-C++: Makefile updated: 1.13 -> 1.14 --- Log message: let these programs work with the new CFE --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/SingleSource/Benchmarks/Shootout-C++/Makefile diff -u llvm-test/SingleSource/Benchmarks/Shootout-C++/Makefile:1.13 llvm-test/SingleSource/Benchmarks/Shootout-C++/Makefile:1.14 --- llvm-test/SingleSource/Benchmarks/Shootout-C++/Makefile:1.13 Tue Nov 23 14:15:39 2004 +++ llvm-test/SingleSource/Benchmarks/Shootout-C++/Makefile Wed Mar 8 12:01:47 2006 @@ -1,7 +1,7 @@ LEVEL = ../../.. CXXFLAGS += -Wno-deprecated CPPFLAGS += -Wno-deprecated -LDFLAGS += -lm +LDFLAGS += -lm -lstdc++ LIBS += -lstdc++ REQUIRES_EH_SUPPORT=1 FP_TOLERANCE = 0.00000001 From jlaskey at apple.com Wed Mar 8 12:11:22 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 8 Mar 2006 12:11:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200603081811.MAA10270@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.145 -> 1.146 --- Log message: Get rid of the multiple copies of getStringValue. Now a Constant:: method. --- Diffs of the changes: (+40 -0) Constants.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 40 insertions(+) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.145 llvm/lib/VMCore/Constants.cpp:1.146 --- llvm/lib/VMCore/Constants.cpp:1.145 Tue Jan 17 14:07:22 2006 +++ llvm/lib/VMCore/Constants.cpp Wed Mar 8 12:11:07 2006 @@ -1712,3 +1712,43 @@ (*I)->destroyConstantImpl(); Constants.clear(); } + +/// getStringValue - Turn an LLVM constant pointer that eventually points to a +/// global into a string value. Return an empty string if we can't do it. +/// +std::string Constant::getStringValue(unsigned Offset) { + if (GlobalVariable *GV = dyn_cast(this)) { + if (GV->hasInitializer() && isa(GV->getInitializer())) { + ConstantArray *Init = cast(GV->getInitializer()); + if (Init->isString()) { + std::string Result = Init->getAsString(); + if (Offset < Result.size()) { + // If we are pointing INTO The string, erase the beginning... + Result.erase(Result.begin(), Result.begin()+Offset); + + // Take off the null terminator, and any string fragments after it. + std::string::size_type NullPos = Result.find_first_of((char)0); + if (NullPos != std::string::npos) + Result.erase(Result.begin()+NullPos, Result.end()); + return Result; + } + } + } + } else if (Constant *C = dyn_cast(this)) { + if (GlobalValue *GV = dyn_cast(C)) + return GV->getStringValue(Offset); + else if (ConstantExpr *CE = dyn_cast(C)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + // Turn a gep into the specified offset. + if (CE->getNumOperands() == 3 && + cast(CE->getOperand(1))->isNullValue() && + isa(CE->getOperand(2))) { + Offset += cast(CE->getOperand(2))->getRawValue(); + return CE->getOperand(0)->getStringValue(Offset); + } + } + } + } + return ""; +} + From jlaskey at apple.com Wed Mar 8 12:11:22 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 8 Mar 2006 12:11:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200603081811.MAA10288@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.182 -> 1.183 --- Log message: Get rid of the multiple copies of getStringValue. Now a Constant:: method. --- Diffs of the changes: (+1 -19) SelectionDAGISel.cpp | 20 +------------------- 1 files changed, 1 insertion(+), 19 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.182 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.183 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.182 Tue Mar 7 22:25:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Mar 8 12:11:06 2006 @@ -873,24 +873,6 @@ CurMBB->getParent()->getFrameInfo()->CreateVariableSizedObject(); } -/// getStringValue - Turn an LLVM constant pointer that eventually points to a -/// global into a string value. Return an empty string if we can't do it. -/// -static std::string getStringValue(GlobalVariable *GV, unsigned Offset = 0) { - if (GV->hasInitializer() && isa(GV->getInitializer())) { - ConstantArray *Init = cast(GV->getInitializer()); - if (Init->isString()) { - std::string Result = Init->getAsString(); - if (Offset < Result.size()) { - // If we are pointing INTO The string, erase the beginning... - Result.erase(Result.begin(), Result.begin()+Offset); - return Result; - } - } - } - return ""; -} - void SelectionDAGLowering::visitLoad(LoadInst &I) { SDOperand Ptr = getValue(I.getOperand(0)); @@ -1962,7 +1944,7 @@ if (G) { GlobalVariable *GV = dyn_cast(G->getGlobal()); if (GV) { - Str = getStringValue(GV); + Str = GV->getStringValue(); if (!Str.empty()) { CopyFromStr = true; SrcOff += SrcDelta; From jlaskey at apple.com Wed Mar 8 12:11:22 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 8 Mar 2006 12:11:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200603081811.MAA10276@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.43 -> 1.44 MachineDebugInfo.cpp updated: 1.26 -> 1.27 --- Log message: Get rid of the multiple copies of getStringValue. Now a Constant:: method. --- Diffs of the changes: (+2 -42) DwarfWriter.cpp | 1 - MachineDebugInfo.cpp | 43 ++----------------------------------------- 2 files changed, 2 insertions(+), 42 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.43 llvm/lib/CodeGen/DwarfWriter.cpp:1.44 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.43 Tue Mar 7 09:51:33 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Mar 8 12:11:06 2006 @@ -1244,7 +1244,6 @@ /// NewType - Create a new type DIE. /// DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc) { - // FIXME - hack to get around NULL types short term. if (!TyDesc) return NewBasicType(Context, Type::IntTy); // FIXME - Should handle other contexts that compile units. Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.26 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.27 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.26 Tue Mar 7 20:07:02 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Mar 8 12:11:06 2006 @@ -67,45 +67,6 @@ return Result; } -/// getStringValue - Turn an LLVM constant pointer that eventually points to a -/// global into a string value. Return an empty string if we can't do it. -/// -static const std::string getStringValue(Value *V, unsigned Offset = 0) { - if (GlobalVariable *GV = dyn_cast(V)) { - if (GV->hasInitializer() && isa(GV->getInitializer())) { - ConstantArray *Init = cast(GV->getInitializer()); - if (Init->isString()) { - std::string Result = Init->getAsString(); - if (Offset < Result.size()) { - // If we are pointing INTO The string, erase the beginning... - Result.erase(Result.begin(), Result.begin()+Offset); - - // Take off the null terminator, and any string fragments after it. - std::string::size_type NullPos = Result.find_first_of((char)0); - if (NullPos != std::string::npos) - Result.erase(Result.begin()+NullPos, Result.end()); - return Result; - } - } - } - } else if (Constant *C = dyn_cast(V)) { - if (GlobalValue *GV = dyn_cast(C)) - return getStringValue(GV, Offset); - else if (ConstantExpr *CE = dyn_cast(C)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - // Turn a gep into the specified offset. - if (CE->getNumOperands() == 3 && - cast(CE->getOperand(1))->isNullValue() && - isa(CE->getOperand(2))) { - return getStringValue(CE->getOperand(0), - Offset+cast(CE->getOperand(2))->getRawValue()); - } - } - } - } - return ""; -} - /// isStringValue - Return true if the given value can be coerced to a string. /// static bool isStringValue(Value *V) { @@ -250,7 +211,7 @@ } virtual void Apply(std::string &Field) { Constant *C = CI->getOperand(I++); - Field = getStringValue(C); + Field = C->getStringValue(); } virtual void Apply(DebugInfoDesc *&Field) { Constant *C = CI->getOperand(I++); @@ -571,7 +532,7 @@ /// getDescString - Return a string used to compose global names and labels. A /// A global variable name needs to be defined for each debug descriptor that is -/// anchored. NOTE: that each global variable name here also needs to be added +/// anchored. NOTE: that each global variable named here also needs to be added /// to the list of names left external in the internalizer. /// ExternalNames.insert("llvm.dbg.compile_units"); /// ExternalNames.insert("llvm.dbg.global_variables"); From jlaskey at apple.com Wed Mar 8 12:11:22 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 8 Mar 2006 12:11:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Debugger/ProgramInfo.cpp Message-ID: <200603081811.MAA10284@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: ProgramInfo.cpp updated: 1.12 -> 1.13 --- Log message: Get rid of the multiple copies of getStringValue. Now a Constant:: method. --- Diffs of the changes: (+3 -42) ProgramInfo.cpp | 45 +++------------------------------------------ 1 files changed, 3 insertions(+), 42 deletions(-) Index: llvm/lib/Debugger/ProgramInfo.cpp diff -u llvm/lib/Debugger/ProgramInfo.cpp:1.12 llvm/lib/Debugger/ProgramInfo.cpp:1.13 --- llvm/lib/Debugger/ProgramInfo.cpp:1.12 Thu Jul 7 18:21:43 2005 +++ llvm/lib/Debugger/ProgramInfo.cpp Wed Mar 8 12:11:07 2006 @@ -38,45 +38,6 @@ } } -/// getStringValue - Turn an LLVM constant pointer that eventually points to a -/// global into a string value. Return an empty string if we can't do it. -/// -static std::string getStringValue(Value *V, unsigned Offset = 0) { - if (GlobalVariable *GV = dyn_cast(V)) { - if (GV->hasInitializer() && isa(GV->getInitializer())) { - ConstantArray *Init = cast(GV->getInitializer()); - if (Init->isString()) { - std::string Result = Init->getAsString(); - if (Offset < Result.size()) { - // If we are pointing INTO The string, erase the beginning... - Result.erase(Result.begin(), Result.begin()+Offset); - - // Take off the null terminator, and any string fragments after it. - std::string::size_type NullPos = Result.find_first_of((char)0); - if (NullPos != std::string::npos) - Result.erase(Result.begin()+NullPos, Result.end()); - return Result; - } - } - } - } else if (Constant *C = dyn_cast(V)) { - if (GlobalValue *GV = dyn_cast(C)) - return getStringValue(GV, Offset); - else if (ConstantExpr *CE = dyn_cast(C)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - // Turn a gep into the specified offset. - if (CE->getNumOperands() == 3 && - cast(CE->getOperand(1))->isNullValue() && - isa(CE->getOperand(2))) { - return getStringValue(CE->getOperand(0), - Offset+cast(CE->getOperand(2))->getRawValue()); - } - } - } - } - return ""; -} - /// getNextStopPoint - Follow the def-use chains of the specified LLVM value, /// traversing the use chains until we get to a stoppoint. When we do, return /// the source location of the stoppoint. If we don't find a stoppoint, return @@ -158,8 +119,8 @@ if (ConstantUInt *CUI = dyn_cast(CS->getOperand(1))) Version = CUI->getValue(); - BaseName = getStringValue(CS->getOperand(3)); - Directory = getStringValue(CS->getOperand(4)); + BaseName = CS->getOperand(3)->getStringValue(); + Directory = CS->getOperand(4)->getStringValue(); } } @@ -199,7 +160,7 @@ SourceFile = &PI.getSourceFile(GV); // Entry #2 is the function name. - Name = getStringValue(CS->getOperand(2)); + Name = CS->getOperand(2)->getStringValue(); } } From jlaskey at apple.com Wed Mar 8 12:11:22 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 8 Mar 2006 12:11:22 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Message-ID: <200603081811.MAA10278@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.27 -> 1.28 --- Log message: Get rid of the multiple copies of getStringValue. Now a Constant:: method. --- Diffs of the changes: (+5 -0) Constant.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.27 llvm/include/llvm/Constant.h:1.28 --- llvm/include/llvm/Constant.h:1.27 Fri Dec 16 18:19:22 2005 +++ llvm/include/llvm/Constant.h Wed Mar 8 12:11:06 2006 @@ -90,6 +90,11 @@ /// constant subsystem, which can be used in environments where this memory /// is otherwise reported as a leak. static void clearAllValueMaps(); + + /// getStringValue - Turn an LLVM constant pointer that eventually points to a + /// global into a string value. Return an empty string if we can't do it. + /// + std::string getStringValue(unsigned Offset = 0); }; } // End llvm namespace From lattner at cs.uiuc.edu Wed Mar 8 12:39:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 12:39:04 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Module.h Message-ID: <200603081839.MAA10786@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Module.h updated: 1.69 -> 1.70 --- Log message: add a new helper method --- Diffs of the changes: (+6 -0) Module.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.69 llvm/include/llvm/Module.h:1.70 --- llvm/include/llvm/Module.h:1.69 Wed Jan 25 12:55:37 2006 +++ llvm/include/llvm/Module.h Wed Mar 8 12:38:51 2006 @@ -148,6 +148,12 @@ GlobalVariable *getGlobalVariable(const std::string &Name, const Type *Ty, bool AllowInternal = false); + /// getNamedGlobal - Return the first global variable in the module with the + /// specified name, of arbitrary type. This method returns null if a global + /// with the specified name is not found. + /// + GlobalVariable *getNamedGlobal(const std::string &Name); + //===--------------------------------------------------------------------===// // Methods for easy access to the types in the module. From lattner at cs.uiuc.edu Wed Mar 8 12:39:26 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 12:39:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Module.cpp Message-ID: <200603081839.MAA10822@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Module.cpp updated: 1.64 -> 1.65 --- Log message: add a new helper method. --- Diffs of the changes: (+14 -0) Module.cpp | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/lib/VMCore/Module.cpp diff -u llvm/lib/VMCore/Module.cpp:1.64 llvm/lib/VMCore/Module.cpp:1.65 --- llvm/lib/VMCore/Module.cpp:1.64 Wed Jan 25 12:57:27 2006 +++ llvm/lib/VMCore/Module.cpp Wed Mar 8 12:39:13 2006 @@ -222,6 +222,20 @@ return 0; } +/// getNamedGlobal - Return the first global variable in the module with the +/// specified name, of arbitrary type. This method returns null if a global +/// with the specified name is not found. +/// +GlobalVariable *Module::getNamedGlobal(const std::string &Name) { + // FIXME: This would be much faster with a symbol table that doesn't + // discriminate based on type! + for (global_iterator I = global_begin(), E = global_end(); + I != E; ++I) + if (I->getName() == Name) + return I; + return 0; +} + //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Wed Mar 8 12:42:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 12:42:46 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Message-ID: <200603081842.MAA10959@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ExecutionEngine: ExecutionEngine.h updated: 1.33 -> 1.34 --- Log message: Add a helper method for running static ctors/dtors in the module. --- Diffs of the changes: (+6 -0) ExecutionEngine.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h diff -u llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.33 llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.34 --- llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.33 Tue Jul 12 10:51:55 2005 +++ llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Wed Mar 8 12:42:33 2006 @@ -95,6 +95,12 @@ virtual GenericValue runFunction(Function *F, const std::vector &ArgValues) = 0; + /// runStaticConstructorsDestructors - This method is used to execute all of + /// the static constructors or destructors for a module, depending on the + /// value of isDtors. + void runStaticConstructorsDestructors(bool isDtors); + + /// runFunctionAsMain - This is a helper function which wraps runFunction to /// handle the common task of starting up main with the specified argc, argv, /// and envp parameters. From lattner at cs.uiuc.edu Wed Mar 8 12:42:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 12:42:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200603081842.MAA11001@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.74 -> 1.75 --- Log message: Add a helper method for running static ctors/dtors in the module. --- Diffs of the changes: (+31 -2) ExecutionEngine.cpp | 33 +++++++++++++++++++++++++++++++-- 1 files changed, 31 insertions(+), 2 deletions(-) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.74 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.75 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.74 Mon Feb 6 23:11:57 2006 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Wed Mar 8 12:42:46 2006 @@ -95,6 +95,37 @@ return Result; } + +/// runStaticConstructorsDestructors - This method is used to execute all of +/// the static constructors or destructors for a module, depending on the +/// value of isDtors. +void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) { + const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors"; + GlobalVariable *GV = CurMod.getNamedGlobal(Name); + if (!GV || GV->isExternal() || !GV->hasInternalLinkage()) return; + + // Should be an array of '{ int, void ()* }' structs. The first value is the + // init priority, which we ignore. + ConstantArray *InitList = dyn_cast(GV->getInitializer()); + if (!InitList) return; + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + + Constant *FP = CS->getOperand(1); + if (FP->isNullValue()) + return; // Found a null terminator, exit. + + if (ConstantExpr *CE = dyn_cast(FP)) + if (CE->getOpcode() == Instruction::Cast) + FP = CE->getOperand(0); + if (Function *F = dyn_cast(FP)) { + // Execute the ctor/dtor function! + runFunction(F, std::vector()); + } + } +} + /// runFunctionAsMain - This is a helper function which wraps runFunction to /// handle the common task of starting up main with the specified argc, argv, /// and envp parameters. @@ -122,8 +153,6 @@ return runFunction(Fn, GVArgs).IntVal; } - - /// If possible, create a JIT, unless the caller specifically requests an /// Interpreter or there's an error. If even an Interpreter cannot be created, /// NULL is returned. From lattner at cs.uiuc.edu Wed Mar 8 12:43:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 12:43:49 -0600 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200603081843.MAA11044@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.54 -> 1.55 --- Log message: Fit to 80 columns. Add support for running static ctor/dtors that aren't handled by __main. This fixes programs with the JIT and the new CFE, such as HBD. --- Diffs of the changes: (+14 -7) lli.cpp | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.54 llvm/tools/lli/lli.cpp:1.55 --- llvm/tools/lli/lli.cpp:1.54 Thu Dec 15 23:19:18 2005 +++ llvm/tools/lli/lli.cpp Wed Mar 8 12:43:36 2006 @@ -60,7 +60,8 @@ try { MP = getBytecodeModuleProvider(InputFile); } catch (std::string &err) { - std::cerr << "Error loading program '" << InputFile << "': " << err << "\n"; + std::cerr << "Error loading program '" << InputFile << "': " + << err << "\n"; exit(1); } @@ -69,10 +70,10 @@ MP->getModule()->setTargetTriple(TargetTriple); ExecutionEngine *EE = ExecutionEngine::create(MP, ForceInterpreter); - assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?"); + assert(EE &&"Couldn't create an ExecutionEngine, not even an interpreter?"); - // If the user specifically requested an argv[0] to pass into the program, do - // it now. + // If the user specifically requested an argv[0] to pass into the program, + // do it now. if (!FakeArgv0.empty()) { InputFile = FakeArgv0; } else { @@ -96,11 +97,17 @@ return -1; } - // Run main... + // Run static constructors. + EE->runStaticConstructorsDestructors(false); + + // Run main. int Result = EE->runFunctionAsMain(Fn, InputArgv, envp); - // If the program didn't explicitly call exit, call exit now, for the program. - // This ensures that any atexit handlers get called correctly. + // Run static destructors. + EE->runStaticConstructorsDestructors(true); + + // If the program didn't explicitly call exit, call exit now, for the + // program. This ensures that any atexit handlers get called correctly. Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy, (Type *)0); From jlaskey at apple.com Wed Mar 8 13:31:28 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 8 Mar 2006 13:31:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200603081931.NAA11373@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.254 -> 1.255 --- Log message: Add #line support for CBE. --- Diffs of the changes: (+17 -0) Writer.cpp | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.254 llvm/lib/Target/CBackend/Writer.cpp:1.255 --- llvm/lib/Target/CBackend/Writer.cpp:1.254 Tue Mar 7 16:58:23 2006 +++ llvm/lib/Target/CBackend/Writer.cpp Wed Mar 8 13:31:15 2006 @@ -1598,6 +1598,7 @@ case Intrinsic::setjmp: case Intrinsic::longjmp: case Intrinsic::prefetch: + case Intrinsic::dbg_stoppoint: // We directly implement these intrinsics break; default: @@ -1687,6 +1688,22 @@ writeOperand(I.getOperand(3)); Out << ")"; return; + case Intrinsic::dbg_stoppoint: { + // If we use writeOperand directly we get a "u" suffix which is rejected + // by gcc. + ConstantUInt *SI = cast(I.getOperand(2)); + GlobalVariable *GV = cast(I.getOperand(4)); + ConstantStruct *CS = cast(GV->getInitializer()); + std::string FileName = CS->getOperand(4)->getStringValue(); + std::string Directory = CS->getOperand(5)->getStringValue(); + + Out << "\n#line " + << SI->getValue() + << " \"" << Directory << FileName << "\"\n"; + // Need to set result. + Out << "0"; + return; + } } } From lattner at cs.uiuc.edu Wed Mar 8 16:28:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 16:28:32 -0600 Subject: [llvm-commits] CVS: llvm/test/TestRunner.sh Message-ID: <200603082228.QAA15401@zion.cs.uiuc.edu> Changes in directory llvm/test: TestRunner.sh updated: 1.10 -> 1.11 --- Log message: Pass -emit-llvm automatically to %llvmgcc and %llvmg++ to fix regression tests with the new f.e. --- Diffs of the changes: (+1 -1) TestRunner.sh | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/TestRunner.sh diff -u llvm/test/TestRunner.sh:1.10 llvm/test/TestRunner.sh:1.11 --- llvm/test/TestRunner.sh:1.10 Fri Aug 5 14:48:29 2005 +++ llvm/test/TestRunner.sh Wed Mar 8 16:28:19 2006 @@ -30,7 +30,7 @@ ulimit -t 40 SCRIPT=$OUTPUT.script -grep 'RUN:' $FILENAME | sed "s|^.*RUN:\(.*\)$|\1|g;s|%s|$SUBST|g;s|%llvmgcc|llvm-gcc|g;s|%llvmgxx|llvm-g++|g;s|%prcontext|prcontext.tcl|g" > $SCRIPT +grep 'RUN:' $FILENAME | sed "s|^.*RUN:\(.*\)$|\1|g;s|%s|$SUBST|g;s|%llvmgcc|llvm-gcc -emit-llvm|g;s|%llvmgxx|llvm-g++ -emit-llvm|g;s|%prcontext|prcontext.tcl|g" > $SCRIPT /bin/sh $SCRIPT > $OUTPUT 2>&1 || ( From lattner at cs.uiuc.edu Wed Mar 8 16:32:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 16:32:34 -0600 Subject: [llvm-commits] CVS: llvm/test/lib/llvm-dg.exp Message-ID: <200603082232.QAA15457@zion.cs.uiuc.edu> Changes in directory llvm/test/lib: llvm-dg.exp updated: 1.11 -> 1.12 --- Log message: Automatically pass -emit-llvm to llvmgcc when using %llvmgcc --- Diffs of the changes: (+2 -2) llvm-dg.exp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/test/lib/llvm-dg.exp diff -u llvm/test/lib/llvm-dg.exp:1.11 llvm/test/lib/llvm-dg.exp:1.12 --- llvm/test/lib/llvm-dg.exp:1.11 Tue Nov 30 00:29:45 2004 +++ llvm/test/lib/llvm-dg.exp Wed Mar 8 16:32:20 2006 @@ -57,10 +57,10 @@ regsub -all {%p} $new_runline [file join $srcdir $subdir] new_runline #replace %llvmgcc with actual path to llvmgcc - regsub -all {%llvmgcc} $new_runline $llvmgcc new_runline + regsub -all {%llvmgcc} $new_runline "$llvmgcc -emit-llvm" new_runline #replace %llvmgxx with actual path to llvmg++ - regsub -all {%llvmgxx} $new_runline $llvmgxx new_runline + regsub -all {%llvmgxx} $new_runline "$llvmgxx -emit-llvm" new_runline puts $scriptFileId $new_runline } elseif {[regexp {XFAIL:[ *](.+)} $line match targets]} { From lattner at cs.uiuc.edu Wed Mar 8 17:55:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 17:55:51 -0600 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp Message-ID: <200603082355.RAA16107@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.45 -> 1.46 --- Log message: Fix a really annoying bug in bugpoint that made reducing C++ testcases almost impossible with the new CFE. It now guarantees that the static ctor/dtor list is correctly split between the modules. --- Diffs of the changes: (+89 -4) ExtractFunction.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 89 insertions(+), 4 deletions(-) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.45 llvm/tools/bugpoint/ExtractFunction.cpp:1.46 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.45 Sun Jan 22 16:53:40 2006 +++ llvm/tools/bugpoint/ExtractFunction.cpp Wed Mar 8 17:55:38 2006 @@ -13,11 +13,11 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "llvm/Constant.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Pass.h" -#include "llvm/Type.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" @@ -74,6 +74,9 @@ // Remove the instruction from the program. TheInst->getParent()->getInstList().erase(TheInst); + + //writeProgramToFile("current.bc", Result); + // Spiff up the output a little bit. PassManager Passes; // Make sure that the appropriate target data is always used... @@ -170,6 +173,80 @@ assert(F->isExternal() && "This didn't make the function external!"); } +/// GetTorInit - Given a list of entries for static ctors/dtors, return them +/// as a constant array. +static Constant *GetTorInit(std::vector > &TorList) { + assert(!TorList.empty() && "Don't create empty tor list!"); + std::vector ArrayElts; + for (unsigned i = 0, e = TorList.size(); i != e; ++i) { + std::vector Elts; + Elts.push_back(ConstantSInt::get(Type::IntTy, TorList[i].second)); + Elts.push_back(TorList[i].first); + ArrayElts.push_back(ConstantStruct::get(Elts)); + } + return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(), + ArrayElts.size()), + ArrayElts); +} + +/// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and +/// M1 has all of the global variables. If M2 contains any functions that are +/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and +/// prune appropriate entries out of M1s list. +static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2){ + GlobalVariable *GV = M1->getNamedGlobal(GlobalName); + if (!GV || GV->isExternal() || GV->hasInternalLinkage() || + !GV->use_empty()) return; + + std::vector > M1Tors, M2Tors; + ConstantArray *InitList = dyn_cast(GV->getInitializer()); + if (!InitList) return; + + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { + if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + + if (CS->getOperand(1)->isNullValue()) + break; // Found a null terminator, stop here. + + ConstantSInt *CI = dyn_cast(CS->getOperand(0)); + int Priority = CI ? CI->getValue() : 0; + + Constant *FP = CS->getOperand(1); + if (ConstantExpr *CE = dyn_cast(FP)) + if (CE->getOpcode() == Instruction::Cast) + FP = CE->getOperand(0); + if (Function *F = dyn_cast(FP)) { + if (!F->isExternal()) + M1Tors.push_back(std::make_pair(F, Priority)); + else { + // Map to M2's version of the function. + F = M2->getFunction(F->getName(), F->getFunctionType()); + M2Tors.push_back(std::make_pair(F, Priority)); + } + } + } + } + + GV->eraseFromParent(); + if (!M1Tors.empty()) { + Constant *M1Init = GetTorInit(M1Tors); + new GlobalVariable(M1Init->getType(), false, GlobalValue::AppendingLinkage, + M1Init, GlobalName, M1); + } + + GV = M2->getNamedGlobal(GlobalName); + assert(GV && "Not a clone of M1?"); + assert(GV->use_empty() && "llvm.ctors shouldn't have uses!"); + + GV->eraseFromParent(); + if (!M2Tors.empty()) { + Constant *M2Init = GetTorInit(M2Tors); + new GlobalVariable(M2Init->getType(), false, GlobalValue::AppendingLinkage, + M2Init, GlobalName, M2); + } +} + /// SplitFunctionsOutOfModule - Given a module and a list of functions in the /// module, split the functions OUT of the specified module, and place them in /// the new module. @@ -184,13 +261,15 @@ // between the two modules will work. for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); - for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); Module *New = CloneModule(M); // Make sure global initializers exist only in the safe module (CBE->.so) - for (Module::global_iterator I = New->global_begin(), E = New->global_end(); I != E; ++I) + for (Module::global_iterator I = New->global_begin(), E = New->global_end(); + I != E; ++I) I->setInitializer(0); // Delete the initializer to make it external // Remove the Test functions from the Safe module @@ -207,6 +286,12 @@ for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I) if (!TestFunctions.count(std::make_pair(I->getName(), I->getType()))) DeleteFunctionBody(I); + + // Make sure that there is a global ctor/dtor array in both halves of the + // module if they both have static ctor/dtor functions. + SplitStaticCtorDtor("llvm.global_ctors", M, New); + SplitStaticCtorDtor("llvm.global_dtors", M, New); + return New; } From lattner at cs.uiuc.edu Wed Mar 8 19:39:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 8 Mar 2006 19:39:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200603090139.TAA16869@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.64 -> 1.65 --- Log message: a couple of miscellaneous things. --- Diffs of the changes: (+18 -0) README.txt | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.64 llvm/lib/Target/X86/README.txt:1.65 --- llvm/lib/Target/X86/README.txt:1.64 Sat Mar 4 19:15:18 2006 +++ llvm/lib/Target/X86/README.txt Wed Mar 8 19:39:46 2006 @@ -566,3 +566,21 @@ jb LBB_foo_3 # no_exit //===---------------------------------------------------------------------===// + +Codegen: + if (copysign(1.0, x) == copysign(1.0, y)) +into: + if (x^y & mask) +when using SSE. + +//===---------------------------------------------------------------------===// + +Optimize this into something reasonable: + x * copysign(1.0, y) * copysign(1.0, z) + +//===---------------------------------------------------------------------===// + +Optimize copysign(x, *y) to use an integer load from y. + +//===---------------------------------------------------------------------===// + From lattner at cs.uiuc.edu Thu Mar 9 00:00:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:00:18 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200603090600.AAA21194@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.349 -> 1.350 --- Log message: Use $(Verb) instead of @ so that VERBOSE=1 will print these. --- Diffs of the changes: (+2 -2) Makefile.rules | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.349 llvm/Makefile.rules:1.350 --- llvm/Makefile.rules:1.349 Thu Mar 2 19:54:54 2006 +++ llvm/Makefile.rules Thu Mar 9 00:00:05 2006 @@ -1096,11 +1096,11 @@ ifdef DEBUG_RUNTIME $(ObjectsBC): $(ObjDir)/%.bc: $(ObjDir)/%.ll $(GCCAS) $(Echo) "Compiling $*.ll to $*.bc for $(BuildMode) build (bytecode)" - @$(GCCAS) $< -o $@ + $(Verb) $(GCCAS) $< -o $@ else $(ObjectsBC): $(ObjDir)/%.bc: $(ObjDir)/%.ll $(GCCAS) $(Echo) "Compiling $*.ll to $*.bc for $(BuildMode) build (bytecode)" - @$(GCCAS) -strip-debug $< -o $@ + $(Verb) $(GCCAS) -strip-debug $< -o $@ endif From lattner at cs.uiuc.edu Thu Mar 9 00:09:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:09:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200603090609.AAA21274@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: StripSymbols.cpp updated: 1.4 -> 1.5 --- Log message: fix a pasto --- Diffs of the changes: (+1 -1) StripSymbols.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/IPO/StripSymbols.cpp diff -u llvm/lib/Transforms/IPO/StripSymbols.cpp:1.4 llvm/lib/Transforms/IPO/StripSymbols.cpp:1.5 --- llvm/lib/Transforms/IPO/StripSymbols.cpp:1.4 Thu Apr 21 18:39:37 2005 +++ llvm/lib/Transforms/IPO/StripSymbols.cpp Thu Mar 9 00:09:41 2006 @@ -100,7 +100,7 @@ // Remove all of the calls to the debugger intrinsics, and remove them from // the module. if (FuncStart) { - Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); + Value *RV = UndefValue::get(FuncStart->getFunctionType()->getReturnType()); while (!FuncStart->use_empty()) { CallInst *CI = cast(FuncStart->use_back()); Value *Arg = CI->getOperand(1); From lattner at cs.uiuc.edu Thu Mar 9 00:14:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:14:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64AsmPrinter.cpp Message-ID: <200603090614.AAA21364@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64AsmPrinter.cpp updated: 1.23 -> 1.24 --- Log message: Add support for 'special' llvm globals like debug info and static ctors/dtors. --- Diffs of the changes: (+4 -0) IA64AsmPrinter.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/IA64/IA64AsmPrinter.cpp diff -u llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.23 llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.24 --- llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.23 Thu Feb 16 07:12:57 2006 +++ llvm/lib/Target/IA64/IA64AsmPrinter.cpp Thu Mar 9 00:14:35 2006 @@ -288,6 +288,10 @@ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (I->hasInitializer()) { // External global require no code + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(I)) + continue; + O << "\n\n"; std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); From lattner at cs.uiuc.edu Thu Mar 9 00:14:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:14:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Message-ID: <200603090614.AAA21360@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaAsmPrinter.cpp updated: 1.32 -> 1.33 --- Log message: Add support for 'special' llvm globals like debug info and static ctors/dtors. --- Diffs of the changes: (+4 -0) AlphaAsmPrinter.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp diff -u llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.32 llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.33 --- llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.32 Mon Feb 27 04:29:04 2006 +++ llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Thu Mar 9 00:14:35 2006 @@ -231,6 +231,10 @@ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (I->hasInitializer()) { // External global require no code + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(I)) + continue; + O << "\n\n"; std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); From lattner at cs.uiuc.edu Thu Mar 9 00:14:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:14:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Message-ID: <200603090614.AAA21356@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcAsmPrinter.cpp updated: 1.56 -> 1.57 --- Log message: Add support for 'special' llvm globals like debug info and static ctors/dtors. --- Diffs of the changes: (+6 -1) SparcAsmPrinter.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp diff -u llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.56 llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.57 --- llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.56 Mon Feb 27 14:09:23 2006 +++ llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Thu Mar 9 00:14:35 2006 @@ -239,8 +239,13 @@ const TargetData &TD = TM.getTargetData(); // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) if (I->hasInitializer()) { // External global require no code + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(I)) + continue; + O << "\n\n"; std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); From lattner at cs.uiuc.edu Thu Mar 9 00:16:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:16:41 -0600 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Makefile README.txt crtend.c listend.ll Message-ID: <200603090616.AAA21459@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Makefile updated: 1.32 -> 1.33 README.txt updated: 1.1 -> 1.2 crtend.c updated: 1.5 -> 1.6 listend.ll (r1.4) removed --- Log message: Make the new and old front-ends more similar: now neither uses __main. --- Diffs of the changes: (+5 -60) Makefile | 4 ++-- README.txt | 2 +- crtend.c | 59 ++--------------------------------------------------------- 3 files changed, 5 insertions(+), 60 deletions(-) Index: llvm/runtime/GCCLibraries/crtend/Makefile diff -u llvm/runtime/GCCLibraries/crtend/Makefile:1.32 llvm/runtime/GCCLibraries/crtend/Makefile:1.33 --- llvm/runtime/GCCLibraries/crtend/Makefile:1.32 Sun Jan 29 20:03:56 2006 +++ llvm/runtime/GCCLibraries/crtend/Makefile Thu Mar 9 00:16:28 2006 @@ -20,7 +20,7 @@ LIBRARYNAME = crtend BYTECODE_DESTINATION = $(CFERuntimeLibDir) -MainSrc := crtend.c listend.ll +MainSrc := crtend.c GenericEHSrc := Exception.cpp SJLJEHSrc := SJLJ-Exception.cpp @@ -29,7 +29,7 @@ include $(LEVEL)/Makefile.common -MainObj := $(ObjDir)/crtend.bc $(ObjDir)/listend.bc +MainObj := $(ObjDir)/crtend.bc GenericEHObj := $(ObjDir)/Exception.bc SJLJEHObj := $(ObjDir)/SJLJ-Exception.bc Index: llvm/runtime/GCCLibraries/crtend/README.txt diff -u llvm/runtime/GCCLibraries/crtend/README.txt:1.1 llvm/runtime/GCCLibraries/crtend/README.txt:1.2 --- llvm/runtime/GCCLibraries/crtend/README.txt:1.1 Sat Nov 29 03:22:53 2003 +++ llvm/runtime/GCCLibraries/crtend/README.txt Thu Mar 9 00:16:28 2006 @@ -1,7 +1,7 @@ This directory contains the C and C++ runtime libraries for the LLVM GCC front-ends. It is composed of four distinct pieces: -1. __main and static ctor/dtor support. This is used by both C and C++ codes. +1. __main: now dead, but provided for compatibility. 2. Generic EH support routines. This is used by C/C++ programs that use setjmp/longjmp, and by C++ programs that make use of exceptions. Index: llvm/runtime/GCCLibraries/crtend/crtend.c diff -u llvm/runtime/GCCLibraries/crtend/crtend.c:1.5 llvm/runtime/GCCLibraries/crtend/crtend.c:1.6 --- llvm/runtime/GCCLibraries/crtend/crtend.c:1.5 Wed Aug 4 19:20:51 2004 +++ llvm/runtime/GCCLibraries/crtend/crtend.c Thu Mar 9 00:16:28 2006 @@ -7,65 +7,10 @@ * *===----------------------------------------------------------------------===* * - * This file defines the __main function, which is used to run static - * constructors and destructors in C++ programs, or with C programs that use GCC - * extensions to accomplish the same effect. - * - * The main data structures used to implement this functionality is the - * llvm.global_ctors and llvm.global_dtors lists, which are null terminated - * lists of TorRec (defined below) structures. + * This file defines the __main function, which we preserve for backwards + * compatibility. * \*===----------------------------------------------------------------------===*/ -#include - -/* TorRec - The record type for each element of the ctor/dtor list */ -typedef struct TorRec { - int Priority; - void (*FP)(void); -} TorRec; - -/* __llvm_getGlobalCtors, __llvm_getGlobalDtors - Interface to the LLVM - * listend.ll file to get access to the start of the ctor and dtor lists... - */ -TorRec *__llvm_getGlobalCtors(void); -TorRec *__llvm_getGlobalDtors(void); - -static void run_destructors(void); - -/* __main - A call to this function is automatically inserted into the top of - * the "main" function in the program compiled. This function is responsible - * for calling static constructors before the program starts executing. - */ void __main(void) { - /* Loop over all of the constructor records, calling each function pointer. */ - TorRec *R = __llvm_getGlobalCtors(); - - /* Recursively calling main is not legal C, but lots of people do it for - * testing stuff. We might as well work for them. - */ - static _Bool Initialized = 0; - if (Initialized) return; - Initialized = 1; - - /* Only register the global dtor handler if there is at least one global - * dtor! - */ - if (__llvm_getGlobalDtors()[0].FP) - if (atexit(run_destructors)) - abort(); /* Should be able to install ONE atexit handler! */ - - /* FIXME: This should sort the list by priority! */ - if (R->FP) - for (; R->FP; ++R) - R->FP(); -} - -static void run_destructors(void) { - /* Loop over all of the destructor records, calling each function pointer. */ - TorRec *R = __llvm_getGlobalDtors(); - - /* FIXME: This should sort the list by priority! */ - for (; R->FP; ++R) - R->FP(); } From lattner at cs.uiuc.edu Thu Mar 9 00:35:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:35:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603090635.AAA21598@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.25 -> 1.26 --- Log message: Refactor the priority mechanism one step further: now that it is a separate class, sever its implementation from the interface. Now we can provide new implementations of the same interface (priority computation) without touching the scheduler itself. --- Diffs of the changes: (+185 -136) ScheduleDAGList.cpp | 321 +++++++++++++++++++++++++++++----------------------- 1 files changed, 185 insertions(+), 136 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.25 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.26 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.25 Tue Mar 7 23:18:27 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 00:35:14 2006 @@ -118,137 +118,25 @@ } } -namespace { - class SchedulingPriorityQueue; - - /// Sorting functions for the Available queue. - struct ls_rr_sort : public std::binary_function { - SchedulingPriorityQueue *SPQ; - ls_rr_sort(SchedulingPriorityQueue *spq) : SPQ(spq) {} - ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} - - bool operator()(const SUnit* left, const SUnit* right) const; - }; -} // end anonymous namespace - -namespace { - class SchedulingPriorityQueue { - // SUnits - The SUnits for the current graph. - std::vector &SUnits; - - // SethiUllmanNumbers - The SethiUllman number for each node. - std::vector SethiUllmanNumbers; - - std::priority_queue, ls_rr_sort> Queue; - public: - SchedulingPriorityQueue(std::vector &sunits) - : SUnits(sunits), Queue(ls_rr_sort(this)) { - // Calculate node priorities. - CalculatePriorities(); - } - - unsigned getSethiUllmanNumber(unsigned NodeNum) const { - assert(NodeNum < SethiUllmanNumbers.size()); - return SethiUllmanNumbers[NodeNum]; - } - - bool empty() const { return Queue.empty(); } - - void push(SUnit *U) { - Queue.push(U); - } - SUnit *pop() { - SUnit *V = Queue.top(); - Queue.pop(); - return V; - } - private: - void CalculatePriorities(); - int CalcNodePriority(SUnit *SU); - }; -} - -bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { - unsigned LeftNum = left->NodeNum; - unsigned RightNum = right->NodeNum; - - int LBonus = (int)left ->isDefNUseOperand; - int RBonus = (int)right->isDefNUseOperand; - - // Special tie breaker: if two nodes share a operand, the one that - // use it as a def&use operand is preferred. - if (left->isTwoAddress && !right->isTwoAddress) { - SDNode *DUNode = left->Node->getOperand(0).Val; - if (DUNode->isOperand(right->Node)) - LBonus++; - } - if (!left->isTwoAddress && right->isTwoAddress) { - SDNode *DUNode = right->Node->getOperand(0).Val; - if (DUNode->isOperand(left->Node)) - RBonus++; - } - - // Priority1 is just the number of live range genned. - int LPriority1 = left ->NumPredsLeft - LBonus; - int RPriority1 = right->NumPredsLeft - RBonus; - int LPriority2 = SPQ->getSethiUllmanNumber(LeftNum) + LBonus; - int RPriority2 = SPQ->getSethiUllmanNumber(RightNum) + RBonus; +//===----------------------------------------------------------------------===// +// SchedulingPriorityQueue - This interface is used to plug different +// priorities computation algorithms into the list scheduler. It implements the +// interface of a standard priority queue, where nodes are inserted in arbitrary +// order and returned in priority order. The computation of the priority and +// the representation of the queue are totally up to the implementation to +// decide. +// +class SchedulingPriorityQueue { +public: + virtual ~SchedulingPriorityQueue() {} - if (LPriority1 > RPriority1) - return true; - else if (LPriority1 == RPriority1) - if (LPriority2 < RPriority2) - return true; - else if (LPriority2 == RPriority2) - if (left->CycleBound > right->CycleBound) - return true; + virtual void initNodes(const std::vector &SUnits) = 0; + virtual void releaseState() = 0; - return false; -} - - -/// CalcNodePriority - Priority is the Sethi Ullman number. -/// Smaller number is the higher priority. -int SchedulingPriorityQueue::CalcNodePriority(SUnit *SU) { - int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; - if (SethiUllmanNumber != INT_MIN) - return SethiUllmanNumber; - - if (SU->Preds.size() == 0) { - SethiUllmanNumber = 1; - } else { - int Extra = 0; - for (std::set::iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) { - SUnit *PredSU = *I; - int PredSethiUllman = CalcNodePriority(PredSU); - if (PredSethiUllman > SethiUllmanNumber) { - SethiUllmanNumber = PredSethiUllman; - Extra = 0; - } else if (PredSethiUllman == SethiUllmanNumber) - Extra++; - } - - if (SU->Node->getOpcode() != ISD::TokenFactor) - SethiUllmanNumber += Extra; - else - SethiUllmanNumber = (Extra == 1) ? 0 : Extra-1; - } - - return SethiUllmanNumber; -} - -/// CalculatePriorities - Calculate priorities of all scheduling units. -void SchedulingPriorityQueue::CalculatePriorities() { - SethiUllmanNumbers.assign(SUnits.size(), INT_MIN); - - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - // FIXME: assumes uniform latency for now. - SUnits[i].Latency = 1; - (void)CalcNodePriority(&SUnits[i]); - } -} - + virtual bool empty() const = 0; + virtual void push(SUnit *U) = 0; + virtual SUnit *pop() = 0; +}; @@ -270,19 +158,25 @@ /// it is top-down. bool isBottomUp; + /// PriorityQueue - The priority queue to use. + SchedulingPriorityQueue *PriorityQueue; + /// HazardRec - The hazard recognizer to use. HazardRecognizer *HazardRec; public: ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, + SchedulingPriorityQueue *priorityqueue, HazardRecognizer *HR) : ScheduleDAG(listSchedulingBURR, dag, bb, tm), - CurrCycle(0), isBottomUp(isbottomup), HazardRec(HR) { + CurrCycle(0), isBottomUp(isbottomup), + PriorityQueue(priorityqueue), HazardRec(HR) { } ~ScheduleDAGList() { delete HazardRec; + delete PriorityQueue; } void Schedule(); @@ -603,6 +497,9 @@ SU = NewSUnit(N); } SUnitMap[N] = SU; + + // FIXME: assumes uniform latency for now. + SU->Latency = 1; } // Pass 2: add the preds, succs, etc. @@ -701,14 +598,16 @@ // Build scheduling units. BuildSchedUnits(); - SchedulingPriorityQueue PQ(SUnits); - + PriorityQueue->initNodes(SUnits); + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) - ListScheduleBottomUp(PQ); + ListScheduleBottomUp(*PriorityQueue); else - ListScheduleTopDown(PQ); - + ListScheduleTopDown(*PriorityQueue); + + PriorityQueue->releaseState(); + DEBUG(std::cerr << "*** Final schedule ***\n"); DEBUG(dump()); DEBUG(std::cerr << "\n"); @@ -717,9 +616,157 @@ EmitSchedule(); } +//===----------------------------------------------------------------------===// +// RegReductionPriorityQueue Implementation +//===----------------------------------------------------------------------===// +// +// This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers +// to reduce register pressure. +// +namespace { + class RegReductionPriorityQueue; + + /// Sorting functions for the Available queue. + struct ls_rr_sort : public std::binary_function { + RegReductionPriorityQueue *SPQ; + ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} + ls_rr_sort(const ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} + + bool operator()(const SUnit* left, const SUnit* right) const; + }; +} // end anonymous namespace + +namespace { + class RegReductionPriorityQueue : public SchedulingPriorityQueue { + // SUnits - The SUnits for the current graph. + const std::vector *SUnits; + + // SethiUllmanNumbers - The SethiUllman number for each node. + std::vector SethiUllmanNumbers; + + std::priority_queue, ls_rr_sort> Queue; + public: + RegReductionPriorityQueue() : Queue(ls_rr_sort(this)) { + } + + void initNodes(const std::vector &sunits) { + SUnits = &sunits; + // Calculate node priorities. + CalculatePriorities(); + } + void releaseState() { + SUnits = 0; + SethiUllmanNumbers.clear(); + } + + unsigned getSethiUllmanNumber(unsigned NodeNum) const { + assert(NodeNum < SethiUllmanNumbers.size()); + return SethiUllmanNumbers[NodeNum]; + } + + bool empty() const { return Queue.empty(); } + + void push(SUnit *U) { + Queue.push(U); + } + SUnit *pop() { + SUnit *V = Queue.top(); + Queue.pop(); + return V; + } + private: + void CalculatePriorities(); + int CalcNodePriority(const SUnit *SU); + }; +} + +bool ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { + unsigned LeftNum = left->NodeNum; + unsigned RightNum = right->NodeNum; + + int LBonus = (int)left ->isDefNUseOperand; + int RBonus = (int)right->isDefNUseOperand; + + // Special tie breaker: if two nodes share a operand, the one that + // use it as a def&use operand is preferred. + if (left->isTwoAddress && !right->isTwoAddress) { + SDNode *DUNode = left->Node->getOperand(0).Val; + if (DUNode->isOperand(right->Node)) + LBonus++; + } + if (!left->isTwoAddress && right->isTwoAddress) { + SDNode *DUNode = right->Node->getOperand(0).Val; + if (DUNode->isOperand(left->Node)) + RBonus++; + } + + // Priority1 is just the number of live range genned. + int LPriority1 = left ->NumPredsLeft - LBonus; + int RPriority1 = right->NumPredsLeft - RBonus; + int LPriority2 = SPQ->getSethiUllmanNumber(LeftNum) + LBonus; + int RPriority2 = SPQ->getSethiUllmanNumber(RightNum) + RBonus; + + if (LPriority1 > RPriority1) + return true; + else if (LPriority1 == RPriority1) + if (LPriority2 < RPriority2) + return true; + else if (LPriority2 == RPriority2) + if (left->CycleBound > right->CycleBound) + return true; + + return false; +} + + +/// CalcNodePriority - Priority is the Sethi Ullman number. +/// Smaller number is the higher priority. +int RegReductionPriorityQueue::CalcNodePriority(const SUnit *SU) { + int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum]; + if (SethiUllmanNumber != INT_MIN) + return SethiUllmanNumber; + + if (SU->Preds.size() == 0) { + SethiUllmanNumber = 1; + } else { + int Extra = 0; + for (std::set::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) { + SUnit *PredSU = *I; + int PredSethiUllman = CalcNodePriority(PredSU); + if (PredSethiUllman > SethiUllmanNumber) { + SethiUllmanNumber = PredSethiUllman; + Extra = 0; + } else if (PredSethiUllman == SethiUllmanNumber) + Extra++; + } + + if (SU->Node->getOpcode() != ISD::TokenFactor) + SethiUllmanNumber += Extra; + else + SethiUllmanNumber = (Extra == 1) ? 0 : Extra-1; + } + + return SethiUllmanNumber; +} + +/// CalculatePriorities - Calculate priorities of all scheduling units. +void RegReductionPriorityQueue::CalculatePriorities() { + SethiUllmanNumbers.assign(SUnits->size(), INT_MIN); + + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) + CalcNodePriority(&(*SUnits)[i]); +} + + +//===----------------------------------------------------------------------===// +// Public Constructor Functions +//===----------------------------------------------------------------------===// + llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB) { return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, + new RegReductionPriorityQueue(), new HazardRecognizer()); } @@ -728,5 +775,7 @@ ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB, HazardRecognizer *HR) { - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, HR); + return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, + new RegReductionPriorityQueue(), + HR); } From lattner at cs.uiuc.edu Thu Mar 9 00:37:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:37:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603090637.AAA21663@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.26 -> 1.27 --- Log message: add some comments --- Diffs of the changes: (+13 -8) ScheduleDAGList.cpp | 21 +++++++++++++-------- 1 files changed, 13 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.26 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.27 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.26 Thu Mar 9 00:35:14 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 00:37:29 2006 @@ -119,13 +119,14 @@ } //===----------------------------------------------------------------------===// -// SchedulingPriorityQueue - This interface is used to plug different -// priorities computation algorithms into the list scheduler. It implements the -// interface of a standard priority queue, where nodes are inserted in arbitrary -// order and returned in priority order. The computation of the priority and -// the representation of the queue are totally up to the implementation to -// decide. -// +/// SchedulingPriorityQueue - This interface is used to plug different +/// priorities computation algorithms into the list scheduler. It implements the +/// interface of a standard priority queue, where nodes are inserted in +/// arbitrary order and returned in priority order. The computation of the +/// priority and the representation of the queue are totally up to the +/// implementation to decide. +/// +namespace { class SchedulingPriorityQueue { public: virtual ~SchedulingPriorityQueue() {} @@ -137,11 +138,15 @@ virtual void push(SUnit *U) = 0; virtual SUnit *pop() = 0; }; +} namespace { -/// ScheduleDAGList - List scheduler. +//===----------------------------------------------------------------------===// +/// ScheduleDAGList - The actual list scheduler implementation. This supports +/// both top-down and bottom-up scheduling. +/// class ScheduleDAGList : public ScheduleDAG { private: // SDNode to SUnit mapping (many to one). From lattner at cs.uiuc.edu Thu Mar 9 00:48:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 00:48:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603090648.AAA21753@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.27 -> 1.28 --- Log message: PriorityQueue is an instance var, use it. --- Diffs of the changes: (+33 -39) ScheduleDAGList.cpp | 72 +++++++++++++++++++++++----------------------------- 1 files changed, 33 insertions(+), 39 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.27 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.28 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.27 Thu Mar 9 00:37:29 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 00:48:37 2006 @@ -190,14 +190,12 @@ private: SUnit *NewSUnit(SDNode *N); - void ReleasePred(SchedulingPriorityQueue &Avail, - SUnit *PredSU, bool isChain = false); - void ReleaseSucc(SchedulingPriorityQueue &Avail, - SUnit *SuccSU, bool isChain = false); - void ScheduleNodeBottomUp(SchedulingPriorityQueue &Avail, SUnit *SU); - void ScheduleNodeTopDown(SchedulingPriorityQueue &Avail, SUnit *SU); - void ListScheduleTopDown(SchedulingPriorityQueue &Available); - void ListScheduleBottomUp(SchedulingPriorityQueue &Available); + void ReleasePred(SUnit *PredSU, bool isChain = false); + void ReleaseSucc(SUnit *SuccSU, bool isChain = false); + void ScheduleNodeBottomUp(SUnit *SU); + void ScheduleNodeTopDown(SUnit *SU); + void ListScheduleTopDown(); + void ListScheduleBottomUp(); void BuildSchedUnits(); void EmitSchedule(); }; @@ -214,8 +212,7 @@ /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleasePred(SchedulingPriorityQueue &Available, - SUnit *PredSU, bool isChain) { +void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the @@ -239,14 +236,13 @@ if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) { // EntryToken has to go last! Special case it here. if (PredSU->Node->getOpcode() != ISD::EntryToken) - Available.push(PredSU); + PriorityQueue->push(PredSU); } } /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleaseSucc(SchedulingPriorityQueue &Available, - SUnit *SuccSU, bool isChain) { +void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the @@ -268,14 +264,13 @@ #endif if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) - Available.push(SuccSU); + PriorityQueue->push(SuccSU); } /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeBottomUp(SchedulingPriorityQueue &Available, - SUnit *SU) { +void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG, false)); @@ -284,12 +279,12 @@ // Bottom up: release predecessors for (std::set::iterator I1 = SU->Preds.begin(), E1 = SU->Preds.end(); I1 != E1; ++I1) { - ReleasePred(Available, *I1); + ReleasePred(*I1); SU->NumPredsLeft--; } for (std::set::iterator I2 = SU->ChainPreds.begin(), E2 = SU->ChainPreds.end(); I2 != E2; ++I2) - ReleasePred(Available, *I2, true); + ReleasePred(*I2, true); CurrCycle++; } @@ -297,8 +292,7 @@ /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeTopDown(SchedulingPriorityQueue &Available, - SUnit *SU) { +void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG, false)); @@ -307,12 +301,12 @@ // Bottom up: release successors. for (std::set::iterator I1 = SU->Succs.begin(), E1 = SU->Succs.end(); I1 != E1; ++I1) { - ReleaseSucc(Available, *I1); + ReleaseSucc(*I1); SU->NumSuccsLeft--; } for (std::set::iterator I2 = SU->ChainSuccs.begin(), E2 = SU->ChainSuccs.end(); I2 != E2; ++I2) - ReleaseSucc(Available, *I2, true); + ReleaseSucc(*I2, true); CurrCycle++; } @@ -325,28 +319,28 @@ /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up /// schedulers. -void ScheduleDAGList::ListScheduleBottomUp(SchedulingPriorityQueue &Available) { +void ScheduleDAGList::ListScheduleBottomUp() { // Add root to Available queue. - Available.push(SUnitMap[DAG.getRoot().Val]); + PriorityQueue->push(SUnitMap[DAG.getRoot().Val]); // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; - while (!Available.empty()) { - SUnit *CurrNode = Available.pop(); + while (!PriorityQueue->empty()) { + SUnit *CurrNode = PriorityQueue->pop(); while (!isReady(CurrNode, CurrCycle)) { NotReady.push_back(CurrNode); - CurrNode = Available.pop(); + CurrNode = PriorityQueue->pop(); } // Add the nodes that aren't ready back onto the available list. while (!NotReady.empty()) { - Available.push(NotReady.back()); + PriorityQueue->push(NotReady.back()); NotReady.pop_back(); } - ScheduleNodeBottomUp(Available, CurrNode); + ScheduleNodeBottomUp(CurrNode); } // Add entry node last @@ -377,10 +371,10 @@ /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. -void ScheduleDAGList::ListScheduleTopDown(SchedulingPriorityQueue &Available) { +void ScheduleDAGList::ListScheduleTopDown() { // Emit the entry node first. SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; - ScheduleNodeTopDown(Available, Entry); + ScheduleNodeTopDown(Entry); HazardRec->EmitInstruction(Entry->Node); // All leaves to Available queue. @@ -388,18 +382,18 @@ // It is available if it has no predecessors. if ((SUnits[i].Preds.size() + SUnits[i].ChainPreds.size()) == 0 && &SUnits[i] != Entry) - Available.push(&SUnits[i]); + PriorityQueue->push(&SUnits[i]); } // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; - while (!Available.empty()) { + while (!PriorityQueue->empty()) { SUnit *FoundNode = 0; bool HasNoopHazards = false; do { - SUnit *CurNode = Available.pop(); + SUnit *CurNode = PriorityQueue->pop(); // Get the node represented by this SUnit. SDNode *N = CurNode->Node; @@ -419,17 +413,17 @@ HasNoopHazards |= HT == HazardRecognizer::NoopHazard; NotReady.push_back(CurNode); - } while (!Available.empty()); + } while (!PriorityQueue->empty()); // Add the nodes that aren't ready back onto the available list. while (!NotReady.empty()) { - Available.push(NotReady.back()); + PriorityQueue->push(NotReady.back()); NotReady.pop_back(); } // If we found a node to schedule, do it now. if (FoundNode) { - ScheduleNodeTopDown(Available, FoundNode); + ScheduleNodeTopDown(FoundNode); HazardRec->EmitInstruction(FoundNode->Node); } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance @@ -607,9 +601,9 @@ // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) - ListScheduleBottomUp(*PriorityQueue); + ListScheduleBottomUp(); else - ListScheduleTopDown(*PriorityQueue); + ListScheduleTopDown(); PriorityQueue->releaseState(); From lattner at cs.uiuc.edu Thu Mar 9 01:13:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 01:13:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Message-ID: <200603090713.BAA21910@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGSimple.cpp updated: 1.5 -> 1.6 --- Log message: don't copy all itinerary data --- Diffs of the changes: (+1 -1) ScheduleDAGSimple.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.5 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.6 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.5 Mon Jan 23 22:43:17 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Thu Mar 9 01:13:00 2006 @@ -292,7 +292,7 @@ /// void ScheduleDAGSimple::GatherSchedulingInfo() { // Get instruction itineraries for the target - const InstrItineraryData InstrItins = TM.getInstrItineraryData(); + const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); // For each node for (unsigned i = 0, N = NodeCount; i < N; i++) { From lattner at cs.uiuc.edu Thu Mar 9 01:15:31 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 01:15:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603090715.BAA21980@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.28 -> 1.29 --- Log message: Pull latency information for target instructions out of the latency tables. :) Only enable this with -use-sched-latencies, I'll enable it by default with a clean nightly tester run tonight. PPC is the only target that provides latency info currently. --- Diffs of the changes: (+80 -46) ScheduleDAGList.cpp | 126 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 80 insertions(+), 46 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.28 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.29 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.28 Thu Mar 9 00:48:37 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 01:15:18 2006 @@ -29,9 +29,12 @@ #include #include #include +#include "llvm/Support/CommandLine.h" using namespace llvm; namespace { + // FIXME: UseLatencies is temporary. + cl::opt UseLatencies("use-sched-latencies"); Statistic<> NumNoops ("scheduler", "Number of noops inserted"); Statistic<> NumStalls("scheduler", "Number of pipeline stalls"); @@ -60,11 +63,12 @@ isTwoAddress(false), isDefNUseOperand(false), Latency(0), CycleBound(0), NodeNum(nodenum) {} - void dump(const SelectionDAG *G, bool All=true) const; + void dump(const SelectionDAG *G) const; + void dumpAll(const SelectionDAG *G) const; }; } -void SUnit::dump(const SelectionDAG *G, bool All) const { +void SUnit::dump(const SelectionDAG *G) const { std::cerr << "SU: "; Node->dump(G); std::cerr << "\n"; @@ -75,47 +79,50 @@ std::cerr << "\n"; } } +} - if (All) { - std::cerr << " # preds left : " << NumPredsLeft << "\n"; - std::cerr << " # succs left : " << NumSuccsLeft << "\n"; - std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n"; - std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n"; - std::cerr << " Latency : " << Latency << "\n"; - - if (Preds.size() != 0) { - std::cerr << " Predecessors:\n"; - for (std::set::const_iterator I = Preds.begin(), - E = Preds.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G, false); - } +void SUnit::dumpAll(const SelectionDAG *G) const { + dump(G); + + std::cerr << " # preds left : " << NumPredsLeft << "\n"; + std::cerr << " # succs left : " << NumSuccsLeft << "\n"; + std::cerr << " # chain preds left : " << NumChainPredsLeft << "\n"; + std::cerr << " # chain succs left : " << NumChainSuccsLeft << "\n"; + std::cerr << " Latency : " << Latency << "\n"; + + if (Preds.size() != 0) { + std::cerr << " Predecessors:\n"; + for (std::set::const_iterator I = Preds.begin(), + E = Preds.end(); I != E; ++I) { + std::cerr << " "; + (*I)->dump(G); } - if (ChainPreds.size() != 0) { - std::cerr << " Chained Preds:\n"; - for (std::set::const_iterator I = ChainPreds.begin(), - E = ChainPreds.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G, false); - } + } + if (ChainPreds.size() != 0) { + std::cerr << " Chained Preds:\n"; + for (std::set::const_iterator I = ChainPreds.begin(), + E = ChainPreds.end(); I != E; ++I) { + std::cerr << " "; + (*I)->dump(G); } - if (Succs.size() != 0) { - std::cerr << " Successors:\n"; - for (std::set::const_iterator I = Succs.begin(), - E = Succs.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G, false); - } + } + if (Succs.size() != 0) { + std::cerr << " Successors:\n"; + for (std::set::const_iterator I = Succs.begin(), + E = Succs.end(); I != E; ++I) { + std::cerr << " "; + (*I)->dump(G); } - if (ChainSuccs.size() != 0) { - std::cerr << " Chained succs:\n"; - for (std::set::const_iterator I = ChainSuccs.begin(), - E = ChainSuccs.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G, false); - } + } + if (ChainSuccs.size() != 0) { + std::cerr << " Chained succs:\n"; + for (std::set::const_iterator I = ChainSuccs.begin(), + E = ChainSuccs.end(); I != E; ++I) { + std::cerr << " "; + (*I)->dump(G); } } + std::cerr << "\n"; } //===----------------------------------------------------------------------===// @@ -186,7 +193,7 @@ void Schedule(); - void dump() const; + void dumpSchedule() const; private: SUnit *NewSUnit(SDNode *N); @@ -272,7 +279,7 @@ /// the Available queue. void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU) { DEBUG(std::cerr << "*** Scheduling: "); - DEBUG(SU->dump(&DAG, false)); + DEBUG(SU->dump(&DAG)); Sequence.push_back(SU); @@ -294,7 +301,7 @@ /// the Available queue. void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) { DEBUG(std::cerr << "*** Scheduling: "); - DEBUG(SU->dump(&DAG, false)); + DEBUG(SU->dump(&DAG)); Sequence.push_back(SU); @@ -465,6 +472,8 @@ // invalidated. SUnits.reserve(NodeCount); + const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); + // Pass 1: create the SUnit's. for (unsigned i = 0, NC = NodeCount; i < NC; i++) { NodeInfo *NI = &Info[i]; @@ -496,9 +505,32 @@ SU = NewSUnit(N); } SUnitMap[N] = SU; - - // FIXME: assumes uniform latency for now. - SU->Latency = 1; + + // Compute the latency for the node. We use the sum of the latencies for + // all nodes flagged together into this SUnit. + if (InstrItins.isEmpty() || !UseLatencies) { + // No latency information. + SU->Latency = 1; + } else { + SU->Latency = 0; + if (N->isTargetOpcode()) { + unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode()); + InstrStage *S = InstrItins.begin(SchedClass); + InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + SU->Latency += S->Cycles; + } + for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) { + SDNode *FNode = SU->FlaggedNodes[i]; + if (FNode->isTargetOpcode()) { + unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode()); + InstrStage *S = InstrItins.begin(SchedClass); + InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + SU->Latency += S->Cycles; + } + } + } } // Pass 2: add the preds, succs, etc. @@ -559,6 +591,8 @@ } } } + + DEBUG(SU->dumpAll(&DAG)); } } @@ -579,10 +613,10 @@ } /// dump - dump the schedule. -void ScheduleDAGList::dump() const { +void ScheduleDAGList::dumpSchedule() const { for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) - SU->dump(&DAG, false); + SU->dump(&DAG); else std::cerr << "**** NOOP ****\n"; } @@ -608,7 +642,7 @@ PriorityQueue->releaseState(); DEBUG(std::cerr << "*** Final schedule ***\n"); - DEBUG(dump()); + DEBUG(dumpSchedule()); DEBUG(std::cerr << "\n"); // Emit in scheduled order From lattner at cs.uiuc.edu Thu Mar 9 01:16:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 01:16:04 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200603090716.BAA22015@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.196 -> 1.197 --- Log message: test -use-sched-latencies as llc beta tonight. --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.196 llvm-test/Makefile.programs:1.197 --- llvm-test/Makefile.programs:1.196 Tue Mar 7 00:47:05 2006 +++ llvm-test/Makefile.programs Thu Mar 9 01:15:51 2006 @@ -187,7 +187,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -sched=list-td +LLCBETAOPTION := -use-sched-latencies endif ifeq ($(ARCH),Alpha) LLCBETAOPTION := -enable-alpha-lsmark From lattner at cs.uiuc.edu Thu Mar 9 01:38:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 01:38:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603090738.BAA22166@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.29 -> 1.30 --- Log message: switch the t-d scheduler to use a really dumb and trivial critical path latency priority function. --- Diffs of the changes: (+104 -1) ScheduleDAGList.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 104 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.29 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.30 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.29 Thu Mar 9 01:15:18 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 01:38:27 2006 @@ -791,6 +791,109 @@ CalcNodePriority(&(*SUnits)[i]); } +//===----------------------------------------------------------------------===// +// LatencyPriorityQueue Implementation +//===----------------------------------------------------------------------===// +// +// This is a SchedulingPriorityQueue that schedules using latency information to +// reduce the length of the critical path through the basic block. +// +namespace { + class LatencyPriorityQueue; + + /// Sorting functions for the Available queue. + struct latency_sort : public std::binary_function { + LatencyPriorityQueue *PQ; + latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {} + latency_sort(const latency_sort &RHS) : PQ(RHS.PQ) {} + + bool operator()(const SUnit* left, const SUnit* right) const; + }; +} // end anonymous namespace + +namespace { + class LatencyPriorityQueue : public SchedulingPriorityQueue { + // SUnits - The SUnits for the current graph. + const std::vector *SUnits; + + // Latencies - The latency (max of latency from this node to the bb exit) + // for each node. + std::vector Latencies; + + std::priority_queue, latency_sort> Queue; +public: + LatencyPriorityQueue() : Queue(latency_sort(this)) { + } + + void initNodes(const std::vector &sunits) { + SUnits = &sunits; + // Calculate node priorities. + CalculatePriorities(); + } + void releaseState() { + SUnits = 0; + Latencies.clear(); + } + + unsigned getLatency(unsigned NodeNum) const { + assert(NodeNum < Latencies.size()); + return Latencies[NodeNum]; + } + + bool empty() const { return Queue.empty(); } + + void push(SUnit *U) { + Queue.push(U); + } + SUnit *pop() { + SUnit *V = Queue.top(); + Queue.pop(); + + std::cerr << "Got node. Latency: " << getLatency(V->NodeNum) + << " \n"; + return V; + } +private: + void CalculatePriorities(); + int CalcLatency(const SUnit &SU); + }; +} + +bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const { + unsigned LHSNum = LHS->NodeNum; + unsigned RHSNum = RHS->NodeNum; + + return PQ->getLatency(LHSNum) < PQ->getLatency(RHSNum); +} + + +/// CalcNodePriority - Calculate the maximal path from the node to the exit. +/// +int LatencyPriorityQueue::CalcLatency(const SUnit &SU) { + int &Latency = Latencies[SU.NodeNum]; + if (Latency != -1) + return Latency; + + int MaxSuccLatency = 0; + for (std::set::iterator I = SU.Succs.begin(), + E = SU.Succs.end(); I != E; ++I) + MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I)); + + for (std::set::iterator I = SU.ChainSuccs.begin(), + E = SU.ChainSuccs.end(); I != E; ++I) + MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I)); + + return Latency = MaxSuccLatency + SU.Latency; +} + +/// CalculatePriorities - Calculate priorities of all scheduling units. +void LatencyPriorityQueue::CalculatePriorities() { + Latencies.assign(SUnits->size(), -1); + + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) + CalcLatency((*SUnits)[i]); +} + //===----------------------------------------------------------------------===// // Public Constructor Functions @@ -809,6 +912,6 @@ MachineBasicBlock *BB, HazardRecognizer *HR) { return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, - new RegReductionPriorityQueue(), + new LatencyPriorityQueue(), HR); } From lattner at cs.uiuc.edu Thu Mar 9 01:39:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 01:39:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603090739.BAA22229@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.30 -> 1.31 --- Log message: yes yes, enabled debug output is bad --- Diffs of the changes: (+0 -3) ScheduleDAGList.cpp | 3 --- 1 files changed, 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.30 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.31 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.30 Thu Mar 9 01:38:27 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 01:39:25 2006 @@ -848,9 +848,6 @@ SUnit *pop() { SUnit *V = Queue.top(); Queue.pop(); - - std::cerr << "Got node. Latency: " << getLatency(V->NodeNum) - << " \n"; return V; } private: From evan.cheng at apple.com Thu Mar 9 02:19:26 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 9 Mar 2006 02:19:26 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200603090819.CAA25279@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.175 -> 1.176 --- Log message: Temporary hack to enable more (store (op (load ...))) folding. This makes it possible when a TokenFactor is between the load and store. But is still missing some cases due to ordering issue. --- Diffs of the changes: (+74 -30) DAGISelEmitter.cpp | 104 +++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 74 insertions(+), 30 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.175 llvm/utils/TableGen/DAGISelEmitter.cpp:1.176 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.175 Tue Mar 7 02:31:27 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Mar 9 02:19:11 2006 @@ -1866,6 +1866,7 @@ std::set > &GeneratedDecl; std::string ChainName; + bool NewTF; bool DoReplace; unsigned TmpNo; @@ -1888,7 +1889,8 @@ std::set > &gd, bool dorep) : ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), - GeneratedCode(gc), GeneratedDecl(gd), DoReplace(dorep), TmpNo(0) {} + GeneratedCode(gc), GeneratedDecl(gd), + NewTF(false), DoReplace(dorep), TmpNo(0) {} /// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo /// if the match fails. At this point, we already know that the opcode for N @@ -2018,14 +2020,19 @@ } if (NodeHasChain) { - if (FoundChain) - emitCheck("Chain.Val == " + RootName + ".Val"); - else - FoundChain = true; ChainName = "Chain" + ChainSuffix; emitDecl(ChainName); - emitCode(ChainName + " = " + RootName + - ".getOperand(0);"); + if (FoundChain) { + // FIXME: temporary workaround for a common case where chain + // is a TokenFactor and the previous "inner" chain is an operand. + NewTF = true; + emitDecl("OldTF", true); + emitCheck("(" + ChainName + " = UpdateFoldedChain(CurDAG, " + + RootName + ".Val, Chain.Val, OldTF)).Val"); + } else { + FoundChain = true; + emitCode(ChainName + " = " + RootName + ".getOperand(0);"); + } } } @@ -2272,11 +2279,11 @@ emitCode("bool HasOptInFlag = false;"); // How many results is this pattern expected to produce? - unsigned NumExpectedResults = 0; + unsigned PatResults = 0; for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) { MVT::ValueType VT = Pattern->getTypeNum(i); if (VT != MVT::isVoid && VT != MVT::Flag) - NumExpectedResults++; + PatResults++; } // Determine operand emission order. Complex pattern first. @@ -2405,61 +2412,64 @@ emitCode(Code + ");"); } - unsigned ValNo = 0; - for (unsigned i = 0; i < NumResults; i++) { + if (NewTF) + emitCode("if (OldTF) " + "SelectionDAG::InsertISelMapEntry(CodeGenMap, OldTF, 0, " + + ChainName + ".Val, 0);"); + + for (unsigned i = 0; i < NumResults; i++) emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(ValNo) + ", ResNode, " + utostr(ValNo) + ");"); - ValNo++; - } + utostr(i) + ", ResNode, " + utostr(i) + ");"); if (NodeHasOutFlag) emitCode("InFlag = SDOperand(ResNode, " + - utostr(ValNo + (unsigned)HasChain) + ");"); + utostr(NumResults + (unsigned)HasChain) + ");"); if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) { - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(ValNo) + ", ResNode, " + utostr(ValNo) + ");"); - ValNo++; + emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + "0, ResNode, 0);"); + NumResults = 1; } - // User does not expect the instruction would produce a chain! - bool AddedChain = HasChain && !NodeHasChain; if (NodeHasChain) { emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(ValNo) + ", ResNode, " + utostr(ValNo) + ");"); + utostr(PatResults) + ", ResNode, " + + utostr(NumResults) + ");"); if (DoReplace) - emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " - + utostr(ValNo) + ", " + "ResNode, " + utostr(ValNo) + ");"); - ValNo++; + emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " + + utostr(PatResults) + ", " + "ResNode, " + + utostr(NumResults) + ");"); } - if (FoldedChains.size() > 0) { std::string Code; for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, " + FoldedChains[j].first + ".Val, " + utostr(FoldedChains[j].second) + ", ResNode, " + - utostr(ValNo) + ");"); + utostr(NumResults) + ");"); for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) { std::string Code = FoldedChains[j].first + ".Val, " + utostr(FoldedChains[j].second) + ", "; emitCode("AddHandleReplacement(" + Code + "ResNode, " + - utostr(ValNo) + ");"); + utostr(NumResults) + ");"); } } if (NodeHasOutFlag) emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(ValNo) + ", InFlag.Val, InFlag.ResNo);"); + utostr(PatResults + (unsigned)NodeHasChain) + + ", InFlag.Val, InFlag.ResNo);"); + // User does not expect the instruction would produce a chain! + bool AddedChain = HasChain && !NodeHasChain; if (AddedChain && NodeHasOutFlag) { - if (NumExpectedResults == 0) { + if (PatResults == 0) { emitCode("Result = SDOperand(ResNode, N.ResNo+1);"); } else { - emitCode("if (N.ResNo < " + utostr(NumExpectedResults) + ")"); + emitCode("if (N.ResNo < " + utostr(PatResults) + ")"); emitCode(" Result = SDOperand(ResNode, N.ResNo);"); emitCode("else"); emitCode(" Result = SDOperand(ResNode, N.ResNo+1);"); @@ -3248,6 +3258,40 @@ OS << "}\n"; OS << "\n"; + OS << "// UpdateFoldedChain - return a SDOperand of the new chain created\n"; + OS << "// if the folding were to happen. This is called when, for example,\n"; + OS << "// a load is folded into a store. If the store's chain is the load,\n"; + OS << "// then the resulting node's input chain would be the load's input\n"; + OS << "// chain. If the store's chain is a TokenFactor and the load's\n"; + OS << "// output chain feeds into in, then the new chain is a TokenFactor\n"; + OS << "// with the other operands along with the input chain of the load.\n"; + OS << "SDOperand UpdateFoldedChain(SelectionDAG *DAG, SDNode *N, " + << "SDNode *Chain, SDNode* &OldTF) {\n"; + OS << " OldTF = NULL;\n"; + OS << " if (N == Chain) {\n"; + OS << " return N->getOperand(0);\n"; + OS << " } else if (Chain->getOpcode() == ISD::TokenFactor &&\n"; + OS << " N->isOperand(Chain)) {\n"; + OS << " SDOperand Ch = SDOperand(Chain, 0);\n"; + OS << " std::map::iterator CGMI = " + << "CodeGenMap.find(Ch);\n"; + OS << " if (CGMI != CodeGenMap.end())\n"; + OS << " return SDOperand(0, 0);\n"; + OS << " OldTF = Chain;\n"; + OS << " std::vector Ops;\n"; + OS << " for (unsigned i = 0; i < Chain->getNumOperands(); ++i) {\n"; + OS << " SDOperand Op = Chain->getOperand(i);\n"; + OS << " if (Op.Val == N)\n"; + OS << " Ops.push_back(N->getOperand(0));\n"; + OS << " else\n"; + OS << " Ops.push_back(Op);\n"; + OS << " }\n"; + OS << " return DAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n"; + OS << " }\n"; + OS << " return SDOperand(0, 0);\n"; + OS << "}\n"; + + OS << "\n"; OS << "// SelectRoot - Top level entry to DAG isel.\n"; OS << "SDOperand SelectRoot(SDOperand N) {\n"; OS << " SDOperand ResNode;\n"; From jlaskey at apple.com Thu Mar 9 07:29:00 2006 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 9 Mar 2006 07:29:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200603091329.HAA18201@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.44 -> 1.45 MachineDebugInfo.cpp updated: 1.27 -> 1.28 --- Log message: Move bit field endianness to backend. --- Diffs of the changes: (+29 -10) DwarfWriter.cpp | 36 ++++++++++++++++++++++++++---------- MachineDebugInfo.cpp | 3 +++ 2 files changed, 29 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.44 llvm/lib/CodeGen/DwarfWriter.cpp:1.45 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.44 Wed Mar 8 12:11:06 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Thu Mar 9 07:28:47 2006 @@ -1323,6 +1323,7 @@ unsigned Line = MemberDesc->getLine(); TypeDesc *MemTy = MemberDesc->getFromType(); uint64_t Size = MemberDesc->getSize(); + uint64_t Align = MemberDesc->getAlign(); uint64_t Offset = MemberDesc->getOffset(); // Construct member die. @@ -1338,27 +1339,42 @@ Member->AddUInt(DW_AT_decl_line, 0, Line); } - // FIXME - Bitfields not quite right but getting there. - uint64_t ByteSize = Size; - uint64_t ByteOffset = Offset; + // Most of the time the field info is the same as the members. + uint64_t FieldSize = Size; + uint64_t FieldAlign = Align; + uint64_t FieldOffset = Offset; if (TypeDesc *FromTy = MemberDesc->getFromType()) { Member->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); - ByteSize = FromTy->getSize(); + FieldSize = FromTy->getSize(); + FieldAlign = FromTy->getSize(); } - if (ByteSize != Size) { - ByteOffset -= Offset % ByteSize; - Member->AddUInt(DW_AT_byte_size, 0, ByteSize >> 3); - Member->AddUInt(DW_AT_bit_size, 0, Size % ByteSize); - Member->AddUInt(DW_AT_bit_offset, 0, Offset - ByteOffset); + // Unless we have a bit field. + if (FieldSize != Size) { + // Construct the alignment mask. + uint64_t AlignMask = ~(FieldAlign - 1); + // Determine the high bit + 1 of the declared size. + uint64_t HiMark = (Offset + FieldSize) & AlignMask; + // Work backwards to determine the base offset of the field. + FieldOffset = HiMark - FieldSize; + // Now normalize offset to the field. + Offset -= FieldOffset; + + // Maybe we need to work from the other. + const TargetData &TD = Asm->TM.getTargetData(); + if (TD.isLittleEndian()) Offset = FieldSize - (Offset + Size); + + Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3); + Member->AddUInt(DW_AT_bit_size, 0, Size); + Member->AddUInt(DW_AT_bit_offset, 0, Offset); } // Add computation for offset. DIEBlock *Block = new DIEBlock(); Block->AddUInt(DW_FORM_data1, DW_OP_plus_uconst); - Block->AddUInt(DW_FORM_udata, ByteOffset >> 3); + Block->AddUInt(DW_FORM_udata, FieldOffset >> 3); Block->ComputeSize(*this); Member->AddBlock(DW_AT_data_member_location, 0, Block); Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.27 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.28 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.27 Wed Mar 8 12:11:06 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Thu Mar 9 07:28:47 2006 @@ -653,6 +653,7 @@ , Name("") , File(NULL) , Size(0) +, Align(0) , Offset(0) {} @@ -666,6 +667,7 @@ Visitor->Apply((DebugInfoDesc *&)File); Visitor->Apply(Line); Visitor->Apply(Size); + Visitor->Apply(Align); Visitor->Apply(Offset); } @@ -690,6 +692,7 @@ << "File(" << File << "), " << "Line(" << Line << "), " << "Size(" << Size << "), " + << "Align(" << Align << "), " << "Offset(" << Offset << ")\n"; } #endif From alenhar2 at cs.uiuc.edu Thu Mar 9 08:57:49 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 08:57:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200603091457.IAA24617@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.49 -> 1.50 --- Log message: fcopysign support --- Diffs of the changes: (+1 -0) TargetSelectionDAG.td | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.49 llvm/lib/Target/TargetSelectionDAG.td:1.50 --- llvm/lib/Target/TargetSelectionDAG.td:1.49 Thu Mar 2 18:19:44 2006 +++ llvm/lib/Target/TargetSelectionDAG.td Thu Mar 9 08:57:36 2006 @@ -262,6 +262,7 @@ def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; +def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPBinOp>; def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; From alenhar2 at cs.uiuc.edu Thu Mar 9 08:58:38 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 08:58:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp AlphaInstrInfo.td Message-ID: <200603091458.IAA24639@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.39 -> 1.40 AlphaInstrInfo.td updated: 1.113 -> 1.114 --- Log message: fcopysign and get rid of dsnode cruft. custom PA runtimes make this better in some senses --- Diffs of the changes: (+15 -220) AlphaISelLowering.cpp | 165 -------------------------------------------------- AlphaInstrInfo.td | 70 ++++----------------- 2 files changed, 15 insertions(+), 220 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.39 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.40 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.39 Sat Mar 4 23:08:37 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Thu Mar 9 08:58:25 2006 @@ -26,12 +26,6 @@ using namespace llvm; -namespace llvm { - cl::opt EnableAlphaLSMark("enable-alpha-lsmark", - cl::desc("Emit symbols to correlate Mem ops to LLVM Values"), - cl::Hidden); -} - /// AddLiveIn - This helper function adds the specified physical register to the /// MachineFunction as a live in value. It also creates a corresponding virtual /// register for it. @@ -71,20 +65,6 @@ setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); - if (EnableAlphaLSMark) { - setOperationAction(ISD::LOAD, MVT::i64, Custom); - setOperationAction(ISD::LOAD, MVT::f64, Custom); - setOperationAction(ISD::LOAD, MVT::f32, Custom); - - setOperationAction(ISD::ZEXTLOAD, MVT::i8, Custom); - setOperationAction(ISD::ZEXTLOAD, MVT::i16, Custom); - setOperationAction(ISD::SEXTLOAD, MVT::i32, Custom); - - setOperationAction(ISD::EXTLOAD, MVT::i8, Custom); - setOperationAction(ISD::EXTLOAD, MVT::i16, Custom); - setOperationAction(ISD::EXTLOAD, MVT::i32, Custom); - } - setOperationAction(ISD::FREM, MVT::f32, Expand); setOperationAction(ISD::FREM, MVT::f64, Expand); @@ -175,18 +155,6 @@ case AlphaISD::GlobalBaseReg: return "Alpha::GlobalBaseReg"; case AlphaISD::CALL: return "Alpha::CALL"; case AlphaISD::DivCall: return "Alpha::DivCall"; - case AlphaISD::LDQ_: return "Alpha::LDQ_"; - case AlphaISD::LDT_: return "Alpha::LDT_"; - case AlphaISD::LDS_: return "Alpha::LDS_"; - case AlphaISD::LDL_: return "Alpha::LDL_"; - case AlphaISD::LDWU_: return "Alpha::LDWU_"; - case AlphaISD::LDBU_: return "Alpha::LDBU_"; - case AlphaISD::STQ_: return "Alpha::STQ_"; - case AlphaISD::STT_: return "Alpha::STT_"; - case AlphaISD::STS_: return "Alpha::STS_"; - case AlphaISD::STL_: return "Alpha::STL_"; - case AlphaISD::STW_: return "Alpha::STW_"; - case AlphaISD::STB_: return "Alpha::STB_"; } } @@ -395,48 +363,6 @@ BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(RA).addReg(RA); } - - -static void getValueInfo(const Value* v, int& type, int& fun, int& offset) -{ - fun = type = offset = 0; - if (v == NULL) { - type = 0; - } else if (const GlobalValue* GV = dyn_cast(v)) { - type = 1; - const Module* M = GV->getParent(); - for(Module::const_global_iterator ii = M->global_begin(); &*ii != GV; ++ii) - ++offset; - } else if (const Argument* Arg = dyn_cast(v)) { - type = 2; - const Function* F = Arg->getParent(); - const Module* M = F->getParent(); - for(Module::const_iterator ii = M->begin(); &*ii != F; ++ii) - ++fun; - for(Function::const_arg_iterator ii = F->arg_begin(); &*ii != Arg; ++ii) - ++offset; - } else if (const Instruction* I = dyn_cast(v)) { - assert(dyn_cast(I->getType())); - type = 3; - const BasicBlock* bb = I->getParent(); - const Function* F = bb->getParent(); - const Module* M = F->getParent(); - for(Module::const_iterator ii = M->begin(); &*ii != F; ++ii) - ++fun; - for(Function::const_iterator ii = F->begin(); &*ii != bb; ++ii) - offset += ii->size(); - for(BasicBlock::const_iterator ii = bb->begin(); &*ii != I; ++ii) - ++offset; - } else if (const Constant* C = dyn_cast(v)) { - //Don't know how to look these up yet - type = 0; - } else { - assert(0 && "Error in value marking"); - } - //type = 4: register spilling - //type = 5: global address loading or constant loading -} - static int getUID() { static int id = 0; @@ -535,97 +461,6 @@ } break; - case ISD::LOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: - case ISD::EXTLOAD: - { - SDOperand Chain = Op.getOperand(0); - SDOperand Address = Op.getOperand(1); - - unsigned Opc; - unsigned opcode = Op.getOpcode(); - - if (opcode == ISD::LOAD) - switch (Op.Val->getValueType(0)) { - default: Op.Val->dump(); assert(0 && "Bad load!"); - case MVT::i64: Opc = AlphaISD::LDQ_; break; - case MVT::f64: Opc = AlphaISD::LDT_; break; - case MVT::f32: Opc = AlphaISD::LDS_; break; - } - else - switch (cast(Op.getOperand(3))->getVT()) { - default: Op.Val->dump(); assert(0 && "Bad sign extend!"); - case MVT::i32: Opc = AlphaISD::LDL_; - assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; - case MVT::i16: Opc = AlphaISD::LDWU_; - assert(opcode != ISD::SEXTLOAD && "Not zext"); break; - case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise - case MVT::i8: Opc = AlphaISD::LDBU_; - assert(opcode != ISD::SEXTLOAD && "Not zext"); break; - } - - int i, j, k; - getValueInfo(dyn_cast(Op.getOperand(2))->getValue(), i, j, k); - - SDOperand Zero = DAG.getConstant(0, MVT::i64); - std::vector VTS; - VTS.push_back(Op.Val->getValueType(0)); - VTS.push_back(MVT::Other); - std::vector ARGS; - ARGS.push_back(Chain); - ARGS.push_back(Zero); - ARGS.push_back(Address); - ARGS.push_back(DAG.getConstant(i, MVT::i64)); - ARGS.push_back(DAG.getConstant(j, MVT::i64)); - ARGS.push_back(DAG.getConstant(k, MVT::i64)); - ARGS.push_back(DAG.getConstant(getUID(), MVT::i64)); - return DAG.getNode(Opc, VTS, ARGS); - } - - case ISD::TRUNCSTORE: - case ISD::STORE: - { - SDOperand Chain = Op.getOperand(0); - SDOperand Value = Op.getOperand(1); - SDOperand Address = Op.getOperand(2); - - unsigned Opc; - unsigned opcode = Op.getOpcode(); - - if (opcode == ISD::STORE) { - switch(Value.getValueType()) { - default: assert(0 && "unknown Type in store"); - case MVT::i64: Opc = AlphaISD::STQ_; break; - case MVT::f64: Opc = AlphaISD::STT_; break; - case MVT::f32: Opc = AlphaISD::STS_; break; - } - } else { //ISD::TRUNCSTORE - switch(cast(Op.getOperand(4))->getVT()) { - default: assert(0 && "unknown Type in store"); - case MVT::i8: Opc = AlphaISD::STB_; break; - case MVT::i16: Opc = AlphaISD::STW_; break; - case MVT::i32: Opc = AlphaISD::STL_; break; - } - } - - int i, j, k; - getValueInfo(cast(Op.getOperand(3))->getValue(), i, j, k); - - SDOperand Zero = DAG.getConstant(0, MVT::i64); - std::vector VTS; - VTS.push_back(MVT::Other); - std::vector ARGS; - ARGS.push_back(Chain); - ARGS.push_back(Value); - ARGS.push_back(Zero); - ARGS.push_back(Address); - ARGS.push_back(DAG.getConstant(i, MVT::i64)); - ARGS.push_back(DAG.getConstant(j, MVT::i64)); - ARGS.push_back(DAG.getConstant(k, MVT::i64)); - ARGS.push_back(DAG.getConstant(getUID(), MVT::i64)); - return DAG.getNode(Opc, VTS, ARGS); - } case ISD::VAARG: { SDOperand Chain = Op.getOperand(0); SDOperand VAListP = Op.getOperand(1); Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.113 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.114 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.113 Thu Feb 2 21:07:37 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Mar 9 08:58:25 2006 @@ -19,13 +19,6 @@ def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [ SDTCisFP<1>, SDTCisFP<0> ]>; -def SDTLoadA : SDTypeProfile<1, 6, [ // load - SDTCisInt<1>, SDTCisPtrTy<2>, SDTCisInt<3>, SDTCisInt<4>, SDTCisInt<5>, SDTCisInt<6> -]>; -def SDTStoreA : SDTypeProfile<0, 7, [ // load - SDTCisInt<1>, SDTCisPtrTy<2>, SDTCisInt<3>, SDTCisInt<4>, SDTCisInt<5>, SDTCisInt<6> -]>; - def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>; def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>; def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>; @@ -34,18 +27,6 @@ def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>; def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>; def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>; -def Alpha_ldq : SDNode<"AlphaISD::LDQ_", SDTLoadA, [SDNPHasChain]>; -def Alpha_ldt : SDNode<"AlphaISD::LDT_", SDTLoadA, [SDNPHasChain]>; -def Alpha_lds : SDNode<"AlphaISD::LDS_", SDTLoadA, [SDNPHasChain]>; -def Alpha_ldl : SDNode<"AlphaISD::LDL_", SDTLoadA, [SDNPHasChain]>; -def Alpha_ldwu : SDNode<"AlphaISD::LDWU_", SDTLoadA, [SDNPHasChain]>; -def Alpha_ldbu : SDNode<"AlphaISD::LDBU_", SDTLoadA, [SDNPHasChain]>; -def Alpha_stq : SDNode<"AlphaISD::STQ_", SDTStoreA, [SDNPHasChain]>; -def Alpha_stl : SDNode<"AlphaISD::STL_", SDTStoreA, [SDNPHasChain]>; -def Alpha_stw : SDNode<"AlphaISD::STW_", SDTStoreA, [SDNPHasChain]>; -def Alpha_stb : SDNode<"AlphaISD::STB_", SDTStoreA, [SDNPHasChain]>; -def Alpha_sts : SDNode<"AlphaISD::STS_", SDTStoreA, [SDNPHasChain]>; -def Alpha_stt : SDNode<"AlphaISD::STT_", SDTStoreA, [SDNPHasChain]>; // These are target-independent nodes, but have target-specific formats. def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>; @@ -569,38 +550,6 @@ (LDQl texternalsym:$ext, GPRC:$RB)>; -//Various tracked versions -let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB, - s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m) in { -def LDQlbl : MForm<0x29, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldq $RA,$DISP($RB)", - [(set GPRC:$RA, (Alpha_ldq imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; -def LDLlbl : MForm<0x28, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldl $RA,$DISP($RB)", - [(set GPRC:$RA, (Alpha_ldl imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; -def LDBUlbl : MForm<0x0A, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldbu $RA,$DISP($RB)", - [(set GPRC:$RA, (Alpha_ldwu imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; -def LDWUlbl : MForm<0x0C, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldwu $RA,$DISP($RB)", - [(set GPRC:$RA, (Alpha_ldbu imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; - -def STBlbl : MForm<0x0E, 1, 0, "LSMARKER$$$i$$$j$$$k$$$m:\n\t stb $RA,$DISP($RB)", - [(Alpha_stb GPRC:$RA, imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m)]>; -def STWlbl : MForm<0x0D, 1, 0, "LSMARKER$$$i$$$j$$$k$$$m:\n\t stw $RA,$DISP($RB)", - [(Alpha_stw GPRC:$RA, imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m)]>; -def STLlbl : MForm<0x2C, 1, 0, "LSMARKER$$$i$$$j$$$k$$$m:\n\t stl $RA,$DISP($RB)", - [(Alpha_stl GPRC:$RA, imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m)]>; -def STQlbl : MForm<0x2D, 1, 0, "LSMARKER$$$i$$$j$$$k$$$m:\n\t stq $RA,$DISP($RB)", - [(Alpha_stq GPRC:$RA, imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m)]>; -} - -let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB, - s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m) in -def LDTlbl : MForm<0x29, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldt $RA,$DISP($RB)", - [(set F8RC:$RA, (Alpha_ldt imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; - -let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB, - s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m) in -def LDSlbl : MForm<0x29, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t lds $RA,$DISP($RB)", - [(set F4RC:$RA, (Alpha_lds imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; - def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter //Basic Floating point ops @@ -621,9 +570,12 @@ def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC", [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>; -def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign +def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", + [(set F4RC:$RC, (fcopysign F4RC:$RA, F4RC:$RB))]>; def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent -def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate +//FIXME: This might be legalized in the oposite manner +def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", + [(set F4RC:$RC, (fneg (fcopysign F4RC:$RA, F4RC:$RB)))]>; } //Doubles @@ -642,9 +594,12 @@ def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC", [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>; -def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign +def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", + [(set F8RC:$RC, (fcopysign F8RC:$RA, F8RC:$RB))]>; def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent -def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate +//FIXME: This might be legalized in the oposite manner +def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", + [(set F8RC:$RC, (fneg (fcopysign F8RC:$RA, F8RC:$RB)))]>; def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>; // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>; @@ -895,6 +850,11 @@ (CPYSNT F8RC:$RB, F8RC:$RB)>; def : Pat<(fneg F4RC:$RB), (CPYSNS F4RC:$RB, F4RC:$RB)>; +def : Pat<(fcopysign (fneg F4RC:$A), F4RC:$B), + (CPYSNS F4RC:$A, F4RC:$B)>; +def : Pat<(fcopysign (fneg F8RC:$A), F8RC:$B), + (CPYSNT F8RC:$A, F8RC:$B)>; + //Yes, signed multiply high is ugly def : Pat<(mulhs GPRC:$RA, GPRC:$RB), (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA), From lattner at cs.uiuc.edu Thu Mar 9 11:11:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 11:11:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineDebugInfo.cpp DwarfWriter.cpp Message-ID: <200603091711.LAA04603@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineDebugInfo.cpp updated: 1.28 -> 1.29 DwarfWriter.cpp updated: 1.45 -> 1.46 --- Log message: temporary hack to get the build working again, apparently a header commit was forgotten --- Diffs of the changes: (+4 -4) DwarfWriter.cpp | 2 +- MachineDebugInfo.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.28 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.29 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.28 Thu Mar 9 07:28:47 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Thu Mar 9 11:11:08 2006 @@ -653,7 +653,7 @@ , Name("") , File(NULL) , Size(0) -, Align(0) +//, Align(0) , Offset(0) {} @@ -667,7 +667,7 @@ Visitor->Apply((DebugInfoDesc *&)File); Visitor->Apply(Line); Visitor->Apply(Size); - Visitor->Apply(Align); + //Visitor->Apply(Align); Visitor->Apply(Offset); } @@ -692,7 +692,7 @@ << "File(" << File << "), " << "Line(" << Line << "), " << "Size(" << Size << "), " - << "Align(" << Align << "), " + //<< "Align(" << Align << "), " << "Offset(" << Offset << ")\n"; } #endif Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.45 llvm/lib/CodeGen/DwarfWriter.cpp:1.46 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.45 Thu Mar 9 07:28:47 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Thu Mar 9 11:11:08 2006 @@ -1323,7 +1323,7 @@ unsigned Line = MemberDesc->getLine(); TypeDesc *MemTy = MemberDesc->getFromType(); uint64_t Size = MemberDesc->getSize(); - uint64_t Align = MemberDesc->getAlign(); + uint64_t Align = 0; //MemberDesc->getAlign(); uint64_t Offset = MemberDesc->getOffset(); // Construct member die. From alenhar2 at cs.uiuc.edu Thu Mar 9 11:16:57 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 11:16:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaSchedule.td Alpha.td AlphaISelLowering.h AlphaInstrFormats.td AlphaInstrInfo.td AlphaSubtarget.h Message-ID: <200603091716.LAA04692@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaSchedule.td added (r1.1) Alpha.td updated: 1.8 -> 1.9 AlphaISelLowering.h updated: 1.14 -> 1.15 AlphaInstrFormats.td updated: 1.26 -> 1.27 AlphaInstrInfo.td updated: 1.114 -> 1.115 AlphaSubtarget.h updated: 1.4 -> 1.5 --- Log message: Alpha Scheduling classes --- Diffs of the changes: (+333 -232) Alpha.td | 16 +- AlphaISelLowering.h | 3 AlphaInstrFormats.td | 77 +++++----- AlphaInstrInfo.td | 382 +++++++++++++++++++++++++-------------------------- AlphaSchedule.td | 84 +++++++++++ AlphaSubtarget.h | 3 6 files changed, 333 insertions(+), 232 deletions(-) Index: llvm/lib/Target/Alpha/AlphaSchedule.td diff -c /dev/null llvm/lib/Target/Alpha/AlphaSchedule.td:1.1 *** /dev/null Thu Mar 9 11:16:55 2006 --- llvm/lib/Target/Alpha/AlphaSchedule.td Thu Mar 9 11:16:45 2006 *************** *** 0 **** --- 1,84 ---- + //===- AlphaSchedule.td - Alpha Scheduling Definitions -----*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Andrew Lenharth and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + + //This is table 2-2 from the 21264 compiler writers guide + //modified some + + //Pipelines + + def L0 : FuncUnit; + def L1 : FuncUnit; + def FST0 : FuncUnit; + def FST1 : FuncUnit; + def U0 : FuncUnit; + def U1 : FuncUnit; + def FA : FuncUnit; + def FM : FuncUnit; + + def s_ild : InstrItinClass; + def s_fld : InstrItinClass; + def s_ist : InstrItinClass; + def s_fst : InstrItinClass; + def s_lda : InstrItinClass; + def s_rpcc : InstrItinClass; + def s_rx : InstrItinClass; + def s_mxpr : InstrItinClass; + def s_icbr : InstrItinClass; + def s_ubr : InstrItinClass; + def s_jsr : InstrItinClass; + def s_iadd : InstrItinClass; + def s_ilog : InstrItinClass; + def s_ishf : InstrItinClass; + def s_cmov : InstrItinClass; + def s_imul : InstrItinClass; + def s_imisc : InstrItinClass; + def s_fbr : InstrItinClass; + def s_fadd : InstrItinClass; + def s_fmul : InstrItinClass; + def s_fcmov : InstrItinClass; + def s_fdivt : InstrItinClass; + def s_fdivs : InstrItinClass; + def s_fsqrts: InstrItinClass; + def s_fsqrtt: InstrItinClass; + def s_ftoi : InstrItinClass; + def s_itof : InstrItinClass; + def s_pseudo : InstrItinClass; + + //Table 2?4 Instruction Class Latency in Cycles + //modified some + + def Alpha21264Itineraries : ProcessorItineraries<[ + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]> + ]>; Index: llvm/lib/Target/Alpha/Alpha.td diff -u llvm/lib/Target/Alpha/Alpha.td:1.8 llvm/lib/Target/Alpha/Alpha.td:1.9 --- llvm/lib/Target/Alpha/Alpha.td:1.8 Fri Jan 27 02:09:42 2006 +++ llvm/lib/Target/Alpha/Alpha.td Thu Mar 9 11:16:45 2006 @@ -32,6 +32,12 @@ include "AlphaRegisterInfo.td" //===----------------------------------------------------------------------===// +// Schedule Description +//===----------------------------------------------------------------------===// + +include "AlphaSchedule.td" + +//===----------------------------------------------------------------------===// // Instruction Descriptions //===----------------------------------------------------------------------===// @@ -47,11 +53,11 @@ // Alpha Processor Definitions //===----------------------------------------------------------------------===// -def : Processor<"generic", NoItineraries, []>; -def : Processor<"pca56" , NoItineraries, []>; -def : Processor<"ev56" , NoItineraries, []>; -def : Processor<"ev6" , NoItineraries, [FeatureFIX]>; -def : Processor<"ev67" , NoItineraries, [FeatureFIX, FeatureCIX]>; +def : Processor<"generic", Alpha21264Itineraries, []>; +def : Processor<"pca56" , Alpha21264Itineraries, []>; +def : Processor<"ev56" , Alpha21264Itineraries, []>; +def : Processor<"ev6" , Alpha21264Itineraries, [FeatureFIX]>; +def : Processor<"ev67" , Alpha21264Itineraries, [FeatureFIX, FeatureCIX]>; //===----------------------------------------------------------------------===// // The Alpha Target Index: llvm/lib/Target/Alpha/AlphaISelLowering.h diff -u llvm/lib/Target/Alpha/AlphaISelLowering.h:1.14 llvm/lib/Target/Alpha/AlphaISelLowering.h:1.15 --- llvm/lib/Target/Alpha/AlphaISelLowering.h:1.14 Fri Jan 27 21:14:31 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.h Thu Mar 9 11:16:45 2006 @@ -44,9 +44,6 @@ /// DIVCALL - used for special library calls for div and rem DivCall, - ///LD, ST - LDQ_, LDT_, LDS_, LDL_, LDWU_, LDBU_, - STQ_, STT_, STS_, STL_, STW_, STB_, }; } Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.26 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.27 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.26 Wed Feb 1 13:37:33 2006 +++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Thu Mar 9 11:16:45 2006 @@ -27,21 +27,18 @@ // Instruction format superclass //===----------------------------------------------------------------------===// // Alpha instruction baseline -class InstAlphaAlt op, string asmstr> : Instruction { +class InstAlpha op, string asmstr, InstrItinClass itin> : Instruction { field bits<32> Inst; let Namespace = "Alpha"; let AsmString = asmstr; let Inst{31-26} = op; + let Itinerary = itin; } -class InstAlpha op, dag OL, string asmstr> -: InstAlphaAlt { // Alpha instruction baseline - let OperandList = OL; -} //3.3.1 -class MForm opcode, bit store, bit load, string asmstr, list pattern> - : InstAlphaAlt { +class MForm opcode, bit store, bit load, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; let isStore = store; let isLoad = load; @@ -55,21 +52,24 @@ let Inst{20-16} = Rb; let Inst{15-0} = disp; } - -class MfcForm opcode, bits<16> fc, string asmstr> - : InstAlpha { +class MfcForm opcode, bits<16> fc, string asmstr, InstrItinClass itin> + : InstAlpha { bits<5> Ra; + let OperandList = (ops GPRC:$RA); let Inst{25-21} = Ra; let Inst{20-16} = 0; let Inst{15-0} = fc; } -class MbrForm opcode, bits<2> TB, dag OL, string asmstr> : InstAlpha { +class MbrForm opcode, bits<2> TB, dag OL, string asmstr, InstrItinClass itin> + : InstAlpha { bits<5> Ra; bits<5> Rb; bits<14> disp; + let OperandList = OL; + let Inst{25-21} = Ra; let Inst{20-16} = Rb; let Inst{15-14} = TB; @@ -79,10 +79,10 @@ //3.3.2 def target : Operand {} let isBranch = 1, isTerminator = 1 in -class BFormD opcode, string asmstr, list pattern> - : InstAlpha { +class BFormD opcode, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; - + let OperandList = (ops target:$DISP); bits<5> Ra; bits<21> disp; @@ -90,9 +90,10 @@ let Inst{20-0} = disp; } let isBranch = 1, isTerminator = 1 in -class BForm opcode, string asmstr, list pattern> - : InstAlpha { +class BForm opcode, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; + let OperandList = (ops GPRC:$RA, target:$DISP); bits<5> Ra; bits<21> disp; @@ -102,9 +103,10 @@ } let isBranch = 1, isTerminator = 1 in -class FBForm opcode, string asmstr, list pattern> - : InstAlpha { +class FBForm opcode, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; + let OperandList = (ops F8RC:$RA, target:$DISP); bits<5> Ra; bits<21> disp; @@ -114,9 +116,10 @@ } //3.3.3 -class OForm opcode, bits<7> fun, string asmstr, list pattern> - : InstAlpha { +class OForm opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; + let OperandList = (ops GPRC:$RC, GPRC:$RA, GPRC:$RB); bits<5> Rc; bits<5> Ra; @@ -131,9 +134,10 @@ let Inst{4-0} = Rc; } -class OForm2 opcode, bits<7> fun, string asmstr, list pattern> - : InstAlpha { +class OForm2 opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; + let OperandList = (ops GPRC:$RC, GPRC:$RB); bits<5> Rc; bits<5> Rb; @@ -147,9 +151,10 @@ let Inst{4-0} = Rc; } -class OForm4 opcode, bits<7> fun, string asmstr, list pattern> - : InstAlpha { +class OForm4 opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; + let OperandList = (ops GPRC:$RDEST, GPRC:$RFALSE, GPRC:$RTRUE, GPRC:$RCOND); bits<5> Rc; bits<5> Rb; @@ -166,9 +171,10 @@ } -class OFormL opcode, bits<7> fun, string asmstr, list pattern> - : InstAlpha { +class OFormL opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; + let OperandList = (ops GPRC:$RC, GPRC:$RA, u8imm:$L); bits<5> Rc; bits<5> Ra; @@ -182,10 +188,11 @@ let Inst{4-0} = Rc; } -class OForm4L opcode, bits<7> fun, string asmstr, list pattern> - : InstAlpha { +class OForm4L opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; - + let OperandList = (ops GPRC:$RDEST, GPRC:$RFALSE, s64imm:$RTRUE, GPRC:$RCOND); + bits<5> Rc; bits<8> LIT; bits<5> Ra; @@ -200,8 +207,8 @@ } //3.3.4 -class FPForm opcode, bits<11> fun, string asmstr, list pattern> - : InstAlphaAlt { +class FPForm opcode, bits<11> fun, string asmstr, list pattern, InstrItinClass itin> + : InstAlpha { let Pattern = pattern; bits<5> Fc; @@ -216,7 +223,9 @@ } //3.3.5 -class PALForm opcode, dag OL, string asmstr> : InstAlpha { +class PALForm opcode, dag OL, string asmstr, InstrItinClass itin> + : InstAlpha { + let OperandList = OL; bits<26> Function; let Inst{25-0} = Function; @@ -224,7 +233,9 @@ // Pseudo instructions. -class PseudoInstAlpha pattern> : InstAlpha<0, OL, nm> { +class PseudoInstAlpha pattern, InstrItinClass itin> + : InstAlpha<0, nm, itin> { + let OperandList = OL; let Pattern = pattern; } Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.114 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.115 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.114 Thu Mar 9 08:58:25 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Mar 9 11:16:45 2006 @@ -95,24 +95,24 @@ //Pseudo ops for selection def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA", - [(set GPRC:$RA, (undef))]>; + [(set GPRC:$RA, (undef))], s_pseudo>; def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA", - [(set F4RC:$RA, (undef))]>; + [(set F4RC:$RA, (undef))], s_pseudo>; def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA", - [(set F8RC:$RA, (undef))]>; + [(set F8RC:$RA, (undef))], s_pseudo>; -def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>; +def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", [], s_pseudo>; let isLoad = 1, hasCtrlDep = 1 in { def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt", - [(callseq_start imm:$amt)]>; + [(callseq_start imm:$amt)], s_pseudo>; def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt", - [(callseq_end imm:$amt)]>; + [(callseq_end imm:$amt)], s_pseudo>; } -def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", []>; -def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>; +def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>; +def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>; def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), - "LSMARKER$$$i$$$j$$$k$$$m:", []>; + "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>; //*********************** @@ -124,38 +124,38 @@ //conditional moves, int def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; + [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>; def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST", - [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>; //General pattern for cmov @@ -166,41 +166,41 @@ def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC", - [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))], s_iadd>; def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC", - [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))]>; + [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))], s_iadd>; def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC", - [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))], s_iadd>; def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC", - [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))], s_iadd>; def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC", - [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))], s_ilog>; def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC", - [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))], s_ilog>; def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC", - [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>; + [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))], s_ilog>; def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC", - [(set GPRC:$RC, (and GPRC:$RA, immUExt8inv:$L))]>; + [(set GPRC:$RC, (and GPRC:$RA, immUExt8inv:$L))], s_ilog>; def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC", - [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))], s_ilog>; def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC", - [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))], s_ilog>; def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC", - [(set GPRC:$RC, (ctlz GPRC:$RB))]>; + [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>; def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC", - [(set GPRC:$RC, (ctpop GPRC:$RB))]>; + [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>; def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC", - [(set GPRC:$RC, (cttz GPRC:$RB))]>; + [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>; def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC", - [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>; + [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))], s_ilog>; def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", - [(set GPRC:$RC, (xor GPRC:$RA, immUExt8inv:$L))]>; + [(set GPRC:$RC, (xor GPRC:$RA, immUExt8inv:$L))], s_ilog>; def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", - [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))]>; + [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>; def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", - [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))]>; + [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>; def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", - [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))]>; + [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>; //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high @@ -246,116 +246,116 @@ //def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC", - [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))], s_imul>; def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC", - [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))]>; + [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))], s_imul>; def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC", - [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))], s_imul>; def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC", - [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))], s_imul>; def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC", - [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>; + [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))], s_ilog>; def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", - [(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))]>; + [(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))], s_ilog>; def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC", - [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))], s_iadd>; def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC", - [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))]>; + [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))], s_iadd>; def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC", - [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))], s_iadd>; def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC", - [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))], s_iadd>; def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC", - [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))], s_iadd>; def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC", - [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))]>; + [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))], s_iadd>; def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC", - [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))], s_iadd>; def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC", - [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))], s_iadd>; def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC", - [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))], s_iadd>; def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC", - [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))]>; + [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))], s_iadd>; def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC", - [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))], s_iadd>; def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC", - [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))], s_iadd>; def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC", - [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))], s_iadd>; def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC", - [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8neg:$L)))]>; + [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8neg:$L)))], s_iadd>; def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC", - [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))], s_iadd>; def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC", - [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8neg:$L))]>; + [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8neg:$L))], s_iadd>; def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC", - [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))]>; + [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>; def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC", - [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))]>; + [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>; def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC", - [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))], s_ishf>; def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC", - [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))], s_ishf>; def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC", - [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))], s_ishf>; def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC", - [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))], s_ishf>; def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC", - [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))], s_ishf>; def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC", - [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))], s_ishf>; def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC", - [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))]>; + [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))], s_iadd>; def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC", - [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8neg:$L)))]>; + [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8neg:$L)))], s_iadd>; def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC", - [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))], s_iadd>; def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC", - [(set GPRC:$RC, (add GPRC:$RA, immUExt8neg:$L))]>; + [(set GPRC:$RC, (add GPRC:$RA, immUExt8neg:$L))], s_iadd>; def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC", - [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))], s_imul>; def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC", - [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))], s_imul>; def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC", - [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))], s_ilog>; def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC", - [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))], s_ilog>; //FIXME: what to do about zap? the cases it catches are very complex -def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", []>; //Zero bytes +def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", [], s_ishf>; //Zero bytes //ZAPi is useless give ZAPNOTi -def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", []>; //Zero bytes +def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", [], s_ishf>; //Zero bytes //FIXME: what to do about zapnot? see ZAP :) -def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", []>; //Zero bytes not +def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", [], s_ishf>; //Zero bytes not def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", - [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))]>; + [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))], s_ishf>; //Comparison, int //So this is a waste of what this instruction can do, but it still saves something def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC", - [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))]>; + [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>; def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC", - [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))]>; + [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>; def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC", - [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>; def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC", - [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>; def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC", - [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>; def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC", - [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>; def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC", - [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>; def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC", - [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>; def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC", - [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>; def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC", - [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>; def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC", - [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>; def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", - [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>; //Patterns for unsupported int comparisons def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>; @@ -381,16 +381,16 @@ let isReturn = 1, isTerminator = 1, noResults = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in - def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine + def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine -def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump +def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP", s_jsr>; //Jump let isCall = 1, noResults = 1, Ra = 26, Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, F0, F1, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in { - def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", []>; //Branch to subroutine + def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine } let isCall = 1, noResults = 1, Ra = 26, Rb = 27, disp = 0, Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, @@ -398,80 +398,80 @@ F0, F1, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in { - def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0">; //Jump to subroutine + def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine } let isCall = 1, noResults = 1, Ra = 23, Rb = 27, disp = 0, Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in - def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem + def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem -def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return +def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in { def LDQ : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)", - [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>; + [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>; def LDQr : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!gprellow", - [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>; + [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>; def LDL : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)", - [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))]>; + [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))], s_ild>; def LDLr : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)\t\t!gprellow", - [(set GPRC:$RA, (sextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32))]>; + [(set GPRC:$RA, (sextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32))], s_ild>; def LDBU : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)", - [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))]>; + [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))], s_ild>; def LDBUr : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow", - [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8))]>; + [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8))], s_ild>; def LDWU : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)", - [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))]>; + [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))], s_ild>; def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow", - [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16))]>; + [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16))], s_ild>; def STB : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)", - [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)]>; + [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)], s_ist>; def STBr : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow", - [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)]>; + [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)], s_ist>; def STW : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)", - [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)]>; + [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)], s_ist>; def STWr : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow", - [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)]>; + [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)], s_ist>; def STL : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)", - [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)]>; + [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)], s_ist>; def STLr : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow", - [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)]>; + [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)], s_ist>; def STQ : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)", - [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>; + [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>; def STQr : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow", - [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>; + [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>; //Load address def LDA : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)", - [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>; + [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>; def LDAr : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)\t\t!gprellow", - [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>; //Load address + [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address def LDAH : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)", - []>; //Load address high + [], s_lda>; //Load address high def LDAHr : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh", - [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))]>; //Load address high + [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high } let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in { def STS : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)", - [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>; + [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>; def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow", - [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>; + [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>; def LDS : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)", - [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>; + [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>; def LDSr : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)\t\t!gprellow", - [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>; + [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>; } let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in { def STT : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)", - [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))]>; + [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>; def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow", - [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))]>; + [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>; def LDT : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)", - [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))]>; + [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>; def LDTr : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)\t\t!gprellow", - [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))]>; + [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>; } @@ -538,19 +538,19 @@ //load address, rellocated gpdist form let OperandList = (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in { -def LDAg : MForm<0x08, 0, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", []>; //Load address -def LDAHg : MForm<0x09, 0, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", []>; //Load address +def LDAg : MForm<0x08, 0, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address +def LDAHg : MForm<0x09, 0, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address } //Load quad, rellocated literal form let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal", - [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))]>; + [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>; def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB), (LDQl texternalsym:$ext, GPRC:$RB)>; -def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter +def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter //Basic Floating point ops @@ -558,56 +558,56 @@ let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC", - [(set F4RC:$RC, (fsqrt F4RC:$RB))]>; + [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>; let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in { def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC", - [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))]>; + [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>; def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC", - [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))]>; + [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>; def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC", - [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))]>; + [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>; def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC", - [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>; + [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>; def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", - [(set F4RC:$RC, (fcopysign F4RC:$RA, F4RC:$RB))]>; -def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent + [(set F4RC:$RC, (fcopysign F4RC:$RA, F4RC:$RB))], s_fadd>; +def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent //FIXME: This might be legalized in the oposite manner def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", - [(set F4RC:$RC, (fneg (fcopysign F4RC:$RA, F4RC:$RB)))]>; + [(set F4RC:$RC, (fneg (fcopysign F4RC:$RA, F4RC:$RB)))], s_fadd>; } //Doubles let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC", - [(set F8RC:$RC, (fsqrt F8RC:$RB))]>; + [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>; let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in { def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC", - [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))]>; + [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>; def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC", - [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))]>; + [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>; def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC", - [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))]>; + [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>; def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC", - [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>; + [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>; def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", - [(set F8RC:$RC, (fcopysign F8RC:$RA, F8RC:$RB))]>; -def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent + [(set F8RC:$RC, (fcopysign F8RC:$RA, F8RC:$RB))], s_fadd>; +def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent //FIXME: This might be legalized in the oposite manner def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", - [(set F8RC:$RC, (fneg (fcopysign F8RC:$RA, F8RC:$RB)))]>; + [(set F8RC:$RC, (fneg (fcopysign F8RC:$RA, F8RC:$RB)))], s_fadd>; -def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>; +def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>; // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>; -def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", []>; +def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>; // [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>; -def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", []>; +def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>; // [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>; -def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>; +def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>; // [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>; } //TODO: Add lots more FP patterns @@ -615,22 +615,22 @@ //conditional moves, floats let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND), isTwoAddress = 1 in { -def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if = zero -def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if >= zero -def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if > zero -def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if <= zero -def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[]>; // FCMOVE if < zero -def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[]>; //FCMOVE if != zero +def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero +def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero +def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero +def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero +def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero +def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero } //conditional moves, doubles let OperandList = (ops F8RC:$RDEST, F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND), isTwoAddress = 1 in { -def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", []>; -def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", []>; -def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", []>; -def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", []>; -def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", []>; -def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", []>; +def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>; +def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>; +def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>; +def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>; +def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>; +def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>; } //misc FP selects @@ -664,32 +664,32 @@ let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in -def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating +def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC", - [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))]>; //Floating to integer move + [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))], s_ftoi>; //Floating to integer move let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in -def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating +def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC", - [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))]>; //Integer to floating move + [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))], s_itof>; //Integer to floating move let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC", - [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))]>; + [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>; let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC", - [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))]>; + [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>; let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC", - [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))]>; + [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>; let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC", - [(set F8RC:$RC, (fextend F4RC:$RB))]>; + [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>; let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", - [(set F4RC:$RC, (fround F8RC:$RB))]>; + [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>; ///////////////////////////////////////////////////////// @@ -697,38 +697,38 @@ ///////////////////////////////////////////////////////// let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in { let Ra = 31 in -def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)]>; +def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>; //Branches, int def BEQ : BForm<0x39, "beq $RA,$DISP", - [(brcond (seteq GPRC:$RA, 0), bb:$DISP)]>; + [(brcond (seteq GPRC:$RA, 0), bb:$DISP)], s_icbr>; def BGE : BForm<0x3E, "bge $RA,$DISP", - [(brcond (setge GPRC:$RA, 0), bb:$DISP)]>; + [(brcond (setge GPRC:$RA, 0), bb:$DISP)], s_icbr>; def BGT : BForm<0x3F, "bgt $RA,$DISP", - [(brcond (setgt GPRC:$RA, 0), bb:$DISP)]>; -def BLBC : BForm<0x38, "blbc $RA,$DISP", []>; //TODO: Low bit clear + [(brcond (setgt GPRC:$RA, 0), bb:$DISP)], s_icbr>; +def BLBC : BForm<0x38, "blbc $RA,$DISP", [], s_icbr>; //TODO: Low bit clear def BLBS : BForm<0x3C, "blbs $RA,$DISP", - [(brcond (and GPRC:$RA, 1), bb:$DISP)]>; + [(brcond (and GPRC:$RA, 1), bb:$DISP)], s_icbr>; def BLE : BForm<0x3B, "ble $RA,$DISP", - [(brcond (setle GPRC:$RA, 0), bb:$DISP)]>; + [(brcond (setle GPRC:$RA, 0), bb:$DISP)], s_icbr>; def BLT : BForm<0x3A, "blt $RA,$DISP", - [(brcond (setlt GPRC:$RA, 0), bb:$DISP)]>; + [(brcond (setlt GPRC:$RA, 0), bb:$DISP)], s_icbr>; def BNE : BForm<0x3D, "bne $RA,$DISP", - [(brcond (setne GPRC:$RA, 0), bb:$DISP)]>; + [(brcond (setne GPRC:$RA, 0), bb:$DISP)], s_icbr>; //Branches, float def FBEQ : FBForm<0x31, "fbeq $RA,$DISP", - [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)]>; + [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>; def FBGE : FBForm<0x36, "fbge $RA,$DISP", - [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)]>; + [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>; def FBGT : FBForm<0x37, "fbgt $RA,$DISP", - [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)]>; + [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>; def FBLE : FBForm<0x33, "fble $RA,$DISP", - [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)]>; + [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>; def FBLT : FBForm<0x32, "fblt $RA,$DISP", - [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)]>; + [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>; def FBNE : FBForm<0x35, "fbne $RA,$DISP", - [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)]>; + [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>; } def : Pat<(brcond GPRC:$RA, bb:$DISP), (BNE GPRC:$RA, bb:$DISP)>; Index: llvm/lib/Target/Alpha/AlphaSubtarget.h diff -u llvm/lib/Target/Alpha/AlphaSubtarget.h:1.4 llvm/lib/Target/Alpha/AlphaSubtarget.h:1.5 --- llvm/lib/Target/Alpha/AlphaSubtarget.h:1.4 Wed Oct 26 13:07:50 2005 +++ llvm/lib/Target/Alpha/AlphaSubtarget.h Thu Mar 9 11:16:45 2006 @@ -14,6 +14,7 @@ #ifndef ALPHASUBTARGET_H #define ALPHASUBTARGET_H +#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetSubtarget.h" #include @@ -28,6 +29,8 @@ bool HasF2I; bool HasCT; + InstrItineraryData InstrItins; + public: /// This constructor initializes the data members to match that /// of the specified module. From alenhar2 at cs.uiuc.edu Thu Mar 9 11:29:27 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 11:29:27 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200603091729.LAA04850@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.197 -> 1.198 --- Log message: change alpha beta --- Diffs of the changes: (+0 -0) 0 files changed From jlaskey at apple.com Thu Mar 9 11:31:05 2006 From: jlaskey at apple.com (Jim Laskey) Date: Thu, 9 Mar 2006 11:31:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603091731.LAA04889@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.28 -> 1.29 --- Log message: Forgot this on last check in. --- Diffs of the changes: (+3 -0) MachineDebugInfo.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.28 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.29 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.28 Tue Mar 7 14:53:47 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Thu Mar 9 11:30:53 2006 @@ -277,6 +277,7 @@ CompileUnitDesc *File; // Declared compile unit (may be NULL.) int Line; // Declared line# (may be zero.) uint64_t Size; // Type bit size (may be zero.) + uint64_t Align; // Type bit alignment (may be zero.) uint64_t Offset; // Type bit offset (may be zero.) public: @@ -288,12 +289,14 @@ CompileUnitDesc *getFile() const { return File; } int getLine() const { return Line; } uint64_t getSize() const { return Size; } + uint64_t getAlign() const { return Align; } uint64_t getOffset() const { return Offset; } void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } void setFile(CompileUnitDesc *U) { File = U; } void setLine(int L) { Line = L; } void setSize(uint64_t S) { Size = S; } + void setAlign(uint64_t A) { Align = A; } void setOffset(uint64_t O) { Offset = O; } /// ApplyToFields - Target the visitor to the fields of the TypeDesc. From lattner at cs.uiuc.edu Thu Mar 9 11:31:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 11:31:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603091731.LAA04931@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.31 -> 1.32 --- Log message: remove temporary option --- Diffs of the changes: (+1 -3) ScheduleDAGList.cpp | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.31 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.32 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.31 Thu Mar 9 01:39:25 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 11:31:22 2006 @@ -33,8 +33,6 @@ using namespace llvm; namespace { - // FIXME: UseLatencies is temporary. - cl::opt UseLatencies("use-sched-latencies"); Statistic<> NumNoops ("scheduler", "Number of noops inserted"); Statistic<> NumStalls("scheduler", "Number of pipeline stalls"); @@ -508,7 +506,7 @@ // Compute the latency for the node. We use the sum of the latencies for // all nodes flagged together into this SUnit. - if (InstrItins.isEmpty() || !UseLatencies) { + if (InstrItins.isEmpty()) { // No latency information. SU->Latency = 1; } else { From alenhar2 at cs.uiuc.edu Thu Mar 9 11:42:02 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 11:42:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200603091742.LAA05044@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.115 -> 1.116 --- Log message: alpha and llvm have different oppinions on which arg is the sign bit --- Diffs of the changes: (+8 -10) AlphaInstrInfo.td | 18 ++++++++---------- 1 files changed, 8 insertions(+), 10 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.115 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.116 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.115 Thu Mar 9 11:16:45 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Mar 9 11:41:50 2006 @@ -571,11 +571,10 @@ [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>; def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", - [(set F4RC:$RC, (fcopysign F4RC:$RA, F4RC:$RB))], s_fadd>; + [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>; def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent -//FIXME: This might be legalized in the oposite manner def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", - [(set F4RC:$RC, (fneg (fcopysign F4RC:$RA, F4RC:$RB)))], s_fadd>; + [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>; } //Doubles @@ -595,11 +594,10 @@ [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>; def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", - [(set F8RC:$RC, (fcopysign F8RC:$RA, F8RC:$RB))], s_fadd>; + [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>; def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent -//FIXME: This might be legalized in the oposite manner def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", - [(set F8RC:$RC, (fneg (fcopysign F8RC:$RA, F8RC:$RB)))], s_fadd>; + [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>; def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>; // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>; @@ -850,10 +848,10 @@ (CPYSNT F8RC:$RB, F8RC:$RB)>; def : Pat<(fneg F4RC:$RB), (CPYSNS F4RC:$RB, F4RC:$RB)>; -def : Pat<(fcopysign (fneg F4RC:$A), F4RC:$B), - (CPYSNS F4RC:$A, F4RC:$B)>; -def : Pat<(fcopysign (fneg F8RC:$A), F8RC:$B), - (CPYSNT F8RC:$A, F8RC:$B)>; +def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)), + (CPYSNS F4RC:$B, F4RC:$A)>; +def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)), + (CPYSNT F8RC:$B, F8RC:$A)>; //Yes, signed multiply high is ugly def : Pat<(mulhs GPRC:$RA, GPRC:$RB), From lattner at cs.uiuc.edu Thu Mar 9 11:45:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 11:45:14 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200603091745.LAA05142@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.198 -> 1.199 --- Log message: Switch PPC beta back to list-td --- Diffs of the changes: (+2 -2) Makefile.programs | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.198 llvm-test/Makefile.programs:1.199 --- llvm-test/Makefile.programs:1.198 Thu Mar 9 11:29:17 2006 +++ llvm-test/Makefile.programs Thu Mar 9 11:45:02 2006 @@ -187,10 +187,10 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -use-sched-latencies +LLCBETAOPTION := -sched=list-td endif ifeq ($(ARCH),Alpha) -LLCBETAOPTION := -sched=list-td -use-sched-latencies +LLCBETAOPTION := -sched=list-td # -enable-alpha-FTOI -enable-alpha-intfpdiv endif ifeq ($(ARCH),IA64) From alenhar2 at cs.uiuc.edu Thu Mar 9 11:47:34 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 11:47:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200603091747.LAA05179@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.50 -> 1.51 --- Log message: relax fcopysign --- Diffs of the changes: (+4 -1) TargetSelectionDAG.td | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.50 llvm/lib/Target/TargetSelectionDAG.td:1.51 --- llvm/lib/Target/TargetSelectionDAG.td:1.50 Thu Mar 9 08:57:36 2006 +++ llvm/lib/Target/TargetSelectionDAG.td Thu Mar 9 11:47:22 2006 @@ -83,6 +83,9 @@ def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> ]>; +def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. + SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> +]>; def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> ]>; @@ -262,7 +265,7 @@ def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; -def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPBinOp>; +def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; From lattner at cs.uiuc.edu Thu Mar 9 11:48:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 11:48:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineDebugInfo.cpp DwarfWriter.cpp Message-ID: <200603091748.LAA05250@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineDebugInfo.cpp updated: 1.29 -> 1.30 DwarfWriter.cpp updated: 1.46 -> 1.47 --- Log message: back out my previous hack --- Diffs of the changes: (+4 -4) DwarfWriter.cpp | 2 +- MachineDebugInfo.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.29 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.30 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.29 Thu Mar 9 11:11:08 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Thu Mar 9 11:48:46 2006 @@ -653,7 +653,7 @@ , Name("") , File(NULL) , Size(0) -//, Align(0) +, Align(0) , Offset(0) {} @@ -667,7 +667,7 @@ Visitor->Apply((DebugInfoDesc *&)File); Visitor->Apply(Line); Visitor->Apply(Size); - //Visitor->Apply(Align); + Visitor->Apply(Align); Visitor->Apply(Offset); } @@ -692,7 +692,7 @@ << "File(" << File << "), " << "Line(" << Line << "), " << "Size(" << Size << "), " - //<< "Align(" << Align << "), " + << "Align(" << Align << "), " << "Offset(" << Offset << ")\n"; } #endif Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.46 llvm/lib/CodeGen/DwarfWriter.cpp:1.47 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.46 Thu Mar 9 11:11:08 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Thu Mar 9 11:48:46 2006 @@ -1323,7 +1323,7 @@ unsigned Line = MemberDesc->getLine(); TypeDesc *MemTy = MemberDesc->getFromType(); uint64_t Size = MemberDesc->getSize(); - uint64_t Align = 0; //MemberDesc->getAlign(); + uint64_t Align = MemberDesc->getAlign(); uint64_t Offset = MemberDesc->getOffset(); // Construct member die. From alenhar2 at cs.uiuc.edu Thu Mar 9 11:56:45 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 11:56:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200603091756.LAA05290@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.116 -> 1.117 --- Log message: fcopysign for mixed mode --- Diffs of the changes: (+20 -1) AlphaInstrInfo.td | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.116 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.117 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.116 Thu Mar 9 11:41:50 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Mar 9 11:56:33 2006 @@ -608,7 +608,21 @@ def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>; // [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>; } -//TODO: Add lots more FP patterns + +//More CPYS forms: +let OperandList = (ops F8RC:$RC, F4RC:$RA, F8RC:$RB) in { +def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", + [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>; +def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", + [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>; +} +let OperandList = (ops F4RC:$RC, F8RC:$RA, F4RC:$RB) in { +def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC", + [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>; +def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent +def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC", + [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>; +} //conditional moves, floats let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND), @@ -848,10 +862,15 @@ (CPYSNT F8RC:$RB, F8RC:$RB)>; def : Pat<(fneg F4RC:$RB), (CPYSNS F4RC:$RB, F4RC:$RB)>; + def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)), (CPYSNS F4RC:$B, F4RC:$A)>; def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)), (CPYSNT F8RC:$B, F8RC:$A)>; +def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)), + (CPYSNSt F8RC:$B, F4RC:$A)>; +def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)), + (CPYSNTs F4RC:$B, F8RC:$A)>; //Yes, signed multiply high is ugly def : Pat<(mulhs GPRC:$RA, GPRC:$RB), From lattner at cs.uiuc.edu Thu Mar 9 12:08:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 12:08:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Message-ID: <200603091808.MAA05468@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaRegisterInfo.cpp updated: 1.35 -> 1.36 --- Log message: remove some now-dead code --- Diffs of the changes: (+0 -16) AlphaRegisterInfo.cpp | 16 ---------------- 1 files changed, 16 deletions(-) Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.35 llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.36 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.35 Thu Feb 2 14:12:32 2006 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Thu Mar 9 12:07:49 2006 @@ -31,10 +31,6 @@ #include using namespace llvm; -namespace llvm { - extern cl::opt EnableAlphaLSMark; -} - //These describe LDAx static const int IMM_LOW = -32768; static const int IMM_HIGH = 32767; @@ -72,9 +68,6 @@ const TargetRegisterClass *RC) const { //std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n"; //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); - if (EnableAlphaLSMark) - BuildMI(MBB, MI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(1) - .addImm(getUID()); if (RC == Alpha::F4RCRegisterClass) BuildMI(MBB, MI, Alpha::STS, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); else if (RC == Alpha::F8RCRegisterClass) @@ -91,9 +84,6 @@ unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC) const { //std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n"; - if (EnableAlphaLSMark) - BuildMI(MBB, MI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(2) - .addImm(getUID()); if (RC == Alpha::F4RCRegisterClass) BuildMI(MBB, MI, Alpha::LDS, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); else if (RC == Alpha::F8RCRegisterClass) @@ -317,9 +307,6 @@ //now if we need to, save the old FP and set the new if (FP) { - if (EnableAlphaLSMark) - BuildMI(MBB, MBBI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(1) - .addImm(getUID()); BuildMI(MBB, MBBI, Alpha::STQ, 3).addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); //this must be the last instr in the prolog BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R15).addReg(Alpha::R30).addReg(Alpha::R30); @@ -346,9 +333,6 @@ BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R30).addReg(Alpha::R15) .addReg(Alpha::R15); //restore the FP - if (EnableAlphaLSMark) - BuildMI(MBB, MBBI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(2) - .addImm(getUID()); BuildMI(MBB, MBBI, Alpha::LDQ, 2, Alpha::R15).addImm(0).addReg(Alpha::R15); } From alenhar2 at cs.uiuc.edu Thu Mar 9 12:19:03 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 9 Mar 2006 12:19:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Message-ID: <200603091819.MAA05526@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.cpp updated: 1.8 -> 1.9 --- Log message: these are copies too --- Diffs of the changes: (+5 -1) AlphaInstrInfo.cpp | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.8 llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.9 --- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.8 Thu Feb 2 21:07:37 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Thu Mar 9 12:18:51 2006 @@ -26,7 +26,11 @@ unsigned& sourceReg, unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); - if (oc == Alpha::BIS || oc == Alpha::CPYSS || oc == Alpha::CPYST) { + if (oc == Alpha::BIS || + oc == Alpha::CPYSS || + oc == Alpha::CPYST || + oc == Alpha::CPYSSt || + oc == Alpha::CPYSTs) { // or r1, r2, r2 // cpys(s|t) r1 r2 r2 assert(MI.getNumOperands() == 3 && From lattner at cs.uiuc.edu Thu Mar 9 12:42:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 12:42:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AutoUpgrade.cpp Message-ID: <200603091842.MAA05698@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AutoUpgrade.cpp updated: 1.10 -> 1.11 --- Log message: autoupgrade memcpy/memmove/memset with signed counts. CVS: ---------------------------------------------------------------------- --- Diffs of the changes: (+12 -4) AutoUpgrade.cpp | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) Index: llvm/lib/VMCore/AutoUpgrade.cpp diff -u llvm/lib/VMCore/AutoUpgrade.cpp:1.10 llvm/lib/VMCore/AutoUpgrade.cpp:1.11 --- llvm/lib/VMCore/AutoUpgrade.cpp:1.10 Fri Mar 3 10:31:22 2006 +++ llvm/lib/VMCore/AutoUpgrade.cpp Thu Mar 9 12:42:10 2006 @@ -84,10 +84,18 @@ case 'm': if (Name == "llvm.memcpy" || Name == "llvm.memset" || Name == "llvm.memmove") { - if (F->getFunctionType()->getParamType(2) == Type::UIntTy) - return M->getOrInsertFunction(Name+".i32", F->getFunctionType()); - if (F->getFunctionType()->getParamType(2) == Type::ULongTy) - return M->getOrInsertFunction(Name+".i64", F->getFunctionType()); + if (F->getFunctionType()->getParamType(2) == Type::UIntTy || + F->getFunctionType()->getParamType(2) == Type::IntTy) + return M->getOrInsertFunction(Name+".i32", Type::VoidTy, + PointerType::get(Type::SByteTy), + F->getFunctionType()->getParamType(1), + Type::UIntTy, Type::UIntTy, NULL); + if (F->getFunctionType()->getParamType(2) == Type::ULongTy || + F->getFunctionType()->getParamType(2) == Type::LongTy) + return M->getOrInsertFunction(Name+".i64", Type::VoidTy, + PointerType::get(Type::SByteTy), + F->getFunctionType()->getParamType(1), + Type::ULongTy, Type::UIntTy, NULL); } break; case 's': From lattner at cs.uiuc.edu Thu Mar 9 12:43:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 12:43:18 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyLibCalls/MemCpy.ll MemMove.ll Message-ID: <200603091843.MAA05739@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyLibCalls: MemCpy.ll updated: 1.1 -> 1.2 MemMove.ll updated: 1.1 -> 1.2 --- Log message: Update these tests (which use autoupgrade) to run constprop and check that the file parses. --- Diffs of the changes: (+4 -2) MemCpy.ll | 3 ++- MemMove.ll | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/test/Regression/Transforms/SimplifyLibCalls/MemCpy.ll diff -u llvm/test/Regression/Transforms/SimplifyLibCalls/MemCpy.ll:1.1 llvm/test/Regression/Transforms/SimplifyLibCalls/MemCpy.ll:1.2 --- llvm/test/Regression/Transforms/SimplifyLibCalls/MemCpy.ll:1.1 Tue Apr 26 02:40:40 2005 +++ llvm/test/Regression/Transforms/SimplifyLibCalls/MemCpy.ll Thu Mar 9 12:43:07 2006 @@ -1,5 +1,6 @@ ; Test that the StrCatOptimizer works correctly -; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | not grep 'call.*llvm.memcpy' +; RUN: llvm-as < %s | opt -constprop -simplify-libcalls -disable-output && +; RUN: llvm-as < %s | opt -constprop -simplify-libcalls | llvm-dis | not grep 'call.*llvm.memcpy' declare sbyte* %llvm.memcpy(sbyte*,sbyte*,int,int) %h = constant [2 x sbyte] c"h\00" Index: llvm/test/Regression/Transforms/SimplifyLibCalls/MemMove.ll diff -u llvm/test/Regression/Transforms/SimplifyLibCalls/MemMove.ll:1.1 llvm/test/Regression/Transforms/SimplifyLibCalls/MemMove.ll:1.2 --- llvm/test/Regression/Transforms/SimplifyLibCalls/MemMove.ll:1.1 Tue Apr 26 14:05:51 2005 +++ llvm/test/Regression/Transforms/SimplifyLibCalls/MemMove.ll Thu Mar 9 12:43:07 2006 @@ -1,5 +1,6 @@ ; Test that the StrCatOptimizer works correctly -; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | not grep 'call.*llvm.memmove' +; RUN: llvm-as < %s | opt -constprop -simplify-libcalls -disable-output && +; RUN: llvm-as < %s | opt -constprop -simplify-libcalls | llvm-dis | not grep 'call.*llvm.memmove' declare sbyte* %llvm.memmove(sbyte*,sbyte*,int,int) %h = constant [2 x sbyte] c"h\00" From evan.cheng at apple.com Thu Mar 9 13:04:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 9 Mar 2006 13:04:42 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/store_op_load_fold2.ll store_op_load_fold.ll Message-ID: <200603091904.NAA06083@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: store_op_load_fold2.ll added (r1.1) store_op_load_fold.ll updated: 1.1 -> 1.2 --- Log message: Add a test case for (store (op (load ..) ..) ..) folding. --- Diffs of the changes: (+45 -2) store_op_load_fold.ll | 2 -- store_op_load_fold2.ll | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) Index: llvm/test/Regression/CodeGen/X86/store_op_load_fold2.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/store_op_load_fold2.ll:1.1 *** /dev/null Thu Mar 9 13:04:40 2006 --- llvm/test/Regression/CodeGen/X86/store_op_load_fold2.ll Thu Mar 9 13:04:30 2006 *************** *** 0 **** --- 1,45 ---- + ; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel | grep 'and DWORD PTR' | wc -l | grep 1 + ; + ; FIXME: The number of (store (and (load ..) ..) ..) really should be 2. But the current hack + ; only allow one of the folding to happen. + + %struct.Macroblock = type { int, int, int, int, int, [8 x int], %struct.Macroblock*, %struct.Macroblock*, int, [2 x [4 x [4 x [2 x int]]]], [16 x sbyte], [16 x sbyte], int, long, [4 x int], [4 x int], long, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, short, double, int, int, int, int, int, int, int, int, int } + + implementation ; Functions: + + internal fastcc int %dct_chroma(int %uv, int %cr_cbp) { + entry: + br bool false, label %bb2611, label %cond_true129 + + cond_true129: ; preds = %entry + ret int 0 + + bb2611: ; preds = %entry + br bool false, label %cond_true2732.preheader, label %cond_next2752 + + cond_true2732.preheader: ; preds = %bb2611 + %tmp2666 = getelementptr %struct.Macroblock* null, int 0, uint 13 ; [#uses=2] + %tmp2674 = cast int 0 to ubyte ; [#uses=1] + br bool false, label %cond_true2732.preheader.split.us, label %cond_true2732.preheader.split + + cond_true2732.preheader.split.us: ; preds = %cond_true2732.preheader + br bool false, label %cond_true2732.outer.us.us, label %cond_true2732.outer.us + + cond_true2732.outer.us.us: ; preds = %cond_true2732.preheader.split.us + %tmp2667.us.us = load long* %tmp2666 ; [#uses=1] + %tmp2670.us.us = load long* null ; [#uses=1] + %tmp2675.us.us = shl long %tmp2670.us.us, ubyte %tmp2674 ; [#uses=1] + %tmp2675not.us.us = xor long %tmp2675.us.us, -1 ; [#uses=1] + %tmp2676.us.us = and long %tmp2667.us.us, %tmp2675not.us.us ; [#uses=1] + store long %tmp2676.us.us, long* %tmp2666 + ret int 0 + + cond_true2732.outer.us: ; preds = %cond_true2732.preheader.split.us + ret int 0 + + cond_true2732.preheader.split: ; preds = %cond_true2732.preheader + ret int 0 + + cond_next2752: ; preds = %bb2611 + ret int 0 + } Index: llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll diff -u llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.1 llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.2 --- llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.1 Fri Feb 3 00:46:41 2006 +++ llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll Thu Mar 9 13:04:30 2006 @@ -2,8 +2,6 @@ ; ; Test the add and load are folded into the store instruction. -target triple = "i686-pc-linux-gnu" - %X = weak global short 0 void %foo() { From lattner at cs.uiuc.edu Thu Mar 9 13:53:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 13:53:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Makefile Message-ID: <200603091953.NAA06590@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Makefile updated: 1.7 -> 1.8 --- Log message: Build intrinsics.gen from intrinsics.td --- Diffs of the changes: (+6 -0) Makefile | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/VMCore/Makefile diff -u llvm/lib/VMCore/Makefile:1.7 llvm/lib/VMCore/Makefile:1.8 --- llvm/lib/VMCore/Makefile:1.7 Sun Aug 14 10:14:34 2005 +++ llvm/lib/VMCore/Makefile Thu Mar 9 13:53:27 2006 @@ -9,6 +9,8 @@ LEVEL = ../.. LIBRARYNAME = LLVMCore +BUILT_SOURCES = $(LEVEL)/include/llvm/intrinsics.gen + include $(LEVEL)/Makefile.config ifeq ($(ARCH),Alpha) BUILD_ARCHIVE = 1 @@ -16,3 +18,7 @@ include $(LEVEL)/Makefile.common +$(LEVEL)/include/llvm/intrinsics.gen: $(LEVEL)/include/llvm/intrinsics.td + @echo Building intrinsics.gen from intrinsics.td + $(Verb) $(TableGen) $< -o $@ -gen-intrinsic + From lattner at cs.uiuc.edu Thu Mar 9 13:55:19 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 13:55:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Makefile Message-ID: <200603091955.NAA06637@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Makefile updated: 1.8 -> 1.9 --- Log message: silly case insensitive file systems... --- Diffs of the changes: (+3 -3) Makefile | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/VMCore/Makefile diff -u llvm/lib/VMCore/Makefile:1.8 llvm/lib/VMCore/Makefile:1.9 --- llvm/lib/VMCore/Makefile:1.8 Thu Mar 9 13:53:27 2006 +++ llvm/lib/VMCore/Makefile Thu Mar 9 13:55:06 2006 @@ -9,7 +9,7 @@ LEVEL = ../.. LIBRARYNAME = LLVMCore -BUILT_SOURCES = $(LEVEL)/include/llvm/intrinsics.gen +BUILT_SOURCES = $(LEVEL)/include/llvm/Intrinsics.gen include $(LEVEL)/Makefile.config ifeq ($(ARCH),Alpha) @@ -18,7 +18,7 @@ include $(LEVEL)/Makefile.common -$(LEVEL)/include/llvm/intrinsics.gen: $(LEVEL)/include/llvm/intrinsics.td - @echo Building intrinsics.gen from intrinsics.td +$(LEVEL)/include/llvm/Intrinsics.gen: $(LEVEL)/include/llvm/Intrinsics.td + @echo Building Intrinsics.gen from Intrinsics.td $(Verb) $(TableGen) $< -o $@ -gen-intrinsic From lattner at cs.uiuc.edu Thu Mar 9 14:01:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:01:32 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicInst.h Message-ID: <200603092001.OAA06768@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicInst.h updated: 1.10 -> 1.11 --- Log message: remove dbg_declare, it's not used yet. --- Diffs of the changes: (+0 -1) IntrinsicInst.h | 1 - 1 files changed, 1 deletion(-) Index: llvm/include/llvm/IntrinsicInst.h diff -u llvm/include/llvm/IntrinsicInst.h:1.10 llvm/include/llvm/IntrinsicInst.h:1.11 --- llvm/include/llvm/IntrinsicInst.h:1.10 Thu Mar 2 17:57:16 2006 +++ llvm/include/llvm/IntrinsicInst.h Thu Mar 9 14:01:20 2006 @@ -76,7 +76,6 @@ case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_end: case Intrinsic::dbg_func_start: - case Intrinsic::dbg_declare: return true; default: return false; } From lattner at cs.uiuc.edu Thu Mar 9 14:02:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:02:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200603092002.OAA06805@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.102 -> 1.103 Verifier.cpp updated: 1.148 -> 1.149 --- Log message: remove dbg_declare, it's not used yet. --- Diffs of the changes: (+0 -2) Function.cpp | 1 - Verifier.cpp | 1 - 2 files changed, 2 deletions(-) Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.102 llvm/lib/VMCore/Function.cpp:1.103 --- llvm/lib/VMCore/Function.cpp:1.102 Thu Mar 2 18:19:44 2006 +++ llvm/lib/VMCore/Function.cpp Thu Mar 9 14:01:50 2006 @@ -232,7 +232,6 @@ if (Name == "llvm.dbg.region.start")return Intrinsic::dbg_region_start; if (Name == "llvm.dbg.region.end") return Intrinsic::dbg_region_end; if (Name == "llvm.dbg.func.start") return Intrinsic::dbg_func_start; - if (Name == "llvm.dbg.declare") return Intrinsic::dbg_declare; break; case 'f': if (Name == "llvm.frameaddress") return Intrinsic::frameaddress; Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.148 llvm/lib/VMCore/Verifier.cpp:1.149 --- llvm/lib/VMCore/Verifier.cpp:1.148 Thu Mar 2 18:19:44 2006 +++ llvm/lib/VMCore/Verifier.cpp Thu Mar 9 14:01:50 2006 @@ -909,7 +909,6 @@ case Intrinsic::dbg_region_start:NumArgs = 1; break; case Intrinsic::dbg_region_end: NumArgs = 1; break; case Intrinsic::dbg_func_start: NumArgs = 1; break; - case Intrinsic::dbg_declare: NumArgs = 1; break; case Intrinsic::memcpy_i32: NumArgs = 4; break; case Intrinsic::memcpy_i64: NumArgs = 4; break; From lattner at cs.uiuc.edu Thu Mar 9 14:02:56 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:02:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IntrinsicLowering.cpp Message-ID: <200603092002.OAA06878@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IntrinsicLowering.cpp updated: 1.40 -> 1.41 --- Log message: remove dbg_declare, it's not used yet. --- Diffs of the changes: (+0 -1) IntrinsicLowering.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/IntrinsicLowering.cpp diff -u llvm/lib/CodeGen/IntrinsicLowering.cpp:1.40 llvm/lib/CodeGen/IntrinsicLowering.cpp:1.41 --- llvm/lib/CodeGen/IntrinsicLowering.cpp:1.40 Thu Mar 2 18:00:25 2006 +++ llvm/lib/CodeGen/IntrinsicLowering.cpp Thu Mar 9 14:02:42 2006 @@ -402,7 +402,6 @@ case Intrinsic::dbg_stoppoint: case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_end: - case Intrinsic::dbg_declare: case Intrinsic::dbg_func_start: if (CI->getType() != Type::VoidTy) CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); From lattner at cs.uiuc.edu Thu Mar 9 14:02:56 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:02:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200603092002.OAA06882@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.183 -> 1.184 --- Log message: remove dbg_declare, it's not used yet. --- Diffs of the changes: (+0 -4) SelectionDAGISel.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.183 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.184 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.183 Wed Mar 8 12:11:06 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Mar 9 14:02:42 2006 @@ -1003,10 +1003,6 @@ if (I.getType() != Type::VoidTy) setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); return 0; - case Intrinsic::dbg_declare: - if (I.getType() != Type::VoidTy) - setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); - return 0; case Intrinsic::isunordered_f32: case Intrinsic::isunordered_f64: From lattner at cs.uiuc.edu Thu Mar 9 14:03:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:03:43 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.h Message-ID: <200603092003.OAA06947@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.h updated: 1.38 -> 1.39 --- Log message: use the enum list autogen'd from Intrinsics.td --- Diffs of the changes: (+4 -61) Intrinsics.h | 65 +++-------------------------------------------------------- 1 files changed, 4 insertions(+), 61 deletions(-) Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.38 llvm/include/llvm/Intrinsics.h:1.39 --- llvm/include/llvm/Intrinsics.h:1.38 Thu Mar 2 18:18:00 2006 +++ llvm/include/llvm/Intrinsics.h Thu Mar 9 14:03:31 2006 @@ -26,68 +26,11 @@ enum ID { not_intrinsic = 0, // Must be zero - // Varargs handling intrinsics. - vastart, // Used to implement the va_start macro in C - vaend, // Used to implement the va_end macro in C - vacopy, // Used to implement the va_copy macro in C - - // Code generator intrinsics. - returnaddress, // Yields the return address of a dynamic call frame - frameaddress, // Yields the frame address of a dynamic call frame - stacksave, // Save the stack pointer - stackrestore, // Restore the stack pointer - prefetch, // Prefetch a value into the cache - pcmarker, // Export a PC from near the marker - readcyclecounter, // Read cycle counter register - - // setjmp/longjmp intrinsics. - setjmp, // Used to represent a setjmp call in C - longjmp, // Used to represent a longjmp call in C - sigsetjmp, // Used to represent a sigsetjmp call in C - siglongjmp, // Used to represent a siglongjmp call in C - - // Garbage Collection intrinsics. - gcroot, // Defines a new GC root on the stack - gcread, // Defines a read of a heap object (for read barriers) - gcwrite, // Defines a write to a heap object (for write barriers) - - // Debugging intrinsics. - dbg_stoppoint, // Represents source lines and breakpointable places - dbg_region_start, // Start of a region - dbg_region_end, // End of a region - dbg_func_start, // Start of a function - dbg_declare, // Declare a local object - - // Standard C library intrinsics. - memcpy_i32, // Copy non-overlapping memory blocks. i32 size. - memcpy_i64, // Copy non-overlapping memory blocks. i64 size. - memmove_i32, // Copy potentially overlapping memory blocks. i32 size. - memmove_i64, // Copy potentially overlapping memory blocks. i64 size. - memset_i32, // Fill memory with a byte value. i32 size. - memset_i64, // Fill memory with a byte value. i64 size. - isunordered_f32, // Return true if either float argument is a NaN - isunordered_f64, // Return true if either double argument is a NaN - sqrt_f32, // Square root of float - sqrt_f64, // Square root of double - - // Bit manipulation instrinsics. - bswap_i16, // Byteswap 16 bits - bswap_i32, // Byteswap 32 bits - bswap_i64, // Byteswap 64 bits - ctpop_i8, // Count population of sbyte - ctpop_i16, // Count population of short - ctpop_i32, // Count population of int - ctpop_i64, // Count population of long - ctlz_i8, // Count leading zeros of sbyte - ctlz_i16, // Count leading zeros of short - ctlz_i32, // Count leading zeros of int - ctlz_i64, // Count leading zeros of long - cttz_i8, // Count trailing zeros of sbyte - cttz_i16, // Count trailing zeros of short - cttz_i32, // Count trailing zeros of int - cttz_i64, // Count trailing zeros of long + // Get the intrinsic enums generated from Intrinsics.td +#define GET_INTRINSIC_ENUM_VALUES +#include "llvm/Intrinsics.gen" +#undef GET_INTRINSIC_ENUM_VALUES }; - } // End Intrinsic namespace } // End llvm namespace From lattner at cs.uiuc.edu Thu Mar 9 14:13:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:13:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603092013.OAA07230@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.14 -> 1.15 --- Log message: add a note --- Diffs of the changes: (+10 -0) README.txt | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.14 llvm/lib/Target/README.txt:1.15 --- llvm/lib/Target/README.txt:1.14 Mon Mar 6 20:46:26 2006 +++ llvm/lib/Target/README.txt Thu Mar 9 14:13:21 2006 @@ -117,3 +117,13 @@ //===---------------------------------------------------------------------===// +These two functions should generate the same code on big-endian systems: + +int g(int *j,int *l) { return memcmp(j,l,4); } +int h(int *j, int *l) { return *j - *l; } + +this could be done in SelectionDAGISel.cpp, along with other special cases, +for 1,2,4,8 bytes. + +//===---------------------------------------------------------------------===// + From lattner at cs.uiuc.edu Thu Mar 9 14:29:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:29:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Makefile Message-ID: <200603092029.OAA07406@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Makefile updated: 1.9 -> 1.10 --- Log message: This rule also depends on tblgen --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/VMCore/Makefile diff -u llvm/lib/VMCore/Makefile:1.9 llvm/lib/VMCore/Makefile:1.10 --- llvm/lib/VMCore/Makefile:1.9 Thu Mar 9 13:55:06 2006 +++ llvm/lib/VMCore/Makefile Thu Mar 9 14:29:41 2006 @@ -18,7 +18,7 @@ include $(LEVEL)/Makefile.common -$(LEVEL)/include/llvm/Intrinsics.gen: $(LEVEL)/include/llvm/Intrinsics.td +$(LEVEL)/include/llvm/Intrinsics.gen: $(LEVEL)/include/llvm/Intrinsics.td $(TBLGEN) @echo Building Intrinsics.gen from Intrinsics.td $(Verb) $(TableGen) $< -o $@ -gen-intrinsic From lattner at cs.uiuc.edu Thu Mar 9 14:34:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:34:32 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/IntrinsicEmitter.cpp IntrinsicEmitter.h Message-ID: <200603092034.OAA07522@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: IntrinsicEmitter.cpp updated: 1.1 -> 1.2 IntrinsicEmitter.h updated: 1.1 -> 1.2 --- Log message: autogenerate the function name recognizer --- Diffs of the changes: (+41 -0) IntrinsicEmitter.cpp | 37 +++++++++++++++++++++++++++++++++++++ IntrinsicEmitter.h | 4 ++++ 2 files changed, 41 insertions(+) Index: llvm/utils/TableGen/IntrinsicEmitter.cpp diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.1 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.2 --- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.1 Thu Mar 2 20:32:46 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.cpp Thu Mar 9 14:34:19 2006 @@ -55,10 +55,14 @@ // Emit the enum information. EmitEnumInfo(Ints, OS); + + // Emit the function name recognizer. + EmitFnNameRecognizer(Ints, OS); } void IntrinsicEmitter::EmitEnumInfo(const std::vector &Ints, std::ostream &OS) { + OS << "// Enum values for Intrinsics.h\n"; OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; for (unsigned i = 0, e = Ints.size(); i != e; ++i) { OS << " " << Ints[i].EnumName; @@ -68,3 +72,36 @@ } OS << "#endif\n\n"; } + +void IntrinsicEmitter:: +EmitFnNameRecognizer(const std::vector &Ints, + std::ostream &OS) { + // Build a function name -> intrinsic name mapping. + std::map IntMapping; + for (unsigned i = 0, e = Ints.size(); i != e; ++i) + IntMapping[Ints[i].Name] = Ints[i].EnumName; + + OS << "// Function name -> enum value recognizer code.\n"; + OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; + OS << " switch (Name[5]) {\n"; + OS << " // The 'llvm.' namespace is reserved!\n"; + OS << " default: assert(0 && \"Unknown LLVM intrinsic function!\");\n"; + // Emit the intrinsics in sorted order. + char LastChar = 0; + for (std::map::iterator I = IntMapping.begin(), + E = IntMapping.end(); I != E; ++I) { + assert(I->first.size() > 5 && std::string(I->first.begin(), + I->first.begin()+5) == "llvm." && + "Invalid intrinsic name!"); + if (I->first[5] != LastChar) { + LastChar = I->first[5]; + OS << " case '" << LastChar << "':\n"; + } + + OS << " if (Name == \"" << I->first << "\") return Intrinsic::" + << I->second << ";\n"; + } + OS << " }\n"; + OS << "#endif\n"; +} + Index: llvm/utils/TableGen/IntrinsicEmitter.h diff -u llvm/utils/TableGen/IntrinsicEmitter.h:1.1 llvm/utils/TableGen/IntrinsicEmitter.h:1.2 --- llvm/utils/TableGen/IntrinsicEmitter.h:1.1 Thu Mar 2 20:32:46 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.h Thu Mar 9 14:34:19 2006 @@ -28,6 +28,10 @@ void EmitEnumInfo(const std::vector &Ints, std::ostream &OS); + + void EmitFnNameRecognizer(const std::vector &Ints, + std::ostream &OS); + }; } // End llvm namespace From lattner at cs.uiuc.edu Thu Mar 9 14:35:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 14:35:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Message-ID: <200603092035.OAA07587@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.103 -> 1.104 --- Log message: Use the function name matcher autogenerated from the .td file. --- Diffs of the changes: (+3 -76) Function.cpp | 79 ++--------------------------------------------------------- 1 files changed, 3 insertions(+), 76 deletions(-) Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.103 llvm/lib/VMCore/Function.cpp:1.104 --- llvm/lib/VMCore/Function.cpp:1.103 Thu Mar 9 14:01:50 2006 +++ llvm/lib/VMCore/Function.cpp Thu Mar 9 14:35:01 2006 @@ -207,82 +207,9 @@ assert(Name.size() != 5 && "'llvm.' is an invalid intrinsic name!"); - switch (Name[5]) { - case 'b': - if (Name == "llvm.bswap.i16") return Intrinsic::bswap_i16; - if (Name == "llvm.bswap.i32") return Intrinsic::bswap_i32; - if (Name == "llvm.bswap.i64") return Intrinsic::bswap_i64; - break; - case 'c': - if (Name == "llvm.ctpop.i8") return Intrinsic::ctpop_i8; - if (Name == "llvm.ctpop.i16") return Intrinsic::ctpop_i16; - if (Name == "llvm.ctpop.i32") return Intrinsic::ctpop_i32; - if (Name == "llvm.ctpop.i64") return Intrinsic::ctpop_i64; - if (Name == "llvm.cttz.i8") return Intrinsic::cttz_i8; - if (Name == "llvm.cttz.i16") return Intrinsic::cttz_i16; - if (Name == "llvm.cttz.i32") return Intrinsic::cttz_i32; - if (Name == "llvm.cttz.i64") return Intrinsic::cttz_i64; - if (Name == "llvm.ctlz.i8") return Intrinsic::ctlz_i8; - if (Name == "llvm.ctlz.i16") return Intrinsic::ctlz_i16; - if (Name == "llvm.ctlz.i32") return Intrinsic::ctlz_i32; - if (Name == "llvm.ctlz.i64") return Intrinsic::ctlz_i64; - break; - case 'd': - if (Name == "llvm.dbg.stoppoint") return Intrinsic::dbg_stoppoint; - if (Name == "llvm.dbg.region.start")return Intrinsic::dbg_region_start; - if (Name == "llvm.dbg.region.end") return Intrinsic::dbg_region_end; - if (Name == "llvm.dbg.func.start") return Intrinsic::dbg_func_start; - break; - case 'f': - if (Name == "llvm.frameaddress") return Intrinsic::frameaddress; - break; - case 'g': - if (Name == "llvm.gcwrite") return Intrinsic::gcwrite; - if (Name == "llvm.gcread") return Intrinsic::gcread; - if (Name == "llvm.gcroot") return Intrinsic::gcroot; - break; - case 'i': - if (Name == "llvm.isunordered.f32") - return Intrinsic::isunordered_f32; - if (Name == "llvm.isunordered.f64") - return Intrinsic::isunordered_f64; - break; - case 'l': - if (Name == "llvm.longjmp") return Intrinsic::longjmp; - break; - case 'm': - if (Name == "llvm.memcpy.i32") return Intrinsic::memcpy_i32; - if (Name == "llvm.memcpy.i64") return Intrinsic::memcpy_i64; - if (Name == "llvm.memmove.i32") return Intrinsic::memmove_i32; - if (Name == "llvm.memmove.i64") return Intrinsic::memmove_i64; - if (Name == "llvm.memset.i32") return Intrinsic::memset_i32; - if (Name == "llvm.memset.i64") return Intrinsic::memset_i64; - break; - case 'p': - if (Name == "llvm.prefetch") return Intrinsic::prefetch; - if (Name == "llvm.pcmarker") return Intrinsic::pcmarker; - break; - case 'r': - if (Name == "llvm.returnaddress") return Intrinsic::returnaddress; - if (Name == "llvm.readcyclecounter") return Intrinsic::readcyclecounter; - break; - case 's': - if (Name == "llvm.setjmp") return Intrinsic::setjmp; - if (Name == "llvm.sigsetjmp") return Intrinsic::sigsetjmp; - if (Name == "llvm.siglongjmp") return Intrinsic::siglongjmp; - if (Name == "llvm.stackrestore") return Intrinsic::stackrestore; - if (Name == "llvm.stacksave") return Intrinsic::stacksave; - if (Name == "llvm.sqrt.f32") return Intrinsic::sqrt_f32; - if (Name == "llvm.sqrt.f64") return Intrinsic::sqrt_f64; - break; - case 'v': - if (Name == "llvm.va_copy") return Intrinsic::vacopy; - if (Name == "llvm.va_end") return Intrinsic::vaend; - if (Name == "llvm.va_start") return Intrinsic::vastart; - break; - } - // The "llvm." namespace is reserved! - assert(!"Unknown LLVM intrinsic function!"); +#define GET_FUNCTION_RECOGNIZER +#include "llvm/Intrinsics.gen" +#undef GET_FUNCTION_RECOGNIZER return 0; } From evan.cheng at apple.com Thu Mar 9 15:51:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 9 Mar 2006 15:51:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.cpp Message-ID: <200603092151.PAA08113@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.cpp updated: 1.105 -> 1.106 --- Log message: Add option -enable-x86-lsr to enable x86 loop strength reduction pass. --- Diffs of the changes: (+7 -0) X86TargetMachine.cpp | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.105 llvm/lib/Target/X86/X86TargetMachine.cpp:1.106 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.105 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Thu Mar 9 15:51:28 2006 @@ -37,6 +37,10 @@ cl::opt DisableOutput("disable-x86-llc-output", cl::Hidden, cl::desc("Disable the X86 asm printer, for use " "when profiling the code generator.")); + + cl::opt EnableX86LSR("enable-x86-lsr", cl::Hidden, + cl::desc("Enable the X86 loop strength reduction " + "pass.")); // Register the target. RegisterTarget X("x86", " IA-32 (Pentium and above)"); } @@ -92,6 +96,9 @@ if (FileType != TargetMachine::AssemblyFile && FileType != TargetMachine::ObjectFile) return true; + // Run loop strength reduction before anything else. + if (EnableX86LSR) PM.add(createLoopStrengthReducePass()); + // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); From lattner at cs.uiuc.edu Thu Mar 9 16:05:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:05:16 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenIntrinsics.h IntrinsicEmitter.cpp IntrinsicEmitter.h Message-ID: <200603092205.QAA08298@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenIntrinsics.h updated: 1.2 -> 1.3 IntrinsicEmitter.cpp updated: 1.2 -> 1.3 IntrinsicEmitter.h updated: 1.2 -> 1.3 --- Log message: parse intrinsic types autogenerate an intrinsic verifier --- Diffs of the changes: (+50 -4) CodeGenIntrinsics.h | 4 ++++ IntrinsicEmitter.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- IntrinsicEmitter.h | 3 ++- 3 files changed, 50 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/CodeGenIntrinsics.h diff -u llvm/utils/TableGen/CodeGenIntrinsics.h:1.2 llvm/utils/TableGen/CodeGenIntrinsics.h:1.3 --- llvm/utils/TableGen/CodeGenIntrinsics.h:1.2 Fri Mar 3 00:13:41 2006 +++ llvm/utils/TableGen/CodeGenIntrinsics.h Thu Mar 9 16:05:04 2006 @@ -26,6 +26,10 @@ std::string Name; // The name of the LLVM function "llvm.bswap.i32" std::string EnumName; // The name of the enum "bswap_i32" + /// ArgTypes - The type primitive enum value for the return value and all + /// of the arguments. These are things like Type::UIntTyID. + std::vector ArgTypes; + // Memory mod/ref behavior of this intrinsic. enum { NoMem, ReadArgMem, ReadMem, WriteArgMem, WriteMem Index: llvm/utils/TableGen/IntrinsicEmitter.cpp diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.2 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.3 --- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.2 Thu Mar 9 14:34:19 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.cpp Thu Mar 9 16:05:04 2006 @@ -42,6 +42,18 @@ else Name += EnumName[i]; } + + // Parse the list of argument types. + ListInit *TypeList = R->getValueAsListInit("Types"); + for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) { + DefInit *DI = dynamic_cast(TypeList->getElement(i)); + assert(DI && "Invalid list type!"); + Record *TyEl = DI->getDef(); + assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!"); + ArgTypes.push_back(TyEl->getValueAsString("TypeVal")); + } + if (ArgTypes.size() == 0) + throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!"; } //===----------------------------------------------------------------------===// @@ -58,6 +70,9 @@ // Emit the function name recognizer. EmitFnNameRecognizer(Ints, OS); + + // Emit the intrinsic verifier. + EmitVerifier(Ints, OS); } void IntrinsicEmitter::EmitEnumInfo(const std::vector &Ints, @@ -84,8 +99,7 @@ OS << "// Function name -> enum value recognizer code.\n"; OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; OS << " switch (Name[5]) {\n"; - OS << " // The 'llvm.' namespace is reserved!\n"; - OS << " default: assert(0 && \"Unknown LLVM intrinsic function!\");\n"; + OS << " default: break;\n"; // Emit the intrinsics in sorted order. char LastChar = 0; for (std::map::iterator I = IntMapping.begin(), @@ -102,6 +116,33 @@ << I->second << ";\n"; } OS << " }\n"; - OS << "#endif\n"; + OS << " // The 'llvm.' namespace is reserved!\n"; + OS << " assert(0 && \"Unknown LLVM intrinsic function!\");\n"; + OS << "#endif\n\n"; +} + +void IntrinsicEmitter::EmitVerifier(const std::vector &Ints, + std::ostream &OS) { + OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; + OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; + OS << " switch (ID) {\n"; + OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; + for (unsigned i = 0, e = Ints.size(); i != e; ++i) { + OS << " case Intrinsic::" << Ints[i].EnumName << ":\t\t// " + << Ints[i].Name << "\n"; + OS << " Assert1(FTy->getNumParams() == " << Ints[i].ArgTypes.size()-1 + << ",\n" + << " \"Illegal # arguments for intrinsic function!\", IF);\n"; + OS << " Assert1(FTy->getReturnType()->getTypeID() == " + << Ints[i].ArgTypes[0] << ",\n" + << " \"Illegal result type!\", IF);\n"; + for (unsigned j = 1; j != Ints[i].ArgTypes.size(); ++j) + OS << " Assert1(FTy->getParamType(" << j-1 << ")->getTypeID() == " + << Ints[i].ArgTypes[j] << ",\n" + << " \"Illegal result type!\", IF);\n"; + OS << " break;\n"; + } + OS << " }\n"; + OS << "#endif\n\n"; } Index: llvm/utils/TableGen/IntrinsicEmitter.h diff -u llvm/utils/TableGen/IntrinsicEmitter.h:1.2 llvm/utils/TableGen/IntrinsicEmitter.h:1.3 --- llvm/utils/TableGen/IntrinsicEmitter.h:1.2 Thu Mar 9 14:34:19 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.h Thu Mar 9 16:05:04 2006 @@ -31,7 +31,8 @@ void EmitFnNameRecognizer(const std::vector &Ints, std::ostream &OS); - + void EmitVerifier(const std::vector &Ints, + std::ostream &OS); }; } // End llvm namespace From lattner at cs.uiuc.edu Thu Mar 9 16:06:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:06:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200603092206.QAA08361@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.149 -> 1.150 --- Log message: Use the autogenerated intrinsic verifier --- Diffs of the changes: (+5 -266) Verifier.cpp | 271 +---------------------------------------------------------- 1 files changed, 5 insertions(+), 266 deletions(-) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.149 llvm/lib/VMCore/Verifier.cpp:1.150 --- llvm/lib/VMCore/Verifier.cpp:1.149 Thu Mar 9 14:01:50 2006 +++ llvm/lib/VMCore/Verifier.cpp Thu Mar 9 16:06:04 2006 @@ -676,273 +676,12 @@ /// void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Function *IF = CI.getCalledFunction(); - const FunctionType *FT = IF->getFunctionType(); + const FunctionType *FTy = IF->getFunctionType(); Assert1(IF->isExternal(), "Intrinsic functions should never be defined!", IF); - unsigned NumArgs = 0; - - // FIXME: this should check the return type of each intrinsic as well, also - // arguments! - switch (ID) { - case Intrinsic::vastart: - Assert1(CI.getParent()->getParent()->getFunctionType()->isVarArg(), - "llvm.va_start intrinsic may only occur in function with variable" - " args!", &CI); - NumArgs = 1; - break; - case Intrinsic::vaend: NumArgs = 1; break; - case Intrinsic::vacopy: NumArgs = 2; break; - - case Intrinsic::returnaddress: - case Intrinsic::frameaddress: - Assert1(isa(FT->getReturnType()), - "llvm.(frame|return)address must return pointers", IF); - Assert1(FT->getNumParams() == 1 && isa(CI.getOperand(1)), - "llvm.(frame|return)address require a single constant integer argument", - &CI); - NumArgs = 1; - break; - - case Intrinsic::isunordered_f32: - Assert1(FT->getNumParams() == 2, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == Type::BoolTy, - "Return type is not bool!", IF); - Assert1(FT->getParamType(0) == FT->getParamType(1), - "Arguments must be of the same type!", IF); - Assert1(FT->getParamType(0) == Type::FloatTy, - "Arguments must be a 32-bit floating point type!", IF); - NumArgs = 2; - break; - - case Intrinsic::isunordered_f64: - Assert1(FT->getNumParams() == 2, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == Type::BoolTy, - "Return type is not bool!", IF); - Assert1(FT->getParamType(0) == FT->getParamType(1), - "Arguments must be of the same type!", IF); - Assert1(FT->getParamType(0) == Type::DoubleTy, - "Argument is not a 64-bit floating point type!", IF); - NumArgs = 2; - break; - - case Intrinsic::readcyclecounter: - Assert1(FT->getNumParams() == 0, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == Type::ULongTy, - "Return type is not ulong!", IF); - NumArgs = 0; - break; - - case Intrinsic::bswap_i16: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getReturnType() == Type::UShortTy, - "Return type is not ushort!", IF); - NumArgs = 1; - break; - - case Intrinsic::bswap_i32: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getReturnType() == Type::UIntTy, - "Return type is not uint!", IF); - NumArgs = 1; - break; - - case Intrinsic::bswap_i64: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getReturnType() == Type::ULongTy, - "Return type is not ulong!", IF); - NumArgs = 1; - break; - - case Intrinsic::ctpop_i8: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UByteTy, - "Argument is not ubyte!", IF); - NumArgs = 1; - break; - - case Intrinsic::ctpop_i16: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UShortTy, - "Argument is not ushort!", IF); - NumArgs = 1; - break; - - case Intrinsic::ctpop_i32: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF); - NumArgs = 1; - break; - - case Intrinsic::ctpop_i64: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::ULongTy, "Argument is not ulong!", IF); - NumArgs = 1; - break; - - case Intrinsic::ctlz_i8: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UByteTy, "Argument is not ubyte!", IF); - NumArgs = 1; - break; - - case Intrinsic::ctlz_i16: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UShortTy, - "Argument is not ushort!", IF); - NumArgs = 1; - break; - case Intrinsic::ctlz_i32: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF); - NumArgs = 1; - break; - case Intrinsic::ctlz_i64: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::ULongTy, "Argument is not ulong!", IF); - NumArgs = 1; - break; - case Intrinsic::cttz_i8: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UByteTy, "Argument is not ubyte!", IF); - NumArgs = 1; - break; - case Intrinsic::cttz_i16: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UShortTy, - "Argument is not ushort!", IF); - NumArgs = 1; - break; - case Intrinsic::cttz_i32: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF); - NumArgs = 1; - break; - case Intrinsic::cttz_i64: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type does not match source type", IF); - Assert1(FT->getParamType(0) == Type::ULongTy, "Argument Is not ulong!", IF); - NumArgs = 1; - break; - - case Intrinsic::sqrt_f32: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getParamType(0) == Type::FloatTy, - "Argument is not a 32-bit floating point type!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type is not the same as argument type!", IF); - NumArgs = 1; - break; - - case Intrinsic::sqrt_f64: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getParamType(0) == Type::DoubleTy, - "Argument is not a 64-bit floating point type!", IF); - Assert1(FT->getReturnType() == FT->getParamType(0), - "Return type is not the same as argument type!", IF); - NumArgs = 1; - break; - - case Intrinsic::setjmp: NumArgs = 1; break; - case Intrinsic::longjmp: NumArgs = 2; break; - case Intrinsic::sigsetjmp: NumArgs = 2; break; - case Intrinsic::siglongjmp: NumArgs = 2; break; - - case Intrinsic::gcroot: - Assert1(FT->getNumParams() == 2, - "Illegal # arguments for intrinsic function!", IF); - Assert1(isa(CI.getOperand(2)), - "Second argument to llvm.gcroot must be a constant!", &CI); - NumArgs = 2; - break; - case Intrinsic::gcread: NumArgs = 2; break; - case Intrinsic::gcwrite: NumArgs = 3; break; - - case Intrinsic::dbg_stoppoint: NumArgs = 4; break; - case Intrinsic::dbg_region_start:NumArgs = 1; break; - case Intrinsic::dbg_region_end: NumArgs = 1; break; - case Intrinsic::dbg_func_start: NumArgs = 1; break; - - case Intrinsic::memcpy_i32: NumArgs = 4; break; - case Intrinsic::memcpy_i64: NumArgs = 4; break; - case Intrinsic::memmove_i32: NumArgs = 4; break; - case Intrinsic::memmove_i64: NumArgs = 4; break; - case Intrinsic::memset_i32: NumArgs = 4; break; - case Intrinsic::memset_i64: NumArgs = 4; break; - - case Intrinsic::stacksave: - NumArgs = 0; - Assert1(CI.getType() == PointerType::get(Type::SByteTy), - "llvm.stacksave must return an sbyte*", &CI); - break; - case Intrinsic::stackrestore: - NumArgs = 1; - Assert1(CI.getOperand(1)->getType() == PointerType::get(Type::SByteTy), - "llvm.stackrestore must take an sbyte*", &CI); - Assert1(CI.getType() == Type::VoidTy, - "llvm.stackrestore return void", &CI); - break; - case Intrinsic::prefetch: NumArgs = 3; break; - case Intrinsic::pcmarker: - NumArgs = 1; - Assert1(isa(CI.getOperand(1)), - "First argument to llvm.pcmarker must be a constant!", &CI); - break; - - case Intrinsic::not_intrinsic: - assert(0 && "Invalid intrinsic!"); NumArgs = 0; break; - } - - Assert1(FT->getNumParams() == NumArgs || (FT->getNumParams() < NumArgs && - FT->isVarArg()), - "Illegal # arguments for intrinsic function!", IF); + +#define GET_INTRINSIC_VERIFIER +#include "llvm/Intrinsics.gen" +#undef GET_INTRINSIC_VERIFIER } From lattner at cs.uiuc.edu Thu Mar 9 16:07:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:07:51 -0600 Subject: [llvm-commits] CVS: llvm/docs/ExtendingLLVM.html Message-ID: <200603092207.QAA08421@zion.cs.uiuc.edu> Changes in directory llvm/docs: ExtendingLLVM.html updated: 1.22 -> 1.23 --- Log message: Intrinsic adding is a little bit simpler now --- Diffs of the changes: (+3 -10) ExtendingLLVM.html | 13 +++---------- 1 files changed, 3 insertions(+), 10 deletions(-) Index: llvm/docs/ExtendingLLVM.html diff -u llvm/docs/ExtendingLLVM.html:1.22 llvm/docs/ExtendingLLVM.html:1.23 --- llvm/docs/ExtendingLLVM.html:1.22 Mon Jan 16 10:31:40 2006 +++ llvm/docs/ExtendingLLVM.html Thu Mar 9 16:07:39 2006 @@ -85,15 +85,8 @@ what the restrictions are. Talk to other people about it so that you are sure it's a good idea. -
  • llvm/include/llvm/Intrinsics.h: - add an enum in the llvm::Intrinsic namespace
  • - -
  • llvm/lib/VMCore/Verifier.cpp: - Add code to check the invariants of the intrinsic are respected.
  • - -
  • llvm/lib/VMCore/Function.cpp (Function::getIntrinsicID()): - Identify the new intrinsic function, returning the enum for the intrinsic - that you added.
  • +
  • llvm/include/llvm/Intrinsics.td: + Add an entry for your intrinsic.
  • llvm/lib/Analysis/BasicAliasAnalysis.cpp: If the new intrinsic does not access memory or does not write to memory, add it to the relevant list @@ -405,7 +398,7 @@ The LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/01/16 16:31:40 $ + Last modified: $Date: 2006/03/09 22:07:39 $ From lattner at cs.uiuc.edu Thu Mar 9 16:31:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:31:01 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/IntrinsicEmitter.cpp IntrinsicEmitter.h Message-ID: <200603092231.QAA08587@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: IntrinsicEmitter.cpp updated: 1.3 -> 1.4 IntrinsicEmitter.h updated: 1.3 -> 1.4 --- Log message: Parse mod/ref properties, autogen mod/ref information --- Diffs of the changes: (+47 -0) IntrinsicEmitter.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ IntrinsicEmitter.h | 2 ++ 2 files changed, 47 insertions(+) Index: llvm/utils/TableGen/IntrinsicEmitter.cpp diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.3 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.4 --- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.3 Thu Mar 9 16:05:04 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.cpp Thu Mar 9 16:30:49 2006 @@ -26,6 +26,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { std::string DefName = R->getName(); + ModRef = WriteMem; if (DefName.size() <= 4 || std::string(DefName.begin(), DefName.begin()+4) != "int_") @@ -54,6 +55,29 @@ } if (ArgTypes.size() == 0) throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!"; + + // Parse the intrinsic properties. + ListInit *PropList = R->getValueAsListInit("Properties"); + for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) { + DefInit *DI = dynamic_cast(PropList->getElement(i)); + assert(DI && "Invalid list type!"); + Record *Property = DI->getDef(); + assert(Property->isSubClassOf("IntrinsicProperty") && + "Expected a property!"); + + if (Property->getName() == "InstrNoMem") + ModRef = NoMem; + else if (Property->getName() == "InstrReadArgMem") + ModRef = ReadArgMem; + else if (Property->getName() == "IntrReadMem") + ModRef = ReadMem; + else if (Property->getName() == "InstrWriteArgMem") + ModRef = WriteArgMem; + else if (Property->getName() == "IntrWriteMem") + ModRef = WriteMem; + else + assert(0 && "Unknown property!"); + } } //===----------------------------------------------------------------------===// @@ -73,6 +97,9 @@ // Emit the intrinsic verifier. EmitVerifier(Ints, OS); + + // Emit mod/ref info for each function. + EmitModRefInfo(Ints, OS); } void IntrinsicEmitter::EmitEnumInfo(const std::vector &Ints, @@ -146,3 +173,21 @@ OS << "#endif\n\n"; } +void IntrinsicEmitter::EmitModRefInfo(const std::vector &Ints, + std::ostream &OS) { + OS << "// BasicAliasAnalysis code.\n"; + OS << "#ifdef GET_MODREF_BEHAVIOR\n"; + for (unsigned i = 0, e = Ints.size(); i != e; ++i) { + switch (Ints[i].ModRef) { + default: break; + case CodeGenIntrinsic::NoMem: + OS << " NoMemoryTable.push_back(\"" << Ints[i].Name << "\");\n"; + break; + case CodeGenIntrinsic::ReadArgMem: + case CodeGenIntrinsic::ReadMem: + OS << " OnlyReadsMemoryTable.push_back(\"" << Ints[i].Name << "\");\n"; + break; + } + } + OS << "#endif\n\n"; +} Index: llvm/utils/TableGen/IntrinsicEmitter.h diff -u llvm/utils/TableGen/IntrinsicEmitter.h:1.3 llvm/utils/TableGen/IntrinsicEmitter.h:1.4 --- llvm/utils/TableGen/IntrinsicEmitter.h:1.3 Thu Mar 9 16:05:04 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.h Thu Mar 9 16:30:49 2006 @@ -33,6 +33,8 @@ std::ostream &OS); void EmitVerifier(const std::vector &Ints, std::ostream &OS); + void EmitModRefInfo(const std::vector &Ints, + std::ostream &OS); }; } // End llvm namespace From lattner at cs.uiuc.edu Thu Mar 9 16:31:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:31:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200603092231.QAA08660@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.78 -> 1.79 --- Log message: Use autogenerated mod/ref info for intrinsics. --- Diffs of the changes: (+26 -22) BasicAliasAnalysis.cpp | 48 ++++++++++++++++++++++++++---------------------- 1 files changed, 26 insertions(+), 22 deletions(-) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.78 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.79 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.78 Sat Mar 4 15:48:01 2006 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Thu Mar 9 16:31:29 2006 @@ -741,12 +741,7 @@ // Note that this list cannot contain libm functions (such as acos and sqrt) // that set errno on a domain or other error. -static const char *DoesntAccessMemoryTable[] = { - // LLVM intrinsics: - "llvm.frameaddress", "llvm.returnaddress", "llvm.readport", - "llvm.isunordered", "llvm.sqrt", "llvm.bswap.i16", "llvm.bswap.i32", - "llvm.bswap.i64", "llvm.ctpop", "llvm.ctlz", "llvm.cttz", - +static const char *DoesntAccessMemoryFns[] = { "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl", "trunc", "truncf", "truncl", "ldexp", @@ -783,10 +778,8 @@ "__signbit", "__signbitf", "__signbitl", }; -static const unsigned DAMTableSize = - sizeof(DoesntAccessMemoryTable)/sizeof(DoesntAccessMemoryTable[0]); -static const char *OnlyReadsMemoryTable[] = { +static const char *OnlyReadsMemoryFns[] = { "atoi", "atol", "atof", "atoll", "atoq", "a64l", "bcmp", "memcmp", "memchr", "memrchr", "wmemcmp", "wmemchr", @@ -810,34 +803,45 @@ "feof_unlocked", "ferror_unlocked", "fileno_unlocked" }; -static const unsigned ORMTableSize = - sizeof(OnlyReadsMemoryTable)/sizeof(OnlyReadsMemoryTable[0]); - AliasAnalysis::ModRefBehavior BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS, std::vector *Info) { if (!F->isExternal()) return UnknownModRefBehavior; + static std::vector NoMemoryTable, OnlyReadsMemoryTable; + static bool Initialized = false; if (!Initialized) { + NoMemoryTable.insert(NoMemoryTable.end(), + DoesntAccessMemoryFns, + DoesntAccessMemoryFns+ + sizeof(DoesntAccessMemoryFns)/sizeof(DoesntAccessMemoryFns[0])); + + OnlyReadsMemoryTable.insert(OnlyReadsMemoryTable.end(), + OnlyReadsMemoryFns, + OnlyReadsMemoryFns+ + sizeof(OnlyReadsMemoryFns)/sizeof(OnlyReadsMemoryFns[0])); +#define GET_MODREF_BEHAVIOR +#include "llvm/Intrinsics.gen" +#undef GET_MODREF_BEHAVIOR + // Sort the table the first time through. - std::sort(DoesntAccessMemoryTable, DoesntAccessMemoryTable+DAMTableSize, - StringCompare()); - std::sort(OnlyReadsMemoryTable, OnlyReadsMemoryTable+ORMTableSize, + std::sort(NoMemoryTable.begin(), NoMemoryTable.end(), StringCompare()); + std::sort(OnlyReadsMemoryTable.begin(), OnlyReadsMemoryTable.end(), StringCompare()); Initialized = true; } - const char **Ptr = std::lower_bound(DoesntAccessMemoryTable, - DoesntAccessMemoryTable+DAMTableSize, - F->getName().c_str(), StringCompare()); - if (Ptr != DoesntAccessMemoryTable+DAMTableSize && *Ptr == F->getName()) + std::vector::iterator Ptr = + std::lower_bound(NoMemoryTable.begin(), NoMemoryTable.end(), + F->getName().c_str(), StringCompare()); + if (Ptr != NoMemoryTable.end() && *Ptr == F->getName()) return DoesNotAccessMemory; - Ptr = std::lower_bound(OnlyReadsMemoryTable, - OnlyReadsMemoryTable+ORMTableSize, + Ptr = std::lower_bound(OnlyReadsMemoryTable.begin(), + OnlyReadsMemoryTable.end(), F->getName().c_str(), StringCompare()); - if (Ptr != OnlyReadsMemoryTable+ORMTableSize && *Ptr == F->getName()) + if (Ptr != OnlyReadsMemoryTable.end() && *Ptr == F->getName()) return OnlyReadsMemory; return UnknownModRefBehavior; From lattner at cs.uiuc.edu Thu Mar 9 16:32:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:32:27 -0600 Subject: [llvm-commits] CVS: llvm/docs/ExtendingLLVM.html Message-ID: <200603092232.QAA08712@zion.cs.uiuc.edu> Changes in directory llvm/docs: ExtendingLLVM.html updated: 1.23 -> 1.24 --- Log message: Simpler still --- Diffs of the changes: (+1 -5) ExtendingLLVM.html | 6 +----- 1 files changed, 1 insertion(+), 5 deletions(-) Index: llvm/docs/ExtendingLLVM.html diff -u llvm/docs/ExtendingLLVM.html:1.23 llvm/docs/ExtendingLLVM.html:1.24 --- llvm/docs/ExtendingLLVM.html:1.23 Thu Mar 9 16:07:39 2006 +++ llvm/docs/ExtendingLLVM.html Thu Mar 9 16:32:16 2006 @@ -88,10 +88,6 @@
  • llvm/include/llvm/Intrinsics.td: Add an entry for your intrinsic.
  • -
  • llvm/lib/Analysis/BasicAliasAnalysis.cpp: If the new intrinsic does - not access memory or does not write to memory, add it to the relevant list - of functions.
  • -
  • llvm/lib/Analysis/ConstantFolding.cpp: If it is possible to constant fold your intrinsic, add support to it in the canConstantFoldCallTo and ConstantFoldCall functions.
  • @@ -398,7 +394,7 @@ The LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/03/09 22:07:39 $ + Last modified: $Date: 2006/03/09 22:32:16 $ From lattner at cs.uiuc.edu Thu Mar 9 16:38:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:38:04 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/IntrinsicEmitter.cpp IntrinsicEmitter.h Message-ID: <200603092238.QAA08945@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: IntrinsicEmitter.cpp updated: 1.4 -> 1.5 IntrinsicEmitter.h updated: 1.4 -> 1.5 --- Log message: generate side-effect info --- Diffs of the changes: (+27 -0) IntrinsicEmitter.cpp | 25 +++++++++++++++++++++++++ IntrinsicEmitter.h | 2 ++ 2 files changed, 27 insertions(+) Index: llvm/utils/TableGen/IntrinsicEmitter.cpp diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.4 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.5 --- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.4 Thu Mar 9 16:30:49 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.cpp Thu Mar 9 16:37:52 2006 @@ -100,6 +100,9 @@ // Emit mod/ref info for each function. EmitModRefInfo(Ints, OS); + + // Emit side effect info for each function. + EmitSideEffectInfo(Ints, OS); } void IntrinsicEmitter::EmitEnumInfo(const std::vector &Ints, @@ -191,3 +194,25 @@ } OS << "#endif\n\n"; } + +void IntrinsicEmitter:: +EmitSideEffectInfo(const std::vector &Ints, std::ostream &OS){ + OS << "// isInstructionTriviallyDead code.\n"; + OS << "#ifdef GET_SIDE_EFFECT_INFO\n"; + OS << " switch (F->getIntrinsicID()) {\n"; + OS << " default: break;\n"; + for (unsigned i = 0, e = Ints.size(); i != e; ++i) { + switch (Ints[i].ModRef) { + default: break; + case CodeGenIntrinsic::NoMem: + case CodeGenIntrinsic::ReadArgMem: + case CodeGenIntrinsic::ReadMem: + OS << " case Intrinsic::" << Ints[i].EnumName << ":\n"; + break; + } + } + OS << " return true; // These intrinsics have no side effects.\n"; + OS << " }\n"; + OS << "#endif\n\n"; + +} Index: llvm/utils/TableGen/IntrinsicEmitter.h diff -u llvm/utils/TableGen/IntrinsicEmitter.h:1.4 llvm/utils/TableGen/IntrinsicEmitter.h:1.5 --- llvm/utils/TableGen/IntrinsicEmitter.h:1.4 Thu Mar 9 16:30:49 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.h Thu Mar 9 16:37:52 2006 @@ -35,6 +35,8 @@ std::ostream &OS); void EmitModRefInfo(const std::vector &Ints, std::ostream &OS); + void EmitSideEffectInfo(const std::vector &Ints, + std::ostream &OS); }; } // End llvm namespace From lattner at cs.uiuc.edu Thu Mar 9 16:38:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:38:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200603092238.QAA08986@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.52 -> 1.53 --- Log message: use autogenerated side-effect information --- Diffs of the changes: (+5 -27) Local.cpp | 32 +++++--------------------------- 1 files changed, 5 insertions(+), 27 deletions(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.52 llvm/lib/Transforms/Utils/Local.cpp:1.53 --- llvm/lib/Transforms/Utils/Local.cpp:1.52 Thu Jan 19 17:53:23 2006 +++ llvm/lib/Transforms/Utils/Local.cpp Thu Mar 9 16:38:10 2006 @@ -307,33 +307,11 @@ if (!I->mayWriteToMemory()) return true; if (CallInst *CI = dyn_cast(I)) - if (Function *F = CI->getCalledFunction()) - switch (F->getIntrinsicID()) { - default: break; - case Intrinsic::returnaddress: - case Intrinsic::frameaddress: - case Intrinsic::stacksave: - case Intrinsic::isunordered_f32: - case Intrinsic::isunordered_f64: - case Intrinsic::bswap_i16: - case Intrinsic::bswap_i32: - case Intrinsic::bswap_i64: - case Intrinsic::ctpop_i8: - case Intrinsic::ctpop_i16: - case Intrinsic::ctpop_i32: - case Intrinsic::ctpop_i64: - case Intrinsic::ctlz_i8: - case Intrinsic::ctlz_i16: - case Intrinsic::ctlz_i32: - case Intrinsic::ctlz_i64: - case Intrinsic::cttz_i8: - case Intrinsic::cttz_i16: - case Intrinsic::cttz_i32: - case Intrinsic::cttz_i64: - case Intrinsic::sqrt_f32: - case Intrinsic::sqrt_f64: - return true; // These intrinsics have no side effects. - } + if (Function *F = CI->getCalledFunction()) { +#define GET_SIDE_EFFECT_INFO +#include "llvm/Intrinsics.gen" +#undef GET_SIDE_EFFECT_INFO + } return false; } From lattner at cs.uiuc.edu Thu Mar 9 16:38:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 16:38:54 -0600 Subject: [llvm-commits] CVS: llvm/docs/ExtendingLLVM.html Message-ID: <200603092238.QAA09043@zion.cs.uiuc.edu> Changes in directory llvm/docs: ExtendingLLVM.html updated: 1.24 -> 1.25 --- Log message: Adding an intrinsic is simpler still. --- Diffs of the changes: (+1 -5) ExtendingLLVM.html | 6 +----- 1 files changed, 1 insertion(+), 5 deletions(-) Index: llvm/docs/ExtendingLLVM.html diff -u llvm/docs/ExtendingLLVM.html:1.24 llvm/docs/ExtendingLLVM.html:1.25 --- llvm/docs/ExtendingLLVM.html:1.24 Thu Mar 9 16:32:16 2006 +++ llvm/docs/ExtendingLLVM.html Thu Mar 9 16:38:42 2006 @@ -92,10 +92,6 @@ constant fold your intrinsic, add support to it in the canConstantFoldCallTo and ConstantFoldCall functions. -
  • llvm/lib/Transforms/Utils/Local.cpp: If your intrinsic has no side- - effects, add it to the list of intrinsics in the - isInstructionTriviallyDead function.
  • -
  • llvm/test/Regression/*: Add test cases for your test cases to the test suite
  • @@ -394,7 +390,7 @@ The LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/03/09 22:32:16 $ + Last modified: $Date: 2006/03/09 22:38:42 $ From evan.cheng at apple.com Thu Mar 9 20:18:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 9 Mar 2006 20:18:41 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200603100218.UAA10309@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.199 -> 1.200 --- Log message: x86 llc-beta sets -enable-x86-lsr to turn on loop strength reduction. --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.199 llvm-test/Makefile.programs:1.200 --- llvm-test/Makefile.programs:1.199 Thu Mar 9 11:45:02 2006 +++ llvm-test/Makefile.programs Thu Mar 9 20:18:30 2006 @@ -197,7 +197,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -enable-x86-fastcc +LLCBETAOPTION := -enable-x86-lsr endif ifeq ($(ARCH),Sparc) LLCBETAOPTION := -enable-sparc-v9-insts From jeffc at jolt-lang.org Thu Mar 9 21:57:58 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 9 Mar 2006 21:57:58 -0600 Subject: [llvm-commits] CVS: llvm/win32/VMCore/VMCore.vcproj Message-ID: <200603100357.VAA10778@zion.cs.uiuc.edu> Changes in directory llvm/win32/VMCore: VMCore.vcproj updated: 1.15 -> 1.16 --- Log message: Fix VC++ build breakage. --- Diffs of the changes: (+29 -0) VMCore.vcproj | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/win32/VMCore/VMCore.vcproj diff -u llvm/win32/VMCore/VMCore.vcproj:1.15 llvm/win32/VMCore/VMCore.vcproj:1.16 --- llvm/win32/VMCore/VMCore.vcproj:1.15 Sun Jan 29 22:07:07 2006 +++ llvm/win32/VMCore/VMCore.vcproj Thu Mar 9 21:57:45 2006 @@ -4,6 +4,7 @@ Version="7.10" Name="VMCore" ProjectGUID="{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}" + RootNamespace="VMCore" Keyword="Win32Proj">
    + + + + + + + + + + + + From jeffc at jolt-lang.org Thu Mar 9 21:57:58 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 9 Mar 2006 21:57:58 -0600 Subject: [llvm-commits] CVS: llvm/win32/llvm.sln Message-ID: <200603100357.VAA10786@zion.cs.uiuc.edu> Changes in directory llvm/win32: llvm.sln updated: 1.25 -> 1.26 --- Log message: Fix VC++ build breakage. --- Diffs of the changes: (+2 -0) llvm.sln | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/win32/llvm.sln diff -u llvm/win32/llvm.sln:1.25 llvm/win32/llvm.sln:1.26 --- llvm/win32/llvm.sln:1.25 Fri Sep 9 21:00:02 2005 +++ llvm/win32/llvm.sln Thu Mar 9 21:57:45 2006 @@ -31,6 +31,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VMCore", "VMCore\VMCore.vcproj", "{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}" ProjectSection(ProjectDependencies) = postProject {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Target", "Target\Target.vcproj", "{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}" @@ -64,6 +65,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Transforms", "Transforms\Transforms.vcproj", "{C59374C1-9FC0-4147-B836-327DFDC52D99}" ProjectSection(ProjectDependencies) = postProject {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Configure", "Configure\Configure.vcproj", "{19514E48-456C-4B9D-8637-F2285476461E}" From jeffc at jolt-lang.org Thu Mar 9 21:57:58 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 9 Mar 2006 21:57:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603100357.VAA10782@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.32 -> 1.33 --- Log message: Fix VC++ build breakage. --- Diffs of the changes: (+3 -3) ScheduleDAGList.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.32 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.33 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.32 Thu Mar 9 11:31:22 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 21:57:45 2006 @@ -761,7 +761,7 @@ SethiUllmanNumber = 1; } else { int Extra = 0; - for (std::set::iterator I = SU->Preds.begin(), + for (std::set::const_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { SUnit *PredSU = *I; int PredSethiUllman = CalcNodePriority(PredSU); @@ -870,11 +870,11 @@ return Latency; int MaxSuccLatency = 0; - for (std::set::iterator I = SU.Succs.begin(), + for (std::set::const_iterator I = SU.Succs.begin(), E = SU.Succs.end(); I != E; ++I) MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I)); - for (std::set::iterator I = SU.ChainSuccs.begin(), + for (std::set::const_iterator I = SU.ChainSuccs.begin(), E = SU.ChainSuccs.end(); I != E; ++I) MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I)); From lattner at cs.uiuc.edu Thu Mar 9 22:17:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 22:17:18 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.td Message-ID: <200603100417.WAA10941@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.td updated: 1.1 -> 1.2 --- Log message: Fix an incorrect intrinsic description --- Diffs of the changes: (+3 -2) Intrinsics.td | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Intrinsics.td diff -u llvm/include/llvm/Intrinsics.td:1.1 llvm/include/llvm/Intrinsics.td:1.2 --- llvm/include/llvm/Intrinsics.td:1.1 Thu Mar 2 20:33:15 2006 +++ llvm/include/llvm/Intrinsics.td Thu Mar 9 22:17:06 2006 @@ -179,8 +179,9 @@ //===------------------------ Debugger Intrinsics -------------------------===// // -def int_dbg_stoppoint : Intrinsic<[llvm_anchor_ty, llvm_uint_ty, - llvm_uint_ty, llvm_descriptor_ty]>; +def int_dbg_stoppoint : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty, + llvm_uint_ty, llvm_uint_ty, + llvm_descriptor_ty]>; def int_dbg_region_start : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; def int_dbg_region_end : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; def int_dbg_func_start : Intrinsic<[llvm_anchor_ty, llvm_descriptor_ty]>; From lattner at cs.uiuc.edu Thu Mar 9 22:33:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 22:33:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603100433.WAA11217@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.33 -> 1.34 --- Log message: add an aggregate method for reinserting scheduled nodes, add a callback for priority impls that want to be notified when a node is scheduled --- Diffs of the changes: (+23 -8) ScheduleDAGList.cpp | 31 +++++++++++++++++++++++-------- 1 files changed, 23 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.33 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.34 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.33 Thu Mar 9 21:57:45 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 22:32:49 2006 @@ -141,7 +141,14 @@ virtual bool empty() const = 0; virtual void push(SUnit *U) = 0; + + virtual void push_all(const std::vector &Nodes) = 0; virtual SUnit *pop() = 0; + + /// ScheduledNode - As each node is scheduled, this method is invoked. This + /// allows the priority function to adjust the priority of node that have + /// already been emitted. + virtual void ScheduledNode(SUnit *Node) {} }; } @@ -340,11 +347,10 @@ } // Add the nodes that aren't ready back onto the available list. - while (!NotReady.empty()) { - PriorityQueue->push(NotReady.back()); - NotReady.pop_back(); - } + PriorityQueue->push_all(NotReady); + NotReady.clear(); + PriorityQueue->ScheduledNode(CurrNode); ScheduleNodeBottomUp(CurrNode); } @@ -421,13 +427,12 @@ } while (!PriorityQueue->empty()); // Add the nodes that aren't ready back onto the available list. - while (!NotReady.empty()) { - PriorityQueue->push(NotReady.back()); - NotReady.pop_back(); - } + PriorityQueue->push_all(NotReady); + NotReady.clear(); // If we found a node to schedule, do it now. if (FoundNode) { + PriorityQueue->ScheduledNode(FoundNode); ScheduleNodeTopDown(FoundNode); HazardRec->EmitInstruction(FoundNode->Node); } else if (!HasNoopHazards) { @@ -700,6 +705,11 @@ void push(SUnit *U) { Queue.push(U); } + void push_all(const std::vector &Nodes) { + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) + Queue.push(Nodes[i]); + } + SUnit *pop() { SUnit *V = Queue.top(); Queue.pop(); @@ -843,6 +853,11 @@ void push(SUnit *U) { Queue.push(U); } + void push_all(const std::vector &Nodes) { + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) + Queue.push(Nodes[i]); + } + SUnit *pop() { SUnit *V = Queue.top(); Queue.pop(); From jeffc at jolt-lang.org Thu Mar 9 22:36:12 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 9 Mar 2006 22:36:12 -0600 Subject: [llvm-commits] CVS: llvm/win32/VMCore/VMCore.vcproj Message-ID: <200603100436.WAA11246@zion.cs.uiuc.edu> Changes in directory llvm/win32/VMCore: VMCore.vcproj updated: 1.16 -> 1.17 --- Log message: Put intrinsics.gen in its proper place. --- Diffs of the changes: (+7 -5) VMCore.vcproj | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) Index: llvm/win32/VMCore/VMCore.vcproj diff -u llvm/win32/VMCore/VMCore.vcproj:1.16 llvm/win32/VMCore/VMCore.vcproj:1.17 --- llvm/win32/VMCore/VMCore.vcproj:1.16 Thu Mar 9 21:57:45 2006 +++ llvm/win32/VMCore/VMCore.vcproj Thu Mar 9 22:36:01 2006 @@ -152,18 +152,20 @@ + Outputs="$(SolutionDir)llvm\intrinsics.gen"/> + Outputs="$(SolutionDir)llvm\intrinsics.gen"/> + RelativePath="..\llvm\intrinsics.gen"> From lattner at cs.uiuc.edu Thu Mar 9 23:51:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 9 Mar 2006 23:51:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603100551.XAA11665@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.34 -> 1.35 --- Log message: Teach the latency scheduler some new tricks. In particular, to break ties, keep track of a sense of "mobility", i.e. how many other nodes scheduling one node will free up. For something like this: float testadd(float *X, float *Y, float *Z, float *W, float *V) { return (*X+*Y)*(*Z+*W)+*V; } For example, this makes us schedule *X then *Y, not *X then *Z. The former allows us to issue the add, the later only lets us issue other loads. This turns the above code from this: _testadd: lfs f0, 0(r3) lfs f1, 0(r6) lfs f2, 0(r4) lfs f3, 0(r5) fadds f0, f0, f2 fadds f1, f3, f1 lfs f2, 0(r7) fmadds f1, f0, f1, f2 blr into this: _testadd: lfs f0, 0(r6) lfs f1, 0(r5) fadds f0, f1, f0 lfs f1, 0(r4) lfs f2, 0(r3) fadds f1, f2, f1 lfs f2, 0(r7) fmadds f1, f1, f0, f2 blr --- Diffs of the changes: (+157 -10) ScheduleDAGList.cpp | 167 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 157 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.34 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.35 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.34 Thu Mar 9 22:32:49 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 9 23:51:05 2006 @@ -51,6 +51,8 @@ short NumChainSuccsLeft; // # of chain succs not scheduled. bool isTwoAddress : 1; // Is a two-address instruction. bool isDefNUseOperand : 1; // Is a def&use operand. + bool isAvailable : 1; // True once available. + bool isScheduled : 1; // True once scheduled. unsigned short Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. unsigned NodeNum; // Entry # of node in the node vector. @@ -59,6 +61,7 @@ : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), isTwoAddress(false), isDefNUseOperand(false), + isAvailable(false), isScheduled(false), Latency(0), CycleBound(0), NodeNum(nodenum) {} void dump(const SelectionDAG *G) const; @@ -247,8 +250,10 @@ if ((PredSU->NumSuccsLeft + PredSU->NumChainSuccsLeft) == 0) { // EntryToken has to go last! Special case it here. - if (PredSU->Node->getOpcode() != ISD::EntryToken) + if (PredSU->Node->getOpcode() != ISD::EntryToken) { + PredSU->isAvailable = true; PriorityQueue->push(PredSU); + } } } @@ -275,8 +280,10 @@ } #endif - if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) + if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) { + SuccSU->isAvailable = true; PriorityQueue->push(SuccSU); + } } /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending @@ -350,8 +357,9 @@ PriorityQueue->push_all(NotReady); NotReady.clear(); - PriorityQueue->ScheduledNode(CurrNode); ScheduleNodeBottomUp(CurrNode); + CurrNode->isScheduled = true; + PriorityQueue->ScheduledNode(CurrNode); } // Add entry node last @@ -432,9 +440,10 @@ // If we found a node to schedule, do it now. if (FoundNode) { - PriorityQueue->ScheduledNode(FoundNode); ScheduleNodeTopDown(FoundNode); HazardRec->EmitInstruction(FoundNode->Node); + FoundNode->isScheduled = true; + PriorityQueue->ScheduledNode(FoundNode); } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. @@ -827,7 +836,13 @@ // Latencies - The latency (max of latency from this node to the bb exit) // for each node. std::vector Latencies; - + + /// NumNodesSolelyBlocking - This vector contains, for every node in the + /// Queue, the number of nodes that the node is the sole unscheduled + /// predecessor for. This is used as a tie-breaker heuristic for better + /// mobility. + std::vector NumNodesSolelyBlocking; + std::priority_queue, latency_sort> Queue; public: LatencyPriorityQueue() : Queue(latency_sort(this)) { @@ -848,14 +863,21 @@ return Latencies[NodeNum]; } + unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { + assert(NodeNum < NumNodesSolelyBlocking.size()); + return NumNodesSolelyBlocking[NodeNum]; + } + bool empty() const { return Queue.empty(); } - void push(SUnit *U) { - Queue.push(U); + virtual void push(SUnit *U) { + push_impl(U); } + void push_impl(SUnit *U); + void push_all(const std::vector &Nodes) { for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - Queue.push(Nodes[i]); + push_impl(Nodes[i]); } SUnit *pop() { @@ -863,17 +885,61 @@ Queue.pop(); return V; } + + // ScheduledNode - As nodes are scheduled, we look to see if there are any + // successor nodes that have a single unscheduled predecessor. If so, that + // single predecessor has a higher priority, since scheduling it will make + // the node available. + void ScheduledNode(SUnit *Node); + private: void CalculatePriorities(); int CalcLatency(const SUnit &SU); + void AdjustPriorityOfUnscheduledPreds(SUnit *SU); + + /// RemoveFromPriorityQueue - This is a really inefficient way to remove a + /// node from a priority queue. We should roll our own heap to make this + /// better or something. + void RemoveFromPriorityQueue(SUnit *SU) { + std::vector Temp; + + assert(!Queue.empty() && "Not in queue!"); + while (Queue.top() != SU) { + Temp.push_back(Queue.top()); + Queue.pop(); + assert(!Queue.empty() && "Not in queue!"); + } + + // Remove the node from the PQ. + Queue.pop(); + + // Add all the other nodes back. + for (unsigned i = 0, e = Temp.size(); i != e; ++i) + Queue.push(Temp[i]); + } }; } bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const { unsigned LHSNum = LHS->NodeNum; unsigned RHSNum = RHS->NodeNum; - - return PQ->getLatency(LHSNum) < PQ->getLatency(RHSNum); + + // The most important heuristic is scheduling the critical path. + unsigned LHSLatency = PQ->getLatency(LHSNum); + unsigned RHSLatency = PQ->getLatency(RHSNum); + if (LHSLatency < RHSLatency) return true; + if (LHSLatency > RHSLatency) return false; + + // After that, if two nodes have identical latencies, look to see if one will + // unblock more other nodes than the other. + unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum); + unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum); + if (LHSBlocked < RHSBlocked) return true; + if (LHSBlocked > RHSBlocked) return false; + + // Finally, just to provide a stable ordering, use the node number as a + // deciding factor. + return LHSNum < RHSNum; } @@ -899,11 +965,92 @@ /// CalculatePriorities - Calculate priorities of all scheduling units. void LatencyPriorityQueue::CalculatePriorities() { Latencies.assign(SUnits->size(), -1); + NumNodesSolelyBlocking.assign(SUnits->size(), 0); for (unsigned i = 0, e = SUnits->size(); i != e; ++i) CalcLatency((*SUnits)[i]); } +/// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor +/// of SU, return it, otherwise return null. +static SUnit *getSingleUnscheduledPred(SUnit *SU) { + SUnit *OnlyAvailablePred = 0; + for (std::set::const_iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) + if (!(*I)->isScheduled) { + // We found an available, but not scheduled, predecessor. If it's the + // only one we have found, keep track of it... otherwise give up. + if (OnlyAvailablePred && OnlyAvailablePred != *I) + return 0; + OnlyAvailablePred = *I; + } + + for (std::set::const_iterator I = SU->ChainSuccs.begin(), + E = SU->ChainSuccs.end(); I != E; ++I) + if (!(*I)->isScheduled) { + // We found an available, but not scheduled, predecessor. If it's the + // only one we have found, keep track of it... otherwise give up. + if (OnlyAvailablePred && OnlyAvailablePred != *I) + return 0; + OnlyAvailablePred = *I; + } + + return OnlyAvailablePred; +} + +void LatencyPriorityQueue::push_impl(SUnit *SU) { + // Look at all of the successors of this node. Count the number of nodes that + // this node is the sole unscheduled node for. + unsigned NumNodesBlocking = 0; + for (std::set::const_iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) + if (getSingleUnscheduledPred(*I) == SU) + ++NumNodesBlocking; + + for (std::set::const_iterator I = SU->ChainSuccs.begin(), + E = SU->ChainSuccs.end(); I != E; ++I) + if (getSingleUnscheduledPred(*I) == SU) + ++NumNodesBlocking; + + Queue.push(SU); +} + + +// ScheduledNode - As nodes are scheduled, we look to see if there are any +// successor nodes that have a single unscheduled predecessor. If so, that +// single predecessor has a higher priority, since scheduling it will make +// the node available. +void LatencyPriorityQueue::ScheduledNode(SUnit *SU) { + for (std::set::const_iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) + AdjustPriorityOfUnscheduledPreds(*I); + + for (std::set::const_iterator I = SU->ChainSuccs.begin(), + E = SU->ChainSuccs.end(); I != E; ++I) + AdjustPriorityOfUnscheduledPreds(*I); +} + +/// AdjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just +/// scheduled. If SU is not itself available, then there is at least one +/// predecessor node that has not been scheduled yet. If SU has exactly ONE +/// unscheduled predecessor, we want to increase its priority: it getting +/// scheduled will make this node available, so it is better than some other +/// node of the same priority that will not make a node available. +void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { + if (SU->isAvailable) return; // All preds scheduled. + + SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU); + if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return; + + // Okay, we found a single predecessor that is available, but not scheduled. + // Since it is available, it must be in the priority queue. First remove it. + RemoveFromPriorityQueue(OnlyAvailablePred); + + // Reinsert the node into the priority queue, which recomputes its + // NumNodesSolelyBlocking value. + push(OnlyAvailablePred); +} + //===----------------------------------------------------------------------===// // Public Constructor Functions From lattner at cs.uiuc.edu Fri Mar 10 00:30:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 00:30:23 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100630.AAA11855@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.15 -> 1.16 --- Log message: make some methods protected instead of private --- Diffs of the changes: (+4 -4) ScheduleDAG.h | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.15 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.16 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.15 Tue Mar 7 22:24:56 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 00:30:11 2006 @@ -382,16 +382,16 @@ private: void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, const TargetInstrDescriptor *II); - + + void AddToGroup(NodeInfo *D, NodeInfo *U); +protected: /// PrepareNodeInfo - Set up the basic minimum node info for scheduling. /// void PrepareNodeInfo(); - + /// IdentifyGroups - Put flagged nodes into groups. /// void IdentifyGroups(); - - void AddToGroup(NodeInfo *D, NodeInfo *U); }; /// createSimpleDAGScheduler - This creates a simple two pass instruction From lattner at cs.uiuc.edu Fri Mar 10 00:35:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 00:35:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp ScheduleDAGSimple.cpp Message-ID: <200603100635.AAA11936@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.73 -> 1.74 ScheduleDAGList.cpp updated: 1.35 -> 1.36 ScheduleDAGSimple.cpp updated: 1.6 -> 1.7 --- Log message: Push PrepareNodeInfo/IdentifyGroups down the inheritance hierarchy --- Diffs of the changes: (+10 -4) ScheduleDAG.cpp | 4 ---- ScheduleDAGList.cpp | 5 +++++ ScheduleDAGSimple.cpp | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.73 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.74 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.73 Tue Mar 7 22:25:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Mar 10 00:34:51 2006 @@ -498,10 +498,6 @@ // Number the nodes NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end()); - // Set up minimum info for scheduling - PrepareNodeInfo(); - // Construct node groups for flagged nodes - IdentifyGroups(); Schedule(); return BB; Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.35 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.36 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.35 Thu Mar 9 23:51:05 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 10 00:34:51 2006 @@ -640,6 +640,11 @@ void ScheduleDAGList::Schedule() { DEBUG(std::cerr << "********** List Scheduling **********\n"); + // Set up minimum info for scheduling + PrepareNodeInfo(); + // Construct node groups for flagged nodes + IdentifyGroups(); + // Build scheduling units. BuildSchedUnits(); Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.6 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.7 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.6 Thu Mar 9 01:13:00 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Fri Mar 10 00:34:51 2006 @@ -560,6 +560,11 @@ /// Schedule - Order nodes according to selected style. /// void ScheduleDAGSimple::Schedule() { + // Set up minimum info for scheduling + PrepareNodeInfo(); + // Construct node groups for flagged nodes + IdentifyGroups(); + // Test to see if scheduling should occur bool ShouldSchedule = NodeCount > 3 && Heuristic != noScheduling; // Don't waste time if is only entry and return From lattner at cs.uiuc.edu Fri Mar 10 01:13:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:13:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603100713.BAA12183@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.36 -> 1.37 --- Log message: Create SUnits directly from the SelectionDAG. --- Diffs of the changes: (+87 -87) ScheduleDAGList.cpp | 174 ++++++++++++++++++++++++++-------------------------- 1 files changed, 87 insertions(+), 87 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.36 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.37 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.36 Fri Mar 10 00:34:51 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 10 01:13:32 2006 @@ -482,128 +482,128 @@ // Reserve entries in the vector for each of the SUnits we are creating. This // ensure that reallocation of the vector won't happen, so SUnit*'s won't get // invalidated. - SUnits.reserve(NodeCount); + SUnits.reserve(std::distance(DAG.allnodes_begin(), DAG.allnodes_end())); const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); - // Pass 1: create the SUnit's. - for (unsigned i = 0, NC = NodeCount; i < NC; i++) { - NodeInfo *NI = &Info[i]; - SDNode *N = NI->Node; - if (isPassiveNode(N)) + for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(), + E = DAG.allnodes_end(); NI != E; ++NI) { + if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. continue; + + // If this node has already been processed, stop now. + if (SUnitMap[NI]) continue; + + SUnit *NodeSUnit = NewSUnit(NI); - SUnit *SU; - if (NI->isInGroup()) { - if (NI != NI->Group->getBottom()) // Bottom up, so only look at bottom - continue; // node of the NodeGroup - - SU = NewSUnit(N); - // Find the flagged nodes. - SDOperand FlagOp = N->getOperand(N->getNumOperands() - 1); - SDNode *Flag = FlagOp.Val; - unsigned ResNo = FlagOp.ResNo; - while (Flag->getValueType(ResNo) == MVT::Flag) { - NodeInfo *FNI = getNI(Flag); - assert(FNI->Group == NI->Group); - SU->FlaggedNodes.insert(SU->FlaggedNodes.begin(), Flag); - SUnitMap[Flag] = SU; - - FlagOp = Flag->getOperand(Flag->getNumOperands() - 1); - Flag = FlagOp.Val; - ResNo = FlagOp.ResNo; - } - } else { - SU = NewSUnit(N); + // See if anything is flagged to this node, if so, add them to flagged + // nodes. Nodes can have at most one flag input and one flag output. Flags + // are required the be the last operand and result of a node. + + // Scan up, adding flagged preds to FlaggedNodes. + SDNode *N = NI; + while (N->getNumOperands() && + N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { + N = N->getOperand(N->getNumOperands()-1).Val; + NodeSUnit->FlaggedNodes.push_back(N); + SUnitMap[N] = NodeSUnit; + } + + // Scan down, adding this node and any flagged succs to FlaggedNodes if they + // have a user of the flag operand. + N = NI; + while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { + SDOperand FlagVal(N, N->getNumValues()-1); + + // There are either zero or one users of the Flag result. + bool HasFlagUse = false; + for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); + UI != E; ++UI) + if (FlagVal.isOperand(*UI)) { + HasFlagUse = true; + NodeSUnit->FlaggedNodes.push_back(N); + SUnitMap[N] = NodeSUnit; + N = *UI; + break; + } + if (!HasFlagUse) break; } - SUnitMap[N] = SU; - + + // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. + // Update the SUnit + NodeSUnit->Node = N; + SUnitMap[N] = NodeSUnit; + // Compute the latency for the node. We use the sum of the latencies for // all nodes flagged together into this SUnit. if (InstrItins.isEmpty()) { // No latency information. - SU->Latency = 1; + NodeSUnit->Latency = 1; } else { - SU->Latency = 0; + NodeSUnit->Latency = 0; if (N->isTargetOpcode()) { unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode()); InstrStage *S = InstrItins.begin(SchedClass); InstrStage *E = InstrItins.end(SchedClass); for (; S != E; ++S) - SU->Latency += S->Cycles; + NodeSUnit->Latency += S->Cycles; } - for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) { - SDNode *FNode = SU->FlaggedNodes[i]; + for (unsigned i = 0, e = NodeSUnit->FlaggedNodes.size(); i != e; ++i) { + SDNode *FNode = NodeSUnit->FlaggedNodes[i]; if (FNode->isTargetOpcode()) { unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode()); InstrStage *S = InstrItins.begin(SchedClass); InstrStage *E = InstrItins.end(SchedClass); for (; S != E; ++S) - SU->Latency += S->Cycles; + NodeSUnit->Latency += S->Cycles; } } } } // Pass 2: add the preds, succs, etc. - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - SUnit *SU = &SUnits[i]; - SDNode *N = SU->Node; - NodeInfo *NI = getNI(N); + for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { + SUnit *SU = &SUnits[su]; + SDNode *MainNode = SU->Node; - if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode())) + if (MainNode->isTargetOpcode() && + TII->isTwoAddrInstr(MainNode->getTargetOpcode())) SU->isTwoAddress = true; - if (NI->isInGroup()) { - // Find all predecessors (of the group). - NodeGroupOpIterator NGOI(NI); - while (!NGOI.isEnd()) { - SDOperand Op = NGOI.next(); - SDNode *OpN = Op.Val; - MVT::ValueType VT = OpN->getValueType(Op.ResNo); - NodeInfo *OpNI = getNI(OpN); - if (OpNI->Group != NI->Group && !isPassiveNode(OpN)) { - assert(VT != MVT::Flag); - SUnit *OpSU = SUnitMap[OpN]; - if (VT == MVT::Other) { - if (SU->ChainPreds.insert(OpSU).second) - SU->NumChainPredsLeft++; - if (OpSU->ChainSuccs.insert(SU).second) - OpSU->NumChainSuccsLeft++; - } else { - if (SU->Preds.insert(OpSU).second) - SU->NumPredsLeft++; - if (OpSU->Succs.insert(SU).second) - OpSU->NumSuccsLeft++; - } - } - } - } else { - // Find node predecessors. - for (unsigned j = 0, e = N->getNumOperands(); j != e; j++) { - SDOperand Op = N->getOperand(j); - SDNode *OpN = Op.Val; - MVT::ValueType VT = OpN->getValueType(Op.ResNo); - if (!isPassiveNode(OpN)) { - assert(VT != MVT::Flag); - SUnit *OpSU = SUnitMap[OpN]; - if (VT == MVT::Other) { - if (SU->ChainPreds.insert(OpSU).second) - SU->NumChainPredsLeft++; - if (OpSU->ChainSuccs.insert(SU).second) - OpSU->NumChainSuccsLeft++; - } else { - if (SU->Preds.insert(OpSU).second) - SU->NumPredsLeft++; - if (OpSU->Succs.insert(SU).second) - OpSU->NumSuccsLeft++; - if (j == 0 && SU->isTwoAddress) - OpSU->isDefNUseOperand = true; - } + // Find all predecessors and successors of the group. + // Temporarily add N to make code simpler. + SU->FlaggedNodes.push_back(MainNode); + + for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { + SDNode *N = SU->FlaggedNodes[n]; + + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDNode *OpN = N->getOperand(i).Val; + if (isPassiveNode(OpN)) continue; // Not scheduled. + SUnit *OpSU = SUnitMap[OpN]; + assert(OpSU && "Node has no SUnit!"); + if (OpSU == SU) continue; // In the same group. + + MVT::ValueType OpVT = N->getOperand(i).getValueType(); + assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); + + if (OpVT == MVT::Other) { + if (SU->ChainPreds.insert(OpSU).second) + SU->NumChainPredsLeft++; + if (OpSU->ChainSuccs.insert(SU).second) + OpSU->NumChainSuccsLeft++; + } else { + if (SU->Preds.insert(OpSU).second) + SU->NumPredsLeft++; + if (OpSU->Succs.insert(SU).second) + OpSU->NumSuccsLeft++; } } } + // Remove MainNode from FlaggedNodes again. + SU->FlaggedNodes.pop_back(); + DEBUG(SU->dumpAll(&DAG)); } } From lattner at cs.uiuc.edu Fri Mar 10 01:16:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:16:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603100716.BAA12252@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.37 -> 1.38 --- Log message: no need to build groups anymore --- Diffs of the changes: (+0 -2) ScheduleDAGList.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.37 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.38 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.37 Fri Mar 10 01:13:32 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 10 01:15:58 2006 @@ -642,8 +642,6 @@ // Set up minimum info for scheduling PrepareNodeInfo(); - // Construct node groups for flagged nodes - IdentifyGroups(); // Build scheduling units. BuildSchedUnits(); From lattner at cs.uiuc.edu Fri Mar 10 01:24:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:24:57 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100724.BAA12370@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.16 -> 1.17 --- Log message: Store VRBase in a map, not in NodeInfo. --- Diffs of the changes: (+5 -12) ScheduleDAG.h | 17 +++++------------ 1 files changed, 5 insertions(+), 12 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.16 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.17 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.16 Fri Mar 10 00:30:11 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 01:24:45 2006 @@ -151,7 +151,6 @@ bool IsStore : 1; // Is memory store unsigned Slot; // Node's time slot NodeGroup *Group; // Grouping information - unsigned VRBase; // Virtual register base #ifndef NDEBUG unsigned Preorder; // Index before scheduling #endif @@ -166,7 +165,6 @@ , IsCall(false) , Slot(0) , Group(NULL) - , VRBase(0) #ifndef NDEBUG , Preorder(0) #endif @@ -326,14 +324,6 @@ /// NodeInfo *getNI(SDNode *Node) { return Map[Node]; } - /// getVR - Returns the virtual register number of the node. - /// - unsigned getVR(SDOperand Op) { - NodeInfo *NI = getNI(Op.Val); - assert(NI->VRBase != 0 && "Node emitted out of order - late"); - return NI->VRBase + Op.ResNo; - } - /// isPassiveNode - Return true if the node is a non-scheduled leaf. /// static bool isPassiveNode(SDNode *Node) { @@ -348,8 +338,10 @@ } /// EmitNode - Generate machine code for an node and needed dependencies. + /// VRBaseMap contains, for each already emitted node, the first virtual + /// register number for the results of the node. /// - void EmitNode(NodeInfo *NI); + void EmitNode(NodeInfo *NI, std::map &VRBaseMap); /// EmitNoop - Emit a noop instruction. /// @@ -381,7 +373,8 @@ private: void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, - const TargetInstrDescriptor *II); + const TargetInstrDescriptor *II, + std::map &VRBaseMap); void AddToGroup(NodeInfo *D, NodeInfo *U); protected: From lattner at cs.uiuc.edu Fri Mar 10 01:25:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:25:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp Message-ID: <200603100725.BAA12406@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.74 -> 1.75 ScheduleDAGList.cpp updated: 1.38 -> 1.39 --- Log message: Move the VRBase field from NodeInfo to being a separate, explicit, map. --- Diffs of the changes: (+27 -13) ScheduleDAG.cpp | 35 ++++++++++++++++++++++++----------- ScheduleDAGList.cpp | 5 +++-- 2 files changed, 27 insertions(+), 13 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.74 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.75 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.74 Fri Mar 10 00:34:51 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Mar 10 01:25:12 2006 @@ -110,13 +110,23 @@ return ResultReg; } +/// getVR - Return the virtual register corresponding to the specified result +/// of the specified node. +static unsigned getVR(SDOperand Op, std::map &VRBaseMap) { + std::map::iterator I = VRBaseMap.find(Op.Val); + assert(I != VRBaseMap.end() && "Node emitted out of order - late"); + return I->second + Op.ResNo; +} + + /// AddOperand - Add the specified operand to the specified machine instr. II /// specifies the instruction information for the node, and IIOpNum is the /// operand number (in the II) that we are adding. IIOpNum and II are used for /// assertions only. void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, - const TargetInstrDescriptor *II) { + const TargetInstrDescriptor *II, + std::map &VRBaseMap) { if (Op.isTargetOpcode()) { // Note that this case is redundant with the final else block, but we // include it because it is the most common and it makes the logic @@ -126,7 +136,7 @@ "Chain and flag operands should occur at end of operand list!"); // Get/emit the operand. - unsigned VReg = getVR(Op); + unsigned VReg = getVR(Op, VRBaseMap); MI->addRegOperand(VReg, MachineOperand::Use); // Verify that it is right. @@ -174,7 +184,7 @@ assert(Op.getValueType() != MVT::Other && Op.getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); - unsigned VReg = getVR(Op); + unsigned VReg = getVR(Op, VRBaseMap); MI->addRegOperand(VReg, MachineOperand::Use); // Verify that it is right. @@ -192,7 +202,8 @@ /// EmitNode - Generate machine code for an node and needed dependencies. /// -void ScheduleDAG::EmitNode(NodeInfo *NI) { +void ScheduleDAG::EmitNode(NodeInfo *NI, + std::map &VRBaseMap) { unsigned VRBase = 0; // First virtual register for node SDNode *Node = NI->Node; @@ -240,7 +251,7 @@ // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. for (unsigned i = 0; i != NodeOperands; ++i) - AddOperand(MI, Node->getOperand(i), i+NumResults, &II); + AddOperand(MI, Node->getOperand(i), i+NumResults, &II, VRBaseMap); // Now that we have emitted all operands, emit this instruction itself. if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { @@ -259,7 +270,7 @@ case ISD::TokenFactor: break; case ISD::CopyToReg: { - unsigned InReg = getVR(Node->getOperand(2)); + unsigned InReg = getVR(Node->getOperand(2), VRBaseMap); unsigned DestReg = cast(Node->getOperand(1))->getReg(); if (InReg != DestReg) // Coallesced away the copy? MRI->copyRegToReg(*BB, BB->end(), DestReg, InReg, @@ -357,7 +368,7 @@ // The addressing mode has been selected, just add all of the // operands to the machine instruction. for (; NumVals; --NumVals, ++i) - AddOperand(MI, Node->getOperand(i), 0, 0); + AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap); break; } } @@ -366,8 +377,8 @@ } } - assert(NI->VRBase == 0 && "Node emitted out of order - early"); - NI->VRBase = VRBase; + assert(!VRBaseMap.count(Node) && "Node emitted out of order - early"); + VRBaseMap[Node] = VRBase; } void ScheduleDAG::EmitNoop() { @@ -377,15 +388,17 @@ /// EmitAll - Emit all nodes in schedule sorted order. /// void ScheduleDAG::EmitAll() { + std::map VRBaseMap; + // For each node in the ordering for (unsigned i = 0, N = Ordering.size(); i < N; i++) { // Get the scheduling info NodeInfo *NI = Ordering[i]; if (NI->isInGroup()) { NodeGroupIterator NGI(Ordering[i]); - while (NodeInfo *NI = NGI.next()) EmitNode(NI); + while (NodeInfo *NI = NGI.next()) EmitNode(NI, VRBaseMap); } else { - EmitNode(NI); + EmitNode(NI, VRBaseMap); } } } Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.38 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.39 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.38 Fri Mar 10 01:15:58 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 10 01:25:12 2006 @@ -610,13 +610,14 @@ /// EmitSchedule - Emit the machine code in scheduled order. void ScheduleDAGList::EmitSchedule() { + std::map VRBaseMap; for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) { for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) { SDNode *N = SU->FlaggedNodes[j]; - EmitNode(getNI(N)); + EmitNode(getNI(N), VRBaseMap); } - EmitNode(getNI(SU->Node)); + EmitNode(getNI(SU->Node), VRBaseMap); } else { // Null SUnit* is a noop. EmitNoop(); From lattner at cs.uiuc.edu Fri Mar 10 01:28:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:28:33 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100728.BAA12480@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.17 -> 1.18 --- Log message: Make EmitNode take a SDNode instead of a NodeInfo* --- Diffs of the changes: (+1 -1) ScheduleDAG.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.17 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.18 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.17 Fri Mar 10 01:24:45 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 01:28:21 2006 @@ -341,7 +341,7 @@ /// VRBaseMap contains, for each already emitted node, the first virtual /// register number for the results of the node. /// - void EmitNode(NodeInfo *NI, std::map &VRBaseMap); + void EmitNode(SDNode *Node, std::map &VRBaseMap); /// EmitNoop - Emit a noop instruction. /// From lattner at cs.uiuc.edu Fri Mar 10 01:28:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:28:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp Message-ID: <200603100728.BAA12515@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.75 -> 1.76 ScheduleDAGList.cpp updated: 1.39 -> 1.40 --- Log message: Make EmitNode take a SDNode instead of a NodeInfo* --- Diffs of the changes: (+6 -12) ScheduleDAG.cpp | 7 +++---- ScheduleDAGList.cpp | 11 +++-------- 2 files changed, 6 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.75 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.76 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.75 Fri Mar 10 01:25:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Mar 10 01:28:36 2006 @@ -202,10 +202,9 @@ /// EmitNode - Generate machine code for an node and needed dependencies. /// -void ScheduleDAG::EmitNode(NodeInfo *NI, +void ScheduleDAG::EmitNode(SDNode *Node, std::map &VRBaseMap) { unsigned VRBase = 0; // First virtual register for node - SDNode *Node = NI->Node; // If machine instruction if (Node->isTargetOpcode()) { @@ -396,9 +395,9 @@ NodeInfo *NI = Ordering[i]; if (NI->isInGroup()) { NodeGroupIterator NGI(Ordering[i]); - while (NodeInfo *NI = NGI.next()) EmitNode(NI, VRBaseMap); + while (NodeInfo *NI = NGI.next()) EmitNode(NI->Node, VRBaseMap); } else { - EmitNode(NI, VRBaseMap); + EmitNode(NI->Node, VRBaseMap); } } } Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.39 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.40 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.39 Fri Mar 10 01:25:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 10 01:28:36 2006 @@ -613,11 +613,9 @@ std::map VRBaseMap; for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) { - for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) { - SDNode *N = SU->FlaggedNodes[j]; - EmitNode(getNI(N), VRBaseMap); - } - EmitNode(getNI(SU->Node), VRBaseMap); + for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) + EmitNode(SU->FlaggedNodes[j], VRBaseMap); + EmitNode(SU->Node, VRBaseMap); } else { // Null SUnit* is a noop. EmitNoop(); @@ -641,9 +639,6 @@ void ScheduleDAGList::Schedule() { DEBUG(std::cerr << "********** List Scheduling **********\n"); - // Set up minimum info for scheduling - PrepareNodeInfo(); - // Build scheduling units. BuildSchedUnits(); From lattner at cs.uiuc.edu Fri Mar 10 01:35:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:35:22 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100735.BAA12649@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.18 -> 1.19 --- Log message: move some simple scheduler methods into the simple scheduler --- Diffs of the changes: (+0 -29) ScheduleDAG.h | 29 ----------------------------- 1 files changed, 29 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.18 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.19 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.18 Fri Mar 10 01:28:21 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 01:35:10 2006 @@ -347,44 +347,15 @@ /// void EmitNoop(); - /// EmitAll - Emit all nodes in schedule sorted order. - /// - void EmitAll(); /// Schedule - Order nodes according to selected style. /// virtual void Schedule() {} - /// printNI - Print node info. - /// - void printNI(std::ostream &O, NodeInfo *NI) const; - - /// printChanges - Hilight changes in order caused by scheduling. - /// - void printChanges(unsigned Index) const; - - /// print - Print ordering to specified output stream. - /// - void print(std::ostream &O) const; - - void dump(const char *tag) const; - - virtual void dump() const; - private: void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, const TargetInstrDescriptor *II, std::map &VRBaseMap); - - void AddToGroup(NodeInfo *D, NodeInfo *U); -protected: - /// PrepareNodeInfo - Set up the basic minimum node info for scheduling. - /// - void PrepareNodeInfo(); - - /// IdentifyGroups - Put flagged nodes into groups. - /// - void IdentifyGroups(); }; /// createSimpleDAGScheduler - This creates a simple two pass instruction From lattner at cs.uiuc.edu Fri Mar 10 01:35:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:35:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGSimple.cpp Message-ID: <200603100735.BAA12658@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.76 -> 1.77 ScheduleDAGSimple.cpp updated: 1.7 -> 1.8 --- Log message: move some simple scheduler methods into the simple scheduler --- Diffs of the changes: (+266 -235) ScheduleDAG.cpp | 235 -------------------------------------------- ScheduleDAGSimple.cpp | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 235 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.76 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.77 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.76 Fri Mar 10 01:28:36 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Mar 10 01:35:21 2006 @@ -52,47 +52,6 @@ return N; } -/// PrepareNodeInfo - Set up the basic minimum node info for scheduling. -/// -void ScheduleDAG::PrepareNodeInfo() { - // Allocate node information - Info = new NodeInfo[NodeCount]; - - unsigned i = 0; - for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), - E = DAG.allnodes_end(); I != E; ++I, ++i) { - // Fast reference to node schedule info - NodeInfo* NI = &Info[i]; - // Set up map - Map[I] = NI; - // Set node - NI->Node = I; - // Set pending visit count - NI->setPending(I->use_size()); - } -} - -/// IdentifyGroups - Put flagged nodes into groups. -/// -void ScheduleDAG::IdentifyGroups() { - for (unsigned i = 0, N = NodeCount; i < N; i++) { - NodeInfo* NI = &Info[i]; - SDNode *Node = NI->Node; - - // For each operand (in reverse to only look at flags) - for (unsigned N = Node->getNumOperands(); 0 < N--;) { - // Get operand - SDOperand Op = Node->getOperand(N); - // No more flags to walk - if (Op.getValueType() != MVT::Flag) break; - // Add to node group - AddToGroup(getNI(Op.Val), NI); - // Let everyone else know - HasGroups = true; - } - } -} - static unsigned CreateVirtualRegisters(MachineInstr *MI, unsigned NumResults, SSARegMap *RegMap, @@ -384,122 +343,6 @@ TII->insertNoop(*BB, BB->end()); } -/// EmitAll - Emit all nodes in schedule sorted order. -/// -void ScheduleDAG::EmitAll() { - std::map VRBaseMap; - - // For each node in the ordering - for (unsigned i = 0, N = Ordering.size(); i < N; i++) { - // Get the scheduling info - NodeInfo *NI = Ordering[i]; - if (NI->isInGroup()) { - NodeGroupIterator NGI(Ordering[i]); - while (NodeInfo *NI = NGI.next()) EmitNode(NI->Node, VRBaseMap); - } else { - EmitNode(NI->Node, VRBaseMap); - } - } -} - -/// isFlagDefiner - Returns true if the node defines a flag result. -static bool isFlagDefiner(SDNode *A) { - unsigned N = A->getNumValues(); - return N && A->getValueType(N - 1) == MVT::Flag; -} - -/// isFlagUser - Returns true if the node uses a flag result. -/// -static bool isFlagUser(SDNode *A) { - unsigned N = A->getNumOperands(); - return N && A->getOperand(N - 1).getValueType() == MVT::Flag; -} - -/// printNI - Print node info. -/// -void ScheduleDAG::printNI(std::ostream &O, NodeInfo *NI) const { -#ifndef NDEBUG - SDNode *Node = NI->Node; - O << " " - << std::hex << Node << std::dec - << ", Lat=" << NI->Latency - << ", Slot=" << NI->Slot - << ", ARITY=(" << Node->getNumOperands() << "," - << Node->getNumValues() << ")" - << " " << Node->getOperationName(&DAG); - if (isFlagDefiner(Node)) O << "<#"; - if (isFlagUser(Node)) O << ">#"; -#endif -} - -/// printChanges - Hilight changes in order caused by scheduling. -/// -void ScheduleDAG::printChanges(unsigned Index) const { -#ifndef NDEBUG - // Get the ordered node count - unsigned N = Ordering.size(); - // Determine if any changes - unsigned i = 0; - for (; i < N; i++) { - NodeInfo *NI = Ordering[i]; - if (NI->Preorder != i) break; - } - - if (i < N) { - std::cerr << Index << ". New Ordering\n"; - - for (i = 0; i < N; i++) { - NodeInfo *NI = Ordering[i]; - std::cerr << " " << NI->Preorder << ". "; - printNI(std::cerr, NI); - std::cerr << "\n"; - if (NI->isGroupDominator()) { - NodeGroup *Group = NI->Group; - for (NIIterator NII = Group->group_begin(), E = Group->group_end(); - NII != E; NII++) { - std::cerr << " "; - printNI(std::cerr, *NII); - std::cerr << "\n"; - } - } - } - } else { - std::cerr << Index << ". No Changes\n"; - } -#endif -} - -/// print - Print ordering to specified output stream. -/// -void ScheduleDAG::print(std::ostream &O) const { -#ifndef NDEBUG - using namespace std; - O << "Ordering\n"; - for (unsigned i = 0, N = Ordering.size(); i < N; i++) { - NodeInfo *NI = Ordering[i]; - printNI(O, NI); - O << "\n"; - if (NI->isGroupDominator()) { - NodeGroup *Group = NI->Group; - for (NIIterator NII = Group->group_begin(), E = Group->group_end(); - NII != E; NII++) { - O << " "; - printNI(O, *NII); - O << "\n"; - } - } - } -#endif -} - -void ScheduleDAG::dump(const char *tag) const { - std::cerr << tag; dump(); -} - -void ScheduleDAG::dump() const { - print(std::cerr); -} - /// Run - perform scheduling. /// MachineBasicBlock *ScheduleDAG::Run() { @@ -516,81 +359,3 @@ } -/// CountInternalUses - Returns the number of edges between the two nodes. -/// -static unsigned CountInternalUses(NodeInfo *D, NodeInfo *U) { - unsigned N = 0; - for (unsigned M = U->Node->getNumOperands(); 0 < M--;) { - SDOperand Op = U->Node->getOperand(M); - if (Op.Val == D->Node) N++; - } - - return N; -} - -//===----------------------------------------------------------------------===// -/// Add - Adds a definer and user pair to a node group. -/// -void ScheduleDAG::AddToGroup(NodeInfo *D, NodeInfo *U) { - // Get current groups - NodeGroup *DGroup = D->Group; - NodeGroup *UGroup = U->Group; - // If both are members of groups - if (DGroup && UGroup) { - // There may have been another edge connecting - if (DGroup == UGroup) return; - // Add the pending users count - DGroup->addPending(UGroup->getPending()); - // For each member of the users group - NodeGroupIterator UNGI(U); - while (NodeInfo *UNI = UNGI.next() ) { - // Change the group - UNI->Group = DGroup; - // For each member of the definers group - NodeGroupIterator DNGI(D); - while (NodeInfo *DNI = DNGI.next() ) { - // Remove internal edges - DGroup->addPending(-CountInternalUses(DNI, UNI)); - } - } - // Merge the two lists - DGroup->group_insert(DGroup->group_end(), - UGroup->group_begin(), UGroup->group_end()); - } else if (DGroup) { - // Make user member of definers group - U->Group = DGroup; - // Add users uses to definers group pending - DGroup->addPending(U->Node->use_size()); - // For each member of the definers group - NodeGroupIterator DNGI(D); - while (NodeInfo *DNI = DNGI.next() ) { - // Remove internal edges - DGroup->addPending(-CountInternalUses(DNI, U)); - } - DGroup->group_push_back(U); - } else if (UGroup) { - // Make definer member of users group - D->Group = UGroup; - // Add definers uses to users group pending - UGroup->addPending(D->Node->use_size()); - // For each member of the users group - NodeGroupIterator UNGI(U); - while (NodeInfo *UNI = UNGI.next() ) { - // Remove internal edges - UGroup->addPending(-CountInternalUses(D, UNI)); - } - UGroup->group_insert(UGroup->group_begin(), D); - } else { - D->Group = U->Group = DGroup = new NodeGroup(); - DGroup->addPending(D->Node->use_size() + U->Node->use_size() - - CountInternalUses(D, U)); - DGroup->group_push_back(D); - DGroup->group_push_back(U); - - if (HeadNG == NULL) - HeadNG = DGroup; - if (TailNG != NULL) - TailNG->Next = DGroup; - TailNG = DGroup; - } -} Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.7 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.8 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.7 Fri Mar 10 00:34:51 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Fri Mar 10 01:35:21 2006 @@ -20,6 +20,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" #include +#include using namespace llvm; namespace { @@ -215,6 +216,35 @@ bool isWeakDependency(NodeInfo *A, NodeInfo *B); void ScheduleBackward(); void ScheduleForward(); + + void AddToGroup(NodeInfo *D, NodeInfo *U); + /// PrepareNodeInfo - Set up the basic minimum node info for scheduling. + /// + void PrepareNodeInfo(); + + /// IdentifyGroups - Put flagged nodes into groups. + /// + void IdentifyGroups(); + + /// print - Print ordering to specified output stream. + /// + void print(std::ostream &O) const; + + void dump(const char *tag) const; + + virtual void dump() const; + + /// EmitAll - Emit all nodes in schedule sorted order. + /// + void EmitAll(); + + /// printNI - Print node info. + /// + void printNI(std::ostream &O, NodeInfo *NI) const; + + /// printChanges - Hilight changes in order caused by scheduling. + /// + void printChanges(unsigned Index) const; }; //===----------------------------------------------------------------------===// @@ -239,6 +269,242 @@ //===----------------------------------------------------------------------===// +/// PrepareNodeInfo - Set up the basic minimum node info for scheduling. +/// +void ScheduleDAGSimple::PrepareNodeInfo() { + // Allocate node information + Info = new NodeInfo[NodeCount]; + + unsigned i = 0; + for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), + E = DAG.allnodes_end(); I != E; ++I, ++i) { + // Fast reference to node schedule info + NodeInfo* NI = &Info[i]; + // Set up map + Map[I] = NI; + // Set node + NI->Node = I; + // Set pending visit count + NI->setPending(I->use_size()); + } +} + +/// IdentifyGroups - Put flagged nodes into groups. +/// +void ScheduleDAGSimple::IdentifyGroups() { + for (unsigned i = 0, N = NodeCount; i < N; i++) { + NodeInfo* NI = &Info[i]; + SDNode *Node = NI->Node; + + // For each operand (in reverse to only look at flags) + for (unsigned N = Node->getNumOperands(); 0 < N--;) { + // Get operand + SDOperand Op = Node->getOperand(N); + // No more flags to walk + if (Op.getValueType() != MVT::Flag) break; + // Add to node group + AddToGroup(getNI(Op.Val), NI); + // Let everyone else know + HasGroups = true; + } + } +} + +/// CountInternalUses - Returns the number of edges between the two nodes. +/// +static unsigned CountInternalUses(NodeInfo *D, NodeInfo *U) { + unsigned N = 0; + for (unsigned M = U->Node->getNumOperands(); 0 < M--;) { + SDOperand Op = U->Node->getOperand(M); + if (Op.Val == D->Node) N++; + } + + return N; +} + +//===----------------------------------------------------------------------===// +/// Add - Adds a definer and user pair to a node group. +/// +void ScheduleDAGSimple::AddToGroup(NodeInfo *D, NodeInfo *U) { + // Get current groups + NodeGroup *DGroup = D->Group; + NodeGroup *UGroup = U->Group; + // If both are members of groups + if (DGroup && UGroup) { + // There may have been another edge connecting + if (DGroup == UGroup) return; + // Add the pending users count + DGroup->addPending(UGroup->getPending()); + // For each member of the users group + NodeGroupIterator UNGI(U); + while (NodeInfo *UNI = UNGI.next() ) { + // Change the group + UNI->Group = DGroup; + // For each member of the definers group + NodeGroupIterator DNGI(D); + while (NodeInfo *DNI = DNGI.next() ) { + // Remove internal edges + DGroup->addPending(-CountInternalUses(DNI, UNI)); + } + } + // Merge the two lists + DGroup->group_insert(DGroup->group_end(), + UGroup->group_begin(), UGroup->group_end()); + } else if (DGroup) { + // Make user member of definers group + U->Group = DGroup; + // Add users uses to definers group pending + DGroup->addPending(U->Node->use_size()); + // For each member of the definers group + NodeGroupIterator DNGI(D); + while (NodeInfo *DNI = DNGI.next() ) { + // Remove internal edges + DGroup->addPending(-CountInternalUses(DNI, U)); + } + DGroup->group_push_back(U); + } else if (UGroup) { + // Make definer member of users group + D->Group = UGroup; + // Add definers uses to users group pending + UGroup->addPending(D->Node->use_size()); + // For each member of the users group + NodeGroupIterator UNGI(U); + while (NodeInfo *UNI = UNGI.next() ) { + // Remove internal edges + UGroup->addPending(-CountInternalUses(D, UNI)); + } + UGroup->group_insert(UGroup->group_begin(), D); + } else { + D->Group = U->Group = DGroup = new NodeGroup(); + DGroup->addPending(D->Node->use_size() + U->Node->use_size() - + CountInternalUses(D, U)); + DGroup->group_push_back(D); + DGroup->group_push_back(U); + + if (HeadNG == NULL) + HeadNG = DGroup; + if (TailNG != NULL) + TailNG->Next = DGroup; + TailNG = DGroup; + } +} + + +/// print - Print ordering to specified output stream. +/// +void ScheduleDAGSimple::print(std::ostream &O) const { +#ifndef NDEBUG + O << "Ordering\n"; + for (unsigned i = 0, N = Ordering.size(); i < N; i++) { + NodeInfo *NI = Ordering[i]; + printNI(O, NI); + O << "\n"; + if (NI->isGroupDominator()) { + NodeGroup *Group = NI->Group; + for (NIIterator NII = Group->group_begin(), E = Group->group_end(); + NII != E; NII++) { + O << " "; + printNI(O, *NII); + O << "\n"; + } + } + } +#endif +} + +void ScheduleDAGSimple::dump(const char *tag) const { + std::cerr << tag; dump(); +} + +void ScheduleDAGSimple::dump() const { + print(std::cerr); +} + + +/// EmitAll - Emit all nodes in schedule sorted order. +/// +void ScheduleDAGSimple::EmitAll() { + std::map VRBaseMap; + + // For each node in the ordering + for (unsigned i = 0, N = Ordering.size(); i < N; i++) { + // Get the scheduling info + NodeInfo *NI = Ordering[i]; + if (NI->isInGroup()) { + NodeGroupIterator NGI(Ordering[i]); + while (NodeInfo *NI = NGI.next()) EmitNode(NI->Node, VRBaseMap); + } else { + EmitNode(NI->Node, VRBaseMap); + } + } +} + +/// isFlagDefiner - Returns true if the node defines a flag result. +static bool isFlagDefiner(SDNode *A) { + unsigned N = A->getNumValues(); + return N && A->getValueType(N - 1) == MVT::Flag; +} + +/// isFlagUser - Returns true if the node uses a flag result. +/// +static bool isFlagUser(SDNode *A) { + unsigned N = A->getNumOperands(); + return N && A->getOperand(N - 1).getValueType() == MVT::Flag; +} + +/// printNI - Print node info. +/// +void ScheduleDAGSimple::printNI(std::ostream &O, NodeInfo *NI) const { +#ifndef NDEBUG + SDNode *Node = NI->Node; + O << " " + << std::hex << Node << std::dec + << ", Lat=" << NI->Latency + << ", Slot=" << NI->Slot + << ", ARITY=(" << Node->getNumOperands() << "," + << Node->getNumValues() << ")" + << " " << Node->getOperationName(&DAG); + if (isFlagDefiner(Node)) O << "<#"; + if (isFlagUser(Node)) O << ">#"; +#endif +} + +/// printChanges - Hilight changes in order caused by scheduling. +/// +void ScheduleDAGSimple::printChanges(unsigned Index) const { +#ifndef NDEBUG + // Get the ordered node count + unsigned N = Ordering.size(); + // Determine if any changes + unsigned i = 0; + for (; i < N; i++) { + NodeInfo *NI = Ordering[i]; + if (NI->Preorder != i) break; + } + + if (i < N) { + std::cerr << Index << ". New Ordering\n"; + + for (i = 0; i < N; i++) { + NodeInfo *NI = Ordering[i]; + std::cerr << " " << NI->Preorder << ". "; + printNI(std::cerr, NI); + std::cerr << "\n"; + if (NI->isGroupDominator()) { + NodeGroup *Group = NI->Group; + for (NIIterator NII = Group->group_begin(), E = Group->group_end(); + NII != E; NII++) { + std::cerr << " "; + printNI(std::cerr, *NII); + std::cerr << "\n"; + } + } + } + } else { + std::cerr << Index << ". No Changes\n"; + } +#endif +} //===----------------------------------------------------------------------===// /// isDefiner - Return true if node A is a definer for B. From lattner at cs.uiuc.edu Fri Mar 10 01:37:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:37:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200603100737.BAA12727@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.77 -> 1.78 --- Log message: prune #includes --- Diffs of the changes: (+0 -5) ScheduleDAG.cpp | 5 ----- 1 files changed, 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.77 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.78 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.77 Fri Mar 10 01:35:21 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Mar 10 01:37:35 2006 @@ -13,18 +13,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sched" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetLowering.h" -#include "llvm/Support/Debug.h" -#include "llvm/Constant.h" -#include using namespace llvm; From lattner at cs.uiuc.edu Fri Mar 10 01:42:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:42:05 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100742.BAA12865@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.19 -> 1.20 --- Log message: Move some simple-sched-specific instance vars to the simple scheduler. --- Diffs of the changes: (+2 -23) ScheduleDAG.h | 25 ++----------------------- 1 files changed, 2 insertions(+), 23 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.19 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.20 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.19 Fri Mar 10 01:35:10 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 01:41:52 2006 @@ -284,7 +284,6 @@ class ScheduleDAG { public: - SchedHeuristics Heuristic; // Scheduling heuristic SelectionDAG &DAG; // DAG of the current basic block MachineBasicBlock *BB; // Current basic block const TargetMachine &TM; // Target processor @@ -292,38 +291,18 @@ const MRegisterInfo *MRI; // Target processor register info SSARegMap *RegMap; // Virtual/real register map MachineConstantPool *ConstPool; // Target constant pool - std::map Map; // Map nodes to info - unsigned NodeCount; // Number of nodes in DAG - bool HasGroups; // True if there are any groups - NodeInfo *Info; // Info for nodes being scheduled - NIVector Ordering; // Emit ordering of nodes - NodeGroup *HeadNG, *TailNG; // Keep track of allocated NodeGroups - ScheduleDAG(SchedHeuristics hstc, SelectionDAG &dag, MachineBasicBlock *bb, + ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm) - : Heuristic(hstc), DAG(dag), BB(bb), TM(tm), NodeCount(0), - HasGroups(false), Info(NULL), HeadNG(NULL), TailNG(NULL) {} + : DAG(dag), BB(bb), TM(tm) {} virtual ~ScheduleDAG() { - if (Info) - delete[] Info; - - NodeGroup *NG = HeadNG; - while (NG) { - NodeGroup *NextSU = NG->Next; - delete NG; - NG = NextSU; - } }; /// Run - perform scheduling. /// MachineBasicBlock *Run(); - /// getNI - Returns the node info for the specified node. - /// - NodeInfo *getNI(SDNode *Node) { return Map[Node]; } - /// isPassiveNode - Return true if the node is a non-scheduled leaf. /// static bool isPassiveNode(SDNode *Node) { From lattner at cs.uiuc.edu Fri Mar 10 01:42:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:42:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp ScheduleDAGSimple.cpp Message-ID: <200603100742.BAA12876@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.78 -> 1.79 ScheduleDAGList.cpp updated: 1.40 -> 1.41 ScheduleDAGSimple.cpp updated: 1.8 -> 1.9 --- Log message: Move some simple-sched-specific instance vars to the simple scheduler. --- Diffs of the changes: (+30 -6) ScheduleDAG.cpp | 3 --- ScheduleDAGList.cpp | 2 +- ScheduleDAGSimple.cpp | 31 +++++++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.78 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.79 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.78 Fri Mar 10 01:37:35 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Mar 10 01:42:02 2006 @@ -346,9 +346,6 @@ RegMap = BB->getParent()->getSSARegMap(); ConstPool = BB->getParent()->getConstantPool(); - // Number the nodes - NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end()); - Schedule(); return BB; } Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.40 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.41 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.40 Fri Mar 10 01:28:36 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 10 01:42:02 2006 @@ -189,7 +189,7 @@ const TargetMachine &tm, bool isbottomup, SchedulingPriorityQueue *priorityqueue, HazardRecognizer *HR) - : ScheduleDAG(listSchedulingBURR, dag, bb, tm), + : ScheduleDAG(dag, bb, tm), CurrCycle(0), isBottomUp(isbottomup), PriorityQueue(priorityqueue), HazardRec(HR) { } Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.8 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.9 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.8 Fri Mar 10 01:35:21 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Fri Mar 10 01:42:02 2006 @@ -188,24 +188,48 @@ /// class ScheduleDAGSimple : public ScheduleDAG { private: + SchedHeuristics Heuristic; // Scheduling heuristic + ResourceTally Tally; // Resource usage tally unsigned NSlots; // Total latency static const unsigned NotFound = ~0U; // Search marker + + unsigned NodeCount; // Number of nodes in DAG + std::map Map; // Map nodes to info + bool HasGroups; // True if there are any groups + NodeInfo *Info; // Info for nodes being scheduled + NIVector Ordering; // Emit ordering of nodes + NodeGroup *HeadNG, *TailNG; // Keep track of allocated NodeGroups public: // Ctor. ScheduleDAGSimple(SchedHeuristics hstc, SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm) - : ScheduleDAG(hstc, dag, bb, tm), Tally(), NSlots(0) { + : ScheduleDAG(dag, bb, tm), Heuristic(hstc), Tally(), NSlots(0), + NodeCount(0), HasGroups(false), Info(NULL), HeadNG(NULL), TailNG(NULL) { assert(&TII && "Target doesn't provide instr info?"); assert(&MRI && "Target doesn't provide register info?"); } - virtual ~ScheduleDAGSimple() {}; + virtual ~ScheduleDAGSimple() { + if (Info) + delete[] Info; + + NodeGroup *NG = HeadNG; + while (NG) { + NodeGroup *NextSU = NG->Next; + delete NG; + NG = NextSU; + } + } void Schedule(); + /// getNI - Returns the node info for the specified node. + /// + NodeInfo *getNI(SDNode *Node) { return Map[Node]; } + private: static bool isDefiner(NodeInfo *A, NodeInfo *B); void IncludeNode(NodeInfo *NI); @@ -826,6 +850,9 @@ /// Schedule - Order nodes according to selected style. /// void ScheduleDAGSimple::Schedule() { + // Number the nodes + NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end()); + // Set up minimum info for scheduling PrepareNodeInfo(); // Construct node groups for flagged nodes From lattner at cs.uiuc.edu Fri Mar 10 01:49:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:49:04 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100749.BAA12981@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.20 -> 1.21 --- Log message: Simplify the interface to the schedulers, to not pass the selected heuristic in. --- Diffs of the changes: (+4 -14) ScheduleDAG.h | 18 ++++-------------- 1 files changed, 4 insertions(+), 14 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.20 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.21 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.20 Fri Mar 10 01:41:52 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 01:48:52 2006 @@ -34,16 +34,6 @@ typedef std::vector NIVector; typedef std::vector::iterator NIIterator; - // Scheduling heuristics - enum SchedHeuristics { - defaultScheduling, // Let the target specify its preference. - noScheduling, // No scheduling, emit breadth first sequence. - simpleScheduling, // Two pass, min. critical path, max. utilization. - simpleNoItinScheduling, // Same as above exact using generic latency. - listSchedulingBURR, // Bottom up reg reduction list scheduling. - listSchedulingTD // Top-down list scheduler. - }; - /// HazardRecognizer - This determines whether or not an instruction can be /// issued this cycle, and whether or not a noop needs to be inserted to handle /// the hazard. @@ -296,8 +286,7 @@ const TargetMachine &tm) : DAG(dag), BB(bb), TM(tm) {} - virtual ~ScheduleDAG() { - }; + virtual ~ScheduleDAG() {} /// Run - perform scheduling. /// @@ -337,10 +326,11 @@ std::map &VRBaseMap); }; + ScheduleDAG *createBFS_DAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB); + /// createSimpleDAGScheduler - This creates a simple two pass instruction /// scheduler. - ScheduleDAG* createSimpleDAGScheduler(SchedHeuristics Heuristic, - SelectionDAG &DAG, + ScheduleDAG* createSimpleDAGScheduler(bool NoItins, SelectionDAG &DAG, MachineBasicBlock *BB); /// createBURRListDAGScheduler - This creates a bottom up register usage From lattner at cs.uiuc.edu Fri Mar 10 01:49:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:49:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp SelectionDAGISel.cpp Message-ID: <200603100749.BAA13016@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGSimple.cpp updated: 1.9 -> 1.10 SelectionDAGISel.cpp updated: 1.184 -> 1.185 --- Log message: Simplify the interface to the schedulers, to not pass the selected heuristicin. --- Diffs of the changes: (+28 -9) ScheduleDAGSimple.cpp | 21 +++++++++++++-------- SelectionDAGISel.cpp | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.9 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.10 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.9 Fri Mar 10 01:42:02 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Fri Mar 10 01:49:12 2006 @@ -188,8 +188,8 @@ /// class ScheduleDAGSimple : public ScheduleDAG { private: - SchedHeuristics Heuristic; // Scheduling heuristic - + bool NoSched; // Just do a BFS schedule, nothing fancy + bool NoItins; // Don't use itineraries? ResourceTally Tally; // Resource usage tally unsigned NSlots; // Total latency static const unsigned NotFound = ~0U; // Search marker @@ -204,9 +204,9 @@ public: // Ctor. - ScheduleDAGSimple(SchedHeuristics hstc, SelectionDAG &dag, + ScheduleDAGSimple(bool noSched, bool noItins, SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm) - : ScheduleDAG(dag, bb, tm), Heuristic(hstc), Tally(), NSlots(0), + : ScheduleDAG(dag, bb, tm), NoSched(noSched), NoItins(noItins), NSlots(0), NodeCount(0), HasGroups(false), Info(NULL), HeadNG(NULL), TailNG(NULL) { assert(&TII && "Target doesn't provide instr info?"); assert(&MRI && "Target doesn't provide register info?"); @@ -591,7 +591,7 @@ SDNode *Node = NI->Node; // If there are itineraries and it is a machine instruction - if (InstrItins.isEmpty() || Heuristic == simpleNoItinScheduling) { + if (InstrItins.isEmpty() || NoItins) { // If machine opcode if (Node->isTargetOpcode()) { // Get return type to guess which processing unit @@ -859,7 +859,7 @@ IdentifyGroups(); // Test to see if scheduling should occur - bool ShouldSchedule = NodeCount > 3 && Heuristic != noScheduling; + bool ShouldSchedule = NodeCount > 3 && !NoSched; // Don't waste time if is only entry and return if (ShouldSchedule) { // Get latency and resource requirements @@ -899,8 +899,13 @@ /// createSimpleDAGScheduler - This creates a simple two pass instruction /// scheduler. -llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(SchedHeuristics Heuristic, +llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(bool NoItins, SelectionDAG &DAG, MachineBasicBlock *BB) { - return new ScheduleDAGSimple(Heuristic, DAG, BB, DAG.getTarget()); + return new ScheduleDAGSimple(false, NoItins, DAG, BB, DAG.getTarget()); +} + +llvm::ScheduleDAG* llvm::createBFS_DAGScheduler(SelectionDAG &DAG, + MachineBasicBlock *BB) { + return new ScheduleDAGSimple(true, false, DAG, BB, DAG.getTarget()); } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.184 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.185 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.184 Thu Mar 9 14:02:42 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 10 01:49:12 2006 @@ -57,6 +57,16 @@ static const bool ViewSchedDAGs = 0; #endif +// Scheduling heuristics +enum SchedHeuristics { + defaultScheduling, // Let the target specify its preference. + noScheduling, // No scheduling, emit breadth first sequence. + simpleScheduling, // Two pass, min. critical path, max. utilization. + simpleNoItinScheduling, // Same as above exact using generic latency. + listSchedulingBURR, // Bottom up reg reduction list scheduling. + listSchedulingTD // Top-down list scheduler. +}; + namespace { cl::opt ISHeuristic( @@ -2444,9 +2454,13 @@ SL = createBURRListDAGScheduler(DAG, BB); break; case noScheduling: + SL = createBFS_DAGScheduler(DAG, BB); + break; case simpleScheduling: + SL = createSimpleDAGScheduler(false, DAG, BB); + break; case simpleNoItinScheduling: - SL = createSimpleDAGScheduler(ISHeuristic, DAG, BB); + SL = createSimpleDAGScheduler(true, DAG, BB); break; case listSchedulingBURR: SL = createBURRListDAGScheduler(DAG, BB); From lattner at cs.uiuc.edu Fri Mar 10 01:51:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:51:25 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200603100751.BAA13112@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.21 -> 1.22 --- Log message: Move simple-selector-specific types to the simple selector. --- Diffs of the changes: (+0 -201) ScheduleDAG.h | 201 ---------------------------------------------------------- 1 files changed, 201 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.21 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.22 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.21 Fri Mar 10 01:48:52 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Fri Mar 10 01:51:12 2006 @@ -29,11 +29,6 @@ class TargetInstrDescriptor; class TargetMachine; - class NodeInfo; - typedef NodeInfo *NodeInfoPtr; - typedef std::vector NIVector; - typedef std::vector::iterator NIIterator; - /// HazardRecognizer - This determines whether or not an instruction can be /// issued this cycle, and whether or not a noop needs to be inserted to handle /// the hazard. @@ -75,203 +70,7 @@ virtual void EmitNoop() { } }; - - //===--------------------------------------------------------------------===// - /// - /// Node group - This struct is used to manage flagged node groups. - /// - class NodeGroup { - public: - NodeGroup *Next; - private: - NIVector Members; // Group member nodes - NodeInfo *Dominator; // Node with highest latency - unsigned Latency; // Total latency of the group - int Pending; // Number of visits pending before - // adding to order - - public: - // Ctor. - NodeGroup() : Next(NULL), Dominator(NULL), Pending(0) {} - - // Accessors - inline void setDominator(NodeInfo *D) { Dominator = D; } - inline NodeInfo *getTop() { return Members.front(); } - inline NodeInfo *getBottom() { return Members.back(); } - inline NodeInfo *getDominator() { return Dominator; } - inline void setLatency(unsigned L) { Latency = L; } - inline unsigned getLatency() { return Latency; } - inline int getPending() const { return Pending; } - inline void setPending(int P) { Pending = P; } - inline int addPending(int I) { return Pending += I; } - - // Pass thru - inline bool group_empty() { return Members.empty(); } - inline NIIterator group_begin() { return Members.begin(); } - inline NIIterator group_end() { return Members.end(); } - inline void group_push_back(const NodeInfoPtr &NI) { - Members.push_back(NI); - } - inline NIIterator group_insert(NIIterator Pos, const NodeInfoPtr &NI) { - return Members.insert(Pos, NI); - } - inline void group_insert(NIIterator Pos, NIIterator First, - NIIterator Last) { - Members.insert(Pos, First, Last); - } - - static void Add(NodeInfo *D, NodeInfo *U); - }; - - //===--------------------------------------------------------------------===// - /// - /// NodeInfo - This struct tracks information used to schedule the a node. - /// - class NodeInfo { - private: - int Pending; // Number of visits pending before - // adding to order - public: - SDNode *Node; // DAG node - InstrStage *StageBegin; // First stage in itinerary - InstrStage *StageEnd; // Last+1 stage in itinerary - unsigned Latency; // Total cycles to complete instr - bool IsCall : 1; // Is function call - bool IsLoad : 1; // Is memory load - bool IsStore : 1; // Is memory store - unsigned Slot; // Node's time slot - NodeGroup *Group; // Grouping information -#ifndef NDEBUG - unsigned Preorder; // Index before scheduling -#endif - - // Ctor. - NodeInfo(SDNode *N = NULL) - : Pending(0) - , Node(N) - , StageBegin(NULL) - , StageEnd(NULL) - , Latency(0) - , IsCall(false) - , Slot(0) - , Group(NULL) -#ifndef NDEBUG - , Preorder(0) -#endif - {} - - // Accessors - inline bool isInGroup() const { - assert(!Group || !Group->group_empty() && "Group with no members"); - return Group != NULL; - } - inline bool isGroupDominator() const { - return isInGroup() && Group->getDominator() == this; - } - inline int getPending() const { - return Group ? Group->getPending() : Pending; - } - inline void setPending(int P) { - if (Group) Group->setPending(P); - else Pending = P; - } - inline int addPending(int I) { - if (Group) return Group->addPending(I); - else return Pending += I; - } - }; - - //===--------------------------------------------------------------------===// - /// - /// NodeGroupIterator - Iterates over all the nodes indicated by the node - /// info. If the node is in a group then iterate over the members of the - /// group, otherwise just the node info. - /// - class NodeGroupIterator { - private: - NodeInfo *NI; // Node info - NIIterator NGI; // Node group iterator - NIIterator NGE; // Node group iterator end - - public: - // Ctor. - NodeGroupIterator(NodeInfo *N) : NI(N) { - // If the node is in a group then set up the group iterator. Otherwise - // the group iterators will trip first time out. - if (N->isInGroup()) { - // get Group - NodeGroup *Group = NI->Group; - NGI = Group->group_begin(); - NGE = Group->group_end(); - // Prevent this node from being used (will be in members list - NI = NULL; - } - } - - /// next - Return the next node info, otherwise NULL. - /// - NodeInfo *next() { - // If members list - if (NGI != NGE) return *NGI++; - // Use node as the result (may be NULL) - NodeInfo *Result = NI; - // Only use once - NI = NULL; - // Return node or NULL - return Result; - } - }; - //===--------------------------------------------------------------------===// - - - //===--------------------------------------------------------------------===// - /// - /// NodeGroupOpIterator - Iterates over all the operands of a node. If the - /// node is a member of a group, this iterates over all the operands of all - /// the members of the group. - /// - class NodeGroupOpIterator { - private: - NodeInfo *NI; // Node containing operands - NodeGroupIterator GI; // Node group iterator - SDNode::op_iterator OI; // Operand iterator - SDNode::op_iterator OE; // Operand iterator end - - /// CheckNode - Test if node has more operands. If not get the next node - /// skipping over nodes that have no operands. - void CheckNode() { - // Only if operands are exhausted first - while (OI == OE) { - // Get next node info - NodeInfo *NI = GI.next(); - // Exit if nodes are exhausted - if (!NI) return; - // Get node itself - SDNode *Node = NI->Node; - // Set up the operand iterators - OI = Node->op_begin(); - OE = Node->op_end(); - } - } - - public: - // Ctor. - NodeGroupOpIterator(NodeInfo *N) - : NI(N), GI(N), OI(SDNode::op_iterator()), OE(SDNode::op_iterator()) {} - /// isEnd - Returns true when not more operands are available. - /// - inline bool isEnd() { CheckNode(); return OI == OE; } - - /// next - Returns the next available operand. - /// - inline SDOperand next() { - assert(OI != OE && - "Not checking for end of NodeGroupOpIterator correctly"); - return *OI++; - } - }; - class ScheduleDAG { public: SelectionDAG &DAG; // DAG of the current basic block From lattner at cs.uiuc.edu Fri Mar 10 01:51:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 01:51:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Message-ID: <200603100751.BAA13119@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGSimple.cpp updated: 1.10 -> 1.11 --- Log message: Move simple-selector-specific types to the simple selector. --- Diffs of the changes: (+202 -0) ScheduleDAGSimple.cpp | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 202 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.10 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.11 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.10 Fri Mar 10 01:49:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Fri Mar 10 01:51:18 2006 @@ -24,6 +24,208 @@ using namespace llvm; namespace { +class NodeInfo; +typedef NodeInfo *NodeInfoPtr; +typedef std::vector NIVector; +typedef std::vector::iterator NIIterator; + +//===--------------------------------------------------------------------===// +/// +/// Node group - This struct is used to manage flagged node groups. +/// +class NodeGroup { +public: + NodeGroup *Next; +private: + NIVector Members; // Group member nodes + NodeInfo *Dominator; // Node with highest latency + unsigned Latency; // Total latency of the group + int Pending; // Number of visits pending before + // adding to order + +public: + // Ctor. + NodeGroup() : Next(NULL), Dominator(NULL), Pending(0) {} + + // Accessors + inline void setDominator(NodeInfo *D) { Dominator = D; } + inline NodeInfo *getTop() { return Members.front(); } + inline NodeInfo *getBottom() { return Members.back(); } + inline NodeInfo *getDominator() { return Dominator; } + inline void setLatency(unsigned L) { Latency = L; } + inline unsigned getLatency() { return Latency; } + inline int getPending() const { return Pending; } + inline void setPending(int P) { Pending = P; } + inline int addPending(int I) { return Pending += I; } + + // Pass thru + inline bool group_empty() { return Members.empty(); } + inline NIIterator group_begin() { return Members.begin(); } + inline NIIterator group_end() { return Members.end(); } + inline void group_push_back(const NodeInfoPtr &NI) { + Members.push_back(NI); + } + inline NIIterator group_insert(NIIterator Pos, const NodeInfoPtr &NI) { + return Members.insert(Pos, NI); + } + inline void group_insert(NIIterator Pos, NIIterator First, + NIIterator Last) { + Members.insert(Pos, First, Last); + } + + static void Add(NodeInfo *D, NodeInfo *U); +}; + +//===--------------------------------------------------------------------===// +/// +/// NodeInfo - This struct tracks information used to schedule the a node. +/// +class NodeInfo { +private: + int Pending; // Number of visits pending before + // adding to order +public: + SDNode *Node; // DAG node + InstrStage *StageBegin; // First stage in itinerary + InstrStage *StageEnd; // Last+1 stage in itinerary + unsigned Latency; // Total cycles to complete instr + bool IsCall : 1; // Is function call + bool IsLoad : 1; // Is memory load + bool IsStore : 1; // Is memory store + unsigned Slot; // Node's time slot + NodeGroup *Group; // Grouping information +#ifndef NDEBUG + unsigned Preorder; // Index before scheduling +#endif + + // Ctor. + NodeInfo(SDNode *N = NULL) + : Pending(0) + , Node(N) + , StageBegin(NULL) + , StageEnd(NULL) + , Latency(0) + , IsCall(false) + , Slot(0) + , Group(NULL) +#ifndef NDEBUG + , Preorder(0) +#endif + {} + + // Accessors + inline bool isInGroup() const { + assert(!Group || !Group->group_empty() && "Group with no members"); + return Group != NULL; + } + inline bool isGroupDominator() const { + return isInGroup() && Group->getDominator() == this; + } + inline int getPending() const { + return Group ? Group->getPending() : Pending; + } + inline void setPending(int P) { + if (Group) Group->setPending(P); + else Pending = P; + } + inline int addPending(int I) { + if (Group) return Group->addPending(I); + else return Pending += I; + } +}; + +//===--------------------------------------------------------------------===// +/// +/// NodeGroupIterator - Iterates over all the nodes indicated by the node +/// info. If the node is in a group then iterate over the members of the +/// group, otherwise just the node info. +/// +class NodeGroupIterator { +private: + NodeInfo *NI; // Node info + NIIterator NGI; // Node group iterator + NIIterator NGE; // Node group iterator end + +public: + // Ctor. + NodeGroupIterator(NodeInfo *N) : NI(N) { + // If the node is in a group then set up the group iterator. Otherwise + // the group iterators will trip first time out. + if (N->isInGroup()) { + // get Group + NodeGroup *Group = NI->Group; + NGI = Group->group_begin(); + NGE = Group->group_end(); + // Prevent this node from being used (will be in members list + NI = NULL; + } + } + + /// next - Return the next node info, otherwise NULL. + /// + NodeInfo *next() { + // If members list + if (NGI != NGE) return *NGI++; + // Use node as the result (may be NULL) + NodeInfo *Result = NI; + // Only use once + NI = NULL; + // Return node or NULL + return Result; + } +}; +//===--------------------------------------------------------------------===// + + +//===--------------------------------------------------------------------===// +/// +/// NodeGroupOpIterator - Iterates over all the operands of a node. If the +/// node is a member of a group, this iterates over all the operands of all +/// the members of the group. +/// +class NodeGroupOpIterator { +private: + NodeInfo *NI; // Node containing operands + NodeGroupIterator GI; // Node group iterator + SDNode::op_iterator OI; // Operand iterator + SDNode::op_iterator OE; // Operand iterator end + + /// CheckNode - Test if node has more operands. If not get the next node + /// skipping over nodes that have no operands. + void CheckNode() { + // Only if operands are exhausted first + while (OI == OE) { + // Get next node info + NodeInfo *NI = GI.next(); + // Exit if nodes are exhausted + if (!NI) return; + // Get node itself + SDNode *Node = NI->Node; + // Set up the operand iterators + OI = Node->op_begin(); + OE = Node->op_end(); + } + } + +public: + // Ctor. + NodeGroupOpIterator(NodeInfo *N) + : NI(N), GI(N), OI(SDNode::op_iterator()), OE(SDNode::op_iterator()) {} + + /// isEnd - Returns true when not more operands are available. + /// + inline bool isEnd() { CheckNode(); return OI == OE; } + + /// next - Returns the next available operand. + /// + inline SDOperand next() { + assert(OI != OE && + "Not checking for end of NodeGroupOpIterator correctly"); + return *OI++; + } +}; + + //===----------------------------------------------------------------------===// /// /// BitsIterator - Provides iteration through individual bits in a bit vector. From lattner at cs.uiuc.edu Fri Mar 10 11:48:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 11:48:57 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.td Message-ID: <200603101748.LAA27467@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.td updated: 1.2 -> 1.3 --- Log message: Fix incorrect definitions of these intrinsics, which broke a bunch of stuff last night. --- Diffs of the changes: (+4 -2) Intrinsics.td | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Intrinsics.td diff -u llvm/include/llvm/Intrinsics.td:1.2 llvm/include/llvm/Intrinsics.td:1.3 --- llvm/include/llvm/Intrinsics.td:1.2 Thu Mar 9 22:17:06 2006 +++ llvm/include/llvm/Intrinsics.td Fri Mar 10 11:48:34 2006 @@ -139,8 +139,10 @@ } let Properties = [InstrNoMem] in { - def int_isunordered_f32 : Intrinsic<[llvm_float_ty, llvm_float_ty]>; - def int_isunordered_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>; + def int_isunordered_f32 : Intrinsic<[llvm_bool_ty, + llvm_float_ty, llvm_float_ty]>; + def int_isunordered_f64 : Intrinsic<[llvm_bool_ty, + llvm_double_ty, llvm_double_ty]>; def int_sqrt_f32 : Intrinsic<[llvm_float_ty , llvm_float_ty]>; def int_sqrt_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>; } From lattner at cs.uiuc.edu Fri Mar 10 11:55:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 11:55:22 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll Message-ID: <200603101755.LAA27536@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: store_op_load_fold.ll updated: 1.2 -> 1.3 --- Log message: weak globals on darwin require an extra load, breaking this test --- Diffs of the changes: (+1 -1) store_op_load_fold.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll diff -u llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.2 llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.3 --- llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.2 Thu Mar 9 13:04:30 2006 +++ llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll Fri Mar 10 11:55:10 2006 @@ -2,7 +2,7 @@ ; ; Test the add and load are folded into the store instruction. -%X = weak global short 0 +%X = internal global short 0 void %foo() { %tmp.0 = load short* %X From lattner at cs.uiuc.edu Fri Mar 10 12:01:15 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 12:01:15 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.td Message-ID: <200603101801.MAA27658@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.td updated: 1.3 -> 1.4 --- Log message: Fix another broken intrinsic. --- Diffs of the changes: (+1 -1) Intrinsics.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Intrinsics.td diff -u llvm/include/llvm/Intrinsics.td:1.3 llvm/include/llvm/Intrinsics.td:1.4 --- llvm/include/llvm/Intrinsics.td:1.3 Fri Mar 10 11:48:34 2006 +++ llvm/include/llvm/Intrinsics.td Fri Mar 10 12:01:03 2006 @@ -113,7 +113,7 @@ def int_returnaddress : Intrinsic<[llvm_ptr_ty, llvm_uint_ty], [InstrNoMem]>; def int_frameaddress : Intrinsic<[llvm_ptr_ty, llvm_uint_ty], [InstrNoMem]>; def int_stacksave : Intrinsic<[llvm_ptr_ty]>; -def int_stackrestore : Intrinsic<[llvm_ptr_ty]>; +def int_stackrestore : Intrinsic<[llvm_void_ty, llvm_ptr_ty]>; def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_uint_ty, llvm_uint_ty]>; def int_pcmarker : Intrinsic<[llvm_void_ty, llvm_uint_ty]>; From lattner at cs.uiuc.edu Fri Mar 10 14:20:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 14:20:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Message-ID: <200603102020.OAA28372@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCCodeEmitter.cpp updated: 1.47 -> 1.48 --- Log message: teach the JIT to encode vector registers --- Diffs of the changes: (+32 -32) PPCCodeEmitter.cpp | 64 ++++++++++++++++++++++++++--------------------------- 1 files changed, 32 insertions(+), 32 deletions(-) Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.47 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.48 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.47 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Fri Mar 10 14:19:50 2006 @@ -142,38 +142,38 @@ static unsigned enumRegToMachineReg(unsigned enumReg) { switch (enumReg) { - case PPC::R0 : case PPC::F0 : case PPC::CR0: return 0; - case PPC::R1 : case PPC::F1 : case PPC::CR1: return 1; - case PPC::R2 : case PPC::F2 : case PPC::CR2: return 2; - case PPC::R3 : case PPC::F3 : case PPC::CR3: return 3; - case PPC::R4 : case PPC::F4 : case PPC::CR4: return 4; - case PPC::R5 : case PPC::F5 : case PPC::CR5: return 5; - case PPC::R6 : case PPC::F6 : case PPC::CR6: return 6; - case PPC::R7 : case PPC::F7 : case PPC::CR7: return 7; - case PPC::R8 : case PPC::F8 : return 8; - case PPC::R9 : case PPC::F9 : return 9; - case PPC::R10: case PPC::F10: return 10; - case PPC::R11: case PPC::F11: return 11; - case PPC::R12: case PPC::F12: return 12; - case PPC::R13: case PPC::F13: return 13; - case PPC::R14: case PPC::F14: return 14; - case PPC::R15: case PPC::F15: return 15; - case PPC::R16: case PPC::F16: return 16; - case PPC::R17: case PPC::F17: return 17; - case PPC::R18: case PPC::F18: return 18; - case PPC::R19: case PPC::F19: return 19; - case PPC::R20: case PPC::F20: return 20; - case PPC::R21: case PPC::F21: return 21; - case PPC::R22: case PPC::F22: return 22; - case PPC::R23: case PPC::F23: return 23; - case PPC::R24: case PPC::F24: return 24; - case PPC::R25: case PPC::F25: return 25; - case PPC::R26: case PPC::F26: return 26; - case PPC::R27: case PPC::F27: return 27; - case PPC::R28: case PPC::F28: return 28; - case PPC::R29: case PPC::F29: return 29; - case PPC::R30: case PPC::F30: return 30; - case PPC::R31: case PPC::F31: return 31; + case PPC::R0 : case PPC::F0 : case PPC::V0 : case PPC::CR0: return 0; + case PPC::R1 : case PPC::F1 : case PPC::V1 : case PPC::CR1: return 1; + case PPC::R2 : case PPC::F2 : case PPC::V2 : case PPC::CR2: return 2; + case PPC::R3 : case PPC::F3 : case PPC::V3 : case PPC::CR3: return 3; + case PPC::R4 : case PPC::F4 : case PPC::V4 : case PPC::CR4: return 4; + case PPC::R5 : case PPC::F5 : case PPC::V5 : case PPC::CR5: return 5; + case PPC::R6 : case PPC::F6 : case PPC::V6 : case PPC::CR6: return 6; + case PPC::R7 : case PPC::F7 : case PPC::V7 : case PPC::CR7: return 7; + case PPC::R8 : case PPC::F8 : case PPC::V8 : return 8; + case PPC::R9 : case PPC::F9 : case PPC::V9 : return 9; + case PPC::R10: case PPC::F10: case PPC::V10: return 10; + case PPC::R11: case PPC::F11: case PPC::V11: return 11; + case PPC::R12: case PPC::F12: case PPC::V12: return 12; + case PPC::R13: case PPC::F13: case PPC::V13: return 13; + case PPC::R14: case PPC::F14: case PPC::V14: return 14; + case PPC::R15: case PPC::F15: case PPC::V15: return 15; + case PPC::R16: case PPC::F16: case PPC::V16: return 16; + case PPC::R17: case PPC::F17: case PPC::V17: return 17; + case PPC::R18: case PPC::F18: case PPC::V18: return 18; + case PPC::R19: case PPC::F19: case PPC::V19: return 19; + case PPC::R20: case PPC::F20: case PPC::V20: return 20; + case PPC::R21: case PPC::F21: case PPC::V21: return 21; + case PPC::R22: case PPC::F22: case PPC::V22: return 22; + case PPC::R23: case PPC::F23: case PPC::V23: return 23; + case PPC::R24: case PPC::F24: case PPC::V24: return 24; + case PPC::R25: case PPC::F25: case PPC::V25: return 25; + case PPC::R26: case PPC::F26: case PPC::V26: return 26; + case PPC::R27: case PPC::F27: case PPC::V27: return 27; + case PPC::R28: case PPC::F28: case PPC::V28: return 28; + case PPC::R29: case PPC::F29: case PPC::V29: return 29; + case PPC::R30: case PPC::F30: case PPC::V30: return 30; + case PPC::R31: case PPC::F31: case PPC::V31: return 31; default: std::cerr << "Unhandled reg in enumRegToRealReg!\n"; abort(); From lattner at cs.uiuc.edu Fri Mar 10 15:01:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 15:01:46 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200603102101.PAA28739@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.350 -> 1.351 --- Log message: reorder these to make it work with static libraries --- Diffs of the changes: (+2 -2) Makefile.rules | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.350 llvm/Makefile.rules:1.351 --- llvm/Makefile.rules:1.350 Thu Mar 9 00:00:05 2006 +++ llvm/Makefile.rules Fri Mar 10 15:01:34 2006 @@ -928,8 +928,8 @@ $(ToolBuildPath): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(Echo) Linking $(BuildMode) executable $(TOOLNAME) $(StripWarnMsg) - $(Verb) $(Link) -o $@ $(TOOLLINKOPTS) $(ObjectsO) $(ProjLibsOptions) \ - $(LLVMLibsOptions) $(ExtraLibs) $(TOOLLINKOPTSB) $(LIBS) + $(Verb) $(Link) -o $@ $(TOOLLINKOPTS) $(ObjectsO) $(LLVMLibsOptions) \ + $(ProjLibsOptions) $(ExtraLibs) $(TOOLLINKOPTSB) $(LIBS) $(Echo) ======= Finished Linking $(BuildMode) Executable $(TOOLNAME) \ $(StripWarnMsg) From lattner at cs.uiuc.edu Fri Mar 10 16:32:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 16:32:30 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Debugger/funccall.ll Message-ID: <200603102232.QAA29103@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Debugger: funccall.ll updated: 1.14 -> 1.15 --- Log message: Simplify this testcase --- Diffs of the changes: (+2 -14) funccall.ll | 16 ++-------------- 1 files changed, 2 insertions(+), 14 deletions(-) Index: llvm/test/Regression/Debugger/funccall.ll diff -u llvm/test/Regression/Debugger/funccall.ll:1.14 llvm/test/Regression/Debugger/funccall.ll:1.15 --- llvm/test/Regression/Debugger/funccall.ll:1.14 Wed Nov 16 01:24:31 2005 +++ llvm/test/Regression/Debugger/funccall.ll Fri Mar 10 16:32:18 2006 @@ -1,14 +1,4 @@ -;; RUN: echo create > %t.commands -;; RUN: echo s >> %t.commands -;; RUN: echo s >> %t.commands -;; RUN: echo finish >> %t.commands -;; RUN: echo bt >> %t.commands -;; RUN: echo q >> %t.commands -;; RUN: echo y >> %t.commands -;; RUN: llvm-as -f %s -o %t.bc -;; RUN: llvm-db %t.bc < %t.commands | grep 'in main at funccall.c:11:2' - -; XFAIL: alpha|ia64 +;; RUN: llvm-as < %s | llc ;; Debugger type declarations %lldb.compile_unit = type { uint, ushort, ushort, sbyte*, sbyte*, sbyte*, {}* } @@ -21,7 +11,6 @@ declare {}* %llvm.dbg.func.start(%lldb.global*) declare {}* %llvm.dbg.region.start({}*) declare {}* %llvm.dbg.region.end({}*) -declare {}* %llvm.dbg.declare({}*, ...) ;; Global object anchors %llvm.dbg.translation_units = linkonce global {} {} @@ -100,10 +89,9 @@ %.1 = call {}* %llvm.dbg.func.start(%lldb.global* %d.foo) %.2 = call {}* %llvm.dbg.stoppoint({}* %.1, uint 5, uint 2, %lldb.compile_unit* %d.compile_unit) - %.3 = call {}*({}*, ...)* %llvm.dbg.declare({}* %.2, %lldb.local* %d.t, int* %t) %tmp.0 = load int* %q store int %tmp.0, int* %t - %.4 = call {}* %llvm.dbg.stoppoint({}* %.3, uint 6, uint 2, %lldb.compile_unit* %d.compile_unit) + %.4 = call {}* %llvm.dbg.stoppoint({}* %.2, uint 6, uint 2, %lldb.compile_unit* %d.compile_unit) %tmp.01 = load int* %t %tmp.1 = add int %tmp.01, 1 store int %tmp.1, int* %q From lattner at cs.uiuc.edu Fri Mar 10 16:40:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 16:40:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Debugger/Debugger.cpp UnixLocalInferiorProcess.cpp Message-ID: <200603102240.QAA29263@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: Debugger.cpp updated: 1.5 -> 1.6 UnixLocalInferiorProcess.cpp (r1.10) removed --- Log message: Remove UnixLocalInferiorProcess: debugging via the JIT isn't a good idea. Perhaps llvm-db will turn into a read debugger someday. --- Diffs of the changes: (+6 -0) Debugger.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Debugger/Debugger.cpp diff -u llvm/lib/Debugger/Debugger.cpp:1.5 llvm/lib/Debugger/Debugger.cpp:1.6 --- llvm/lib/Debugger/Debugger.cpp:1.5 Mon Dec 26 04:24:15 2005 +++ llvm/lib/Debugger/Debugger.cpp Fri Mar 10 16:39:48 2006 @@ -113,6 +113,12 @@ Process = InferiorProcess::create(Program, Args, Environment); } +InferiorProcess * +InferiorProcess::create(Module *M, const std::vector &Arguments, + const char * const *envp) { + throw"No supported binding to inferior processes (debugger not implemented)."; +} + /// killProgram - If the program is currently executing, kill off the /// process and free up any state related to the currently running program. If /// there is no program currently running, this just silently succeeds. From lattner at cs.uiuc.edu Fri Mar 10 16:48:31 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 16:48:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200603102248.QAA29358@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.185 -> 1.186 --- Log message: scrape out bits of llvm-db --- Diffs of the changes: (+0 -9) SelectionDAGISel.cpp | 9 --------- 1 files changed, 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.185 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.186 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.185 Fri Mar 10 01:49:12 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 10 16:48:19 2006 @@ -965,9 +965,6 @@ return 0; case Intrinsic::dbg_stoppoint: { - if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) - return "llvm_debugger_stop"; - MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo(); if (DebugInfo && DebugInfo->Verify(I.getOperand(4))) { std::vector Ops; @@ -996,20 +993,14 @@ return 0; } case Intrinsic::dbg_region_start: - if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) - return "llvm_dbg_region_start"; if (I.getType() != Type::VoidTy) setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); return 0; case Intrinsic::dbg_region_end: - if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) - return "llvm_dbg_region_end"; if (I.getType() != Type::VoidTy) setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); return 0; case Intrinsic::dbg_func_start: - if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) - return "llvm_dbg_subprogram"; if (I.getType() != Type::VoidTy) setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); return 0; From lattner at cs.uiuc.edu Fri Mar 10 16:49:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 16:49:17 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/IntrinsicLowering.h Message-ID: <200603102249.QAA29445@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: IntrinsicLowering.h updated: 1.9 -> 1.10 --- Log message: remove ShouldEmitDebugFunctions, a hack to support llvm-db via the jit --- Diffs of the changes: (+1 -5) IntrinsicLowering.h | 6 +----- 1 files changed, 1 insertion(+), 5 deletions(-) Index: llvm/include/llvm/CodeGen/IntrinsicLowering.h diff -u llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.9 llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.10 --- llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.9 Wed Nov 16 01:21:15 2005 +++ llvm/include/llvm/CodeGen/IntrinsicLowering.h Fri Mar 10 16:49:05 2006 @@ -40,14 +40,10 @@ class Module; class IntrinsicLowering { - protected: - bool ShouldEmitDebugFunctions; public: - IntrinsicLowering() : ShouldEmitDebugFunctions(false) {} + IntrinsicLowering() {} virtual ~IntrinsicLowering() {} - bool EmitDebugFunctions() const { return ShouldEmitDebugFunctions; } - /// AddPrototypes - This method, if called, causes all of the prototypes /// that might be needed by an intrinsic lowering implementation to be /// inserted into the module specified. From lattner at cs.uiuc.edu Fri Mar 10 17:14:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 17:14:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Debugger/FDHandle.cpp FDHandle.h Message-ID: <200603102314.RAA29817@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: FDHandle.cpp (r1.3) removed FDHandle.h (r1.2) removed --- Log message: remove some dead code --- Diffs of the changes: (+0 -0) 0 files changed From evan.cheng at apple.com Fri Mar 10 17:52:16 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 10 Mar 2006 17:52:16 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Message-ID: <200603102352.RAA30544@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.28 -> 1.29 --- Log message: Added a parameter to control whether Constant::getStringValue() would chop off the result string at the first null terminator. --- Diffs of the changes: (+3 -1) Constant.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.28 llvm/include/llvm/Constant.h:1.29 --- llvm/include/llvm/Constant.h:1.28 Wed Mar 8 12:11:06 2006 +++ llvm/include/llvm/Constant.h Fri Mar 10 17:52:03 2006 @@ -93,8 +93,10 @@ /// getStringValue - Turn an LLVM constant pointer that eventually points to a /// global into a string value. Return an empty string if we can't do it. + /// Parameter Chop determines if the result is chopped at the first null + /// terminator. /// - std::string getStringValue(unsigned Offset = 0); + std::string getStringValue(bool Chop = true, unsigned Offset = 0); }; } // End llvm namespace From evan.cheng at apple.com Fri Mar 10 17:52:17 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 10 Mar 2006 17:52:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200603102352.RAA30552@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.186 -> 1.187 --- Log message: Added a parameter to control whether Constant::getStringValue() would chop off the result string at the first null terminator. --- Diffs of the changes: (+1 -1) SelectionDAGISel.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.186 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.187 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.186 Fri Mar 10 16:48:19 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 10 17:52:03 2006 @@ -1941,7 +1941,7 @@ if (G) { GlobalVariable *GV = dyn_cast(G->getGlobal()); if (GV) { - Str = GV->getStringValue(); + Str = GV->getStringValue(false); if (!Str.empty()) { CopyFromStr = true; SrcOff += SrcDelta; From evan.cheng at apple.com Fri Mar 10 17:52:17 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 10 Mar 2006 17:52:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200603102352.RAA30548@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.146 -> 1.147 --- Log message: Added a parameter to control whether Constant::getStringValue() would chop off the result string at the first null terminator. --- Diffs of the changes: (+8 -4) Constants.cpp | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.146 llvm/lib/VMCore/Constants.cpp:1.147 --- llvm/lib/VMCore/Constants.cpp:1.146 Wed Mar 8 12:11:07 2006 +++ llvm/lib/VMCore/Constants.cpp Fri Mar 10 17:52:03 2006 @@ -1715,8 +1715,10 @@ /// getStringValue - Turn an LLVM constant pointer that eventually points to a /// global into a string value. Return an empty string if we can't do it. +/// Parameter Chop determines if the result is chopped at the first null +/// terminator. /// -std::string Constant::getStringValue(unsigned Offset) { +std::string Constant::getStringValue(bool Chop, unsigned Offset) { if (GlobalVariable *GV = dyn_cast(this)) { if (GV->hasInitializer() && isa(GV->getInitializer())) { ConstantArray *Init = cast(GV->getInitializer()); @@ -1727,9 +1729,11 @@ Result.erase(Result.begin(), Result.begin()+Offset); // Take off the null terminator, and any string fragments after it. - std::string::size_type NullPos = Result.find_first_of((char)0); - if (NullPos != std::string::npos) - Result.erase(Result.begin()+NullPos, Result.end()); + if (Chop) { + std::string::size_type NullPos = Result.find_first_of((char)0); + if (NullPos != std::string::npos) + Result.erase(Result.begin()+NullPos, Result.end()); + } return Result; } } From evan.cheng at apple.com Fri Mar 10 18:13:22 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 10 Mar 2006 18:13:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200603110013.SAA30697@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.147 -> 1.148 --- Log message: Doh! --- Diffs of the changes: (+2 -2) Constants.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.147 llvm/lib/VMCore/Constants.cpp:1.148 --- llvm/lib/VMCore/Constants.cpp:1.147 Fri Mar 10 17:52:03 2006 +++ llvm/lib/VMCore/Constants.cpp Fri Mar 10 18:13:10 2006 @@ -1740,7 +1740,7 @@ } } else if (Constant *C = dyn_cast(this)) { if (GlobalValue *GV = dyn_cast(C)) - return GV->getStringValue(Offset); + return GV->getStringValue(Chop, Offset); else if (ConstantExpr *CE = dyn_cast(C)) { if (CE->getOpcode() == Instruction::GetElementPtr) { // Turn a gep into the specified offset. @@ -1748,7 +1748,7 @@ cast(CE->getOperand(1))->isNullValue() && isa(CE->getOperand(2))) { Offset += cast(CE->getOperand(2))->getRawValue(); - return CE->getOperand(0)->getStringValue(Offset); + return CE->getOperand(0)->getStringValue(Chop, Offset); } } } From lattner at cs.uiuc.edu Fri Mar 10 18:20:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 10 Mar 2006 18:20:59 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/IntrinsicEmitter.cpp Message-ID: <200603110020.SAA30752@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: IntrinsicEmitter.cpp updated: 1.5 -> 1.6 --- Log message: fix pasto in generate assertion msg --- Diffs of the changes: (+1 -1) IntrinsicEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/IntrinsicEmitter.cpp diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.5 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.6 --- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.5 Thu Mar 9 16:37:52 2006 +++ llvm/utils/TableGen/IntrinsicEmitter.cpp Fri Mar 10 18:20:47 2006 @@ -169,7 +169,7 @@ for (unsigned j = 1; j != Ints[i].ArgTypes.size(); ++j) OS << " Assert1(FTy->getParamType(" << j-1 << ")->getTypeID() == " << Ints[i].ArgTypes[j] << ",\n" - << " \"Illegal result type!\", IF);\n"; + << " \"Illegal argument type!\", IF);\n"; OS << " break;\n"; } OS << " }\n"; From natebegeman at mac.com Fri Mar 10 20:20:58 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 10 Mar 2006 20:20:58 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/PostDominators.h Message-ID: <200603110220.UAA31196@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: PostDominators.h updated: 1.10 -> 1.11 --- Log message: Fix PR681: http://llvm.cs.uiuc.edu/PR681 by using the standard Lengauer and Tarjan algorithm for dominator set construction, rather than intersecting various std::sets. This reduces the memory usage for the testcase in PR681: http://llvm.cs.uiuc.edu/PR681 from 496 to 26MB of ram on my darwin system, and reduces the runtime from 32.8 to 0.8 seconds on a 2.5GHz G5. This also enables future code sharing between Dom and PostDom now that they share near-identical implementations. --- Diffs of the changes: (+49 -32) PostDominators.h | 81 +++++++++++++++++++++++++++++++++---------------------- 1 files changed, 49 insertions(+), 32 deletions(-) Index: llvm/include/llvm/Analysis/PostDominators.h diff -u llvm/include/llvm/Analysis/PostDominators.h:1.10 llvm/include/llvm/Analysis/PostDominators.h:1.11 --- llvm/include/llvm/Analysis/PostDominators.h:1.10 Sun Jan 8 02:19:58 2006 +++ llvm/include/llvm/Analysis/PostDominators.h Fri Mar 10 20:20:46 2006 @@ -18,6 +18,42 @@ namespace llvm { +//===------------------------------------- +/// ImmediatePostDominators Class - Concrete subclass of ImmediateDominatorsBase +/// that is used to compute a normal immediate dominator set. +/// +struct ImmediatePostDominators : public ImmediateDominatorsBase { + ImmediatePostDominators() : ImmediateDominatorsBase(false) {} + + virtual bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + +private: + struct InfoRec { + unsigned Semi; + unsigned Size; + BasicBlock *Label, *Parent, *Child, *Ancestor; + + std::vector Bucket; + + InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0){} + }; + + // Vertex - Map the DFS number to the BasicBlock* + std::vector Vertex; + + // Info - Collection of information used during the computation of idoms. + std::map Info; + + unsigned DFSPass(BasicBlock *V, InfoRec &VInfo, unsigned N); + void Compress(BasicBlock *V, InfoRec &VInfo); + BasicBlock *Eval(BasicBlock *v); + void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo); +}; + /// PostDominatorSet Class - Concrete subclass of DominatorSetBase that is used /// to compute the post-dominator set. Because there can be multiple exit nodes /// in an LLVM function, we calculate post dominators with a special null block @@ -27,40 +63,20 @@ /// struct PostDominatorSet : public DominatorSetBase { PostDominatorSet() : DominatorSetBase(true) {} - + virtual bool runOnFunction(Function &F); - - /// getAnalysisUsage - This pass does not modify the function at all. + + /// getAnalysisUsage - This simply provides a dominator set /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); AU.setPreservesAll(); } + + // stub - dummy function, just ignore it + static void stub(); }; - -/// ImmediatePostDominators Class - Concrete subclass of ImmediateDominatorsBase -/// that is used to compute the immediate post-dominators. -/// -struct ImmediatePostDominators : public ImmediateDominatorsBase { - ImmediatePostDominators() : ImmediateDominatorsBase(true) {} - - virtual bool runOnFunction(Function &F) { - IDoms.clear(); // Reset from the last time we were run... - PostDominatorSet &DS = getAnalysis(); - Roots = DS.getRoots(); - calcIDoms(DS); - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - } -private: - void calcIDoms(const DominatorSetBase &DS); -}; - - /// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to /// compute the a post-dominator tree. /// @@ -69,18 +85,19 @@ virtual bool runOnFunction(Function &F) { reset(); // Reset from the last time we were run... - PostDominatorSet &DS = getAnalysis(); - Roots = DS.getRoots(); - calculate(DS); + ImmediatePostDominators &IPD = getAnalysis(); + Roots = IPD.getRoots(); + calculate(IPD); return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); } private: - void calculate(const PostDominatorSet &DS); + void calculate(const ImmediatePostDominators &IPD); + Node *getNodeForBlock(BasicBlock *BB); }; From natebegeman at mac.com Fri Mar 10 20:20:58 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 10 Mar 2006 20:20:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PostDominators.cpp Message-ID: <200603110220.UAA31192@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PostDominators.cpp updated: 1.54 -> 1.55 --- Log message: Fix PR681: http://llvm.cs.uiuc.edu/PR681 by using the standard Lengauer and Tarjan algorithm for dominator set construction, rather than intersecting various std::sets. This reduces the memory usage for the testcase in PR681: http://llvm.cs.uiuc.edu/PR681 from 496 to 26MB of ram on my darwin system, and reduces the runtime from 32.8 to 0.8 seconds on a 2.5GHz G5. This also enables future code sharing between Dom and PostDom now that they share near-identical implementations. --- Diffs of the changes: (+190 -141) PostDominators.cpp | 331 ++++++++++++++++++++++++++++++----------------------- 1 files changed, 190 insertions(+), 141 deletions(-) Index: llvm/lib/Analysis/PostDominators.cpp diff -u llvm/lib/Analysis/PostDominators.cpp:1.54 llvm/lib/Analysis/PostDominators.cpp:1.55 --- llvm/lib/Analysis/PostDominators.cpp:1.54 Sun Jan 8 02:22:18 2006 +++ llvm/lib/Analysis/PostDominators.cpp Fri Mar 10 20:20:46 2006 @@ -16,9 +16,132 @@ #include "llvm/Support/CFG.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SetOperations.h" +#include using namespace llvm; //===----------------------------------------------------------------------===// +// ImmediatePostDominators Implementation +//===----------------------------------------------------------------------===// + +static RegisterAnalysis +D("postidom", "Immediate Post-Dominators Construction", true); + +unsigned ImmediatePostDominators::DFSPass(BasicBlock *V, InfoRec &VInfo, + unsigned N) { + VInfo.Semi = ++N; + VInfo.Label = V; + + Vertex.push_back(V); // Vertex[n] = V; + //Info[V].Ancestor = 0; // Ancestor[n] = 0 + //Child[V] = 0; // Child[v] = 0 + VInfo.Size = 1; // Size[v] = 1 + + // For PostDominators, we want to walk predecessors rather than successors + // as we do in forward Dominators. + for (pred_iterator PI = pred_begin(V), PE = pred_end(V); PI != PE; ++PI) { + InfoRec &SuccVInfo = Info[*PI]; + if (SuccVInfo.Semi == 0) { + SuccVInfo.Parent = V; + N = DFSPass(*PI, SuccVInfo, N); + } + } + return N; +} + +void ImmediatePostDominators::Compress(BasicBlock *V, InfoRec &VInfo) { + BasicBlock *VAncestor = VInfo.Ancestor; + InfoRec &VAInfo = Info[VAncestor]; + if (VAInfo.Ancestor == 0) + return; + + Compress(VAncestor, VAInfo); + + BasicBlock *VAncestorLabel = VAInfo.Label; + BasicBlock *VLabel = VInfo.Label; + if (Info[VAncestorLabel].Semi < Info[VLabel].Semi) + VInfo.Label = VAncestorLabel; + + VInfo.Ancestor = VAInfo.Ancestor; +} + +BasicBlock *ImmediatePostDominators::Eval(BasicBlock *V) { + InfoRec &VInfo = Info[V]; + + // Higher-complexity but faster implementation + if (VInfo.Ancestor == 0) + return V; + Compress(V, VInfo); + return VInfo.Label; +} + +void ImmediatePostDominators::Link(BasicBlock *V, BasicBlock *W, + InfoRec &WInfo) { + // Higher-complexity but faster implementation + WInfo.Ancestor = V; +} + +bool ImmediatePostDominators::runOnFunction(Function &F) { + IDoms.clear(); // Reset from the last time we were run... + Roots.clear(); + + // Step #0: Scan the function looking for the root nodes of the post-dominance + // relationships. These blocks, which have no successors, end with return and + // unwind instructions. + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + if (succ_begin(I) == succ_end(I)) + Roots.push_back(I); + + Vertex.push_back(0); + + // Step #1: Number blocks in depth-first order and initialize variables used + // in later stages of the algorithm. + unsigned N = 0; + for (unsigned i = 0, e = Roots.size(); i != e; ++i) + N = DFSPass(Roots[i], Info[Roots[i]], N); + + for (unsigned i = N; i >= 2; --i) { + BasicBlock *W = Vertex[i]; + InfoRec &WInfo = Info[W]; + + // Step #2: Calculate the semidominators of all vertices + for (succ_iterator SI = succ_begin(W), SE = succ_end(W); SI != SE; ++SI) + if (Info.count(*SI)) { // Only if this predecessor is reachable! + unsigned SemiU = Info[Eval(*SI)].Semi; + if (SemiU < WInfo.Semi) + WInfo.Semi = SemiU; + } + + Info[Vertex[WInfo.Semi]].Bucket.push_back(W); + + BasicBlock *WParent = WInfo.Parent; + Link(WParent, W, WInfo); + + // Step #3: Implicitly define the immediate dominator of vertices + std::vector &WParentBucket = Info[WParent].Bucket; + while (!WParentBucket.empty()) { + BasicBlock *V = WParentBucket.back(); + WParentBucket.pop_back(); + BasicBlock *U = Eval(V); + IDoms[V] = Info[U].Semi < Info[V].Semi ? U : WParent; + } + } + + // Step #4: Explicitly define the immediate dominator of each vertex + for (unsigned i = 2; i <= N; ++i) { + BasicBlock *W = Vertex[i]; + BasicBlock *&WIDom = IDoms[W]; + if (WIDom != Vertex[Info[W].Semi]) + WIDom = IDoms[WIDom]; + } + + // Free temporary memory used to construct idom's + Info.clear(); + std::vector().swap(Vertex); + + return false; +} + +//===----------------------------------------------------------------------===// // PostDominatorSet Implementation //===----------------------------------------------------------------------===// @@ -30,119 +153,59 @@ // sets for the function. // bool PostDominatorSet::runOnFunction(Function &F) { - Doms.clear(); // Reset from the last time we were run... - // Scan the function looking for the root nodes of the post-dominance // relationships. These blocks end with return and unwind instructions. // While we are iterating over the function, we also initialize all of the // domsets to empty. Roots.clear(); - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { - Doms[I]; // Initialize to empty - + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) if (succ_begin(I) == succ_end(I)) Roots.push_back(I); - } // If there are no exit nodes for the function, postdomsets are all empty. // This can happen if the function just contains an infinite loop, for // example. + ImmediatePostDominators &IPD = getAnalysis(); + Doms.clear(); // Reset from the last time we were run... if (Roots.empty()) return false; // If we have more than one root, we insert an artificial "null" exit, which // has "virtual edges" to each of the real exit nodes. - if (Roots.size() > 1) - Doms[0].insert(0); + //if (Roots.size() > 1) + // Doms[0].insert(0); - bool Changed; - do { - Changed = false; - - std::set Visited; - DomSetType WorkingSet; - - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - for (idf_ext_iterator It = idf_ext_begin(Roots[i], Visited), - E = idf_ext_end(Roots[i], Visited); It != E; ++It) { - BasicBlock *BB = *It; - succ_iterator SI = succ_begin(BB), SE = succ_end(BB); - if (SI != SE) { // Is there SOME successor? - // Loop until we get to a successor that has had it's dom set filled - // in at least once. We are guaranteed to have this because we are - // traversing the graph in DFO and have handled start nodes specially. - // - while (Doms[*SI].size() == 0) ++SI; - WorkingSet = Doms[*SI]; - - for (++SI; SI != SE; ++SI) { // Intersect all of the successor sets - DomSetType &SuccSet = Doms[*SI]; - if (SuccSet.size()) - set_intersect(WorkingSet, SuccSet); - } + // Root nodes only dominate themselves. + for (unsigned i = 0, e = Roots.size(); i != e; ++i) + Doms[Roots[i]].insert(Roots[i]); + + // Loop over all of the blocks in the function, calculating dominator sets for + // each function. + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + if (BasicBlock *IPDom = IPD[I]) { // Get idom if block is reachable + DomSetType &DS = Doms[I]; + assert(DS.empty() && "PostDomset already filled in for this block?"); + DS.insert(I); // Blocks always dominate themselves + + // Insert all dominators into the set... + while (IPDom) { + // If we have already computed the dominator sets for our immediate post + // dominator, just use it instead of walking all the way up to the root. + DomSetType &IPDS = Doms[IPDom]; + if (!IPDS.empty()) { + DS.insert(IPDS.begin(), IPDS.end()); + break; } else { - // If this node has no successors, it must be one of the root nodes. - // We will already take care of the notion that the node - // post-dominates itself. The only thing we have to add is that if - // there are multiple root nodes, we want to insert a special "null" - // exit node which dominates the roots as well. - if (Roots.size() > 1) - WorkingSet.insert(0); + DS.insert(IPDom); + IPDom = IPD[IPDom]; } - - WorkingSet.insert(BB); // A block always dominates itself - DomSetType &BBSet = Doms[BB]; - if (BBSet != WorkingSet) { - BBSet.swap(WorkingSet); // Constant time operation! - Changed = true; // The sets changed. - } - WorkingSet.clear(); // Clear out the set for next iteration - } - } while (Changed); - return false; -} - -//===----------------------------------------------------------------------===// -// ImmediatePostDominators Implementation -//===----------------------------------------------------------------------===// - -static RegisterAnalysis -D("postidom", "Immediate Post-Dominators Construction", true); - - -// calcIDoms - Calculate the immediate dominator mapping, given a set of -// dominators for every basic block. -void ImmediatePostDominators::calcIDoms(const DominatorSetBase &DS) { - // Loop over all of the nodes that have dominators... figuring out the IDOM - // for each node... - // - for (DominatorSet::const_iterator DI = DS.begin(), DEnd = DS.end(); - DI != DEnd; ++DI) { - BasicBlock *BB = DI->first; - const DominatorSet::DomSetType &Dominators = DI->second; - unsigned DomSetSize = Dominators.size(); - if (DomSetSize == 1) continue; // Root node... IDom = null - - // Loop over all dominators of this node. This corresponds to looping over - // nodes in the dominator chain, looking for a node whose dominator set is - // equal to the current nodes, except that the current node does not exist - // in it. This means that it is one level higher in the dom chain than the - // current node, and it is our idom! - // - DominatorSet::DomSetType::const_iterator I = Dominators.begin(); - DominatorSet::DomSetType::const_iterator End = Dominators.end(); - for (; I != End; ++I) { // Iterate over dominators... - // All of our dominators should form a chain, where the number of elements - // in the dominator set indicates what level the node is at in the chain. - // We want the node immediately above us, so it will have an identical - // dominator set, except that BB will not dominate it... therefore it's - // dominator set size will be one less than BB's... - // - if (DS.getDominators(*I).size() == DomSetSize - 1) { - IDoms[BB] = *I; - break; } + } else { + // Ensure that every basic block has at least an empty set of nodes. This + // is important for the case when there is unreachable blocks. + Doms[I]; } - } + + return false; } //===----------------------------------------------------------------------===// @@ -152,59 +215,45 @@ static RegisterAnalysis F("postdomtree", "Post-Dominator Tree Construction", true); -void PostDominatorTree::calculate(const PostDominatorSet &DS) { - if (Roots.empty()) return; - BasicBlock *Root = Roots.size() == 1 ? Roots[0] : 0; +DominatorTreeBase::Node *PostDominatorTree::getNodeForBlock(BasicBlock *BB) { + Node *&BBNode = Nodes[BB]; + if (BBNode) return BBNode; + + // Haven't calculated this node yet? Get or calculate the node for the + // immediate postdominator. + BasicBlock *IPDom = getAnalysis()[BB]; + Node *IPDomNode = getNodeForBlock(IPDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + return BBNode = IPDomNode->addChild(new Node(BB, IPDomNode)); +} - Nodes[Root] = RootNode = new Node(Root, 0); // Add a node for the root... +void PostDominatorTree::calculate(const ImmediatePostDominators &IPD) { + if (Roots.empty()) return; - // Iterate over all nodes in depth first order... - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - for (idf_iterator I = idf_begin(Roots[i]), - E = idf_end(Roots[i]); I != E; ++I) { - BasicBlock *BB = *I; - const DominatorSet::DomSetType &Dominators = DS.getDominators(BB); - unsigned DomSetSize = Dominators.size(); - if (DomSetSize == 1) continue; // Root node... IDom = null - - // If we have already computed the immediate dominator for this node, - // don't revisit. This can happen due to nodes reachable from multiple - // roots, but which the idf_iterator doesn't know about. - if (Nodes.find(BB) != Nodes.end()) continue; - - // Loop over all dominators of this node. This corresponds to looping - // over nodes in the dominator chain, looking for a node whose dominator - // set is equal to the current nodes, except that the current node does - // not exist in it. This means that it is one level higher in the dom - // chain than the current node, and it is our idom! We know that we have - // already added a DominatorTree node for our idom, because the idom must - // be a predecessor in the depth first order that we are iterating through - // the function. - // - for (DominatorSet::DomSetType::const_iterator I = Dominators.begin(), - E = Dominators.end(); I != E; ++I) { // Iterate over dominators. - // All of our dominators should form a chain, where the number - // of elements in the dominator set indicates what level the - // node is at in the chain. We want the node immediately - // above us, so it will have an identical dominator set, - // except that BB will not dominate it... therefore it's - // dominator set size will be one less than BB's... - // - if (DS.getDominators(*I).size() == DomSetSize - 1) { - // We know that the immediate dominator should already have a node, - // because we are traversing the CFG in depth first order! - // - Node *IDomNode = Nodes[*I]; - assert(IDomNode && "No node for IDOM?"); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - Nodes[BB] = IDomNode->addChild(new Node(BB, IDomNode)); - break; - } + // Add a node for the root. This node might be the actual root, if there is + // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) + // which postdominates all real exits if there are multiple exit blocks. + BasicBlock *Root = Roots.size() == 1 ? Roots[0] : 0; + Nodes[Root] = RootNode = new Node(Root, 0); + + Function *F = Roots[0]->getParent(); + // Loop over all of the reachable blocks in the function... + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) + if (BasicBlock *ImmPostDom = IPD.get(I)) { // Reachable block. + Node *&BBNode = Nodes[I]; + if (!BBNode) { // Haven't calculated this node yet? + // Get or calculate the node for the immediate dominator + Node *IPDomNode = getNodeForBlock(ImmPostDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + BBNode = IPDomNode->addChild(new Node(I, IPDomNode)); } } } + //===----------------------------------------------------------------------===// // PostETForest Implementation //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sat Mar 11 14:17:21 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 14:17:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603112017.OAA15796@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.15 -> 1.16 --- Log message: add a note --- Diffs of the changes: (+4 -0) README.txt | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.15 llvm/lib/Target/README.txt:1.16 --- llvm/lib/Target/README.txt:1.15 Thu Mar 9 14:13:21 2006 +++ llvm/lib/Target/README.txt Sat Mar 11 14:17:08 2006 @@ -117,6 +117,10 @@ //===---------------------------------------------------------------------===// +Reassociate should turn: X*X*X*X -> t=(X*X) (t*t) to eliminate a multiply. + +//===---------------------------------------------------------------------===// + These two functions should generate the same code on big-endian systems: int g(int *j,int *l) { return memcmp(j,l,4); } From lattner at cs.uiuc.edu Sat Mar 11 14:20:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 14:20:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603112020.OAA15841@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.16 -> 1.17 --- Log message: add an example --- Diffs of the changes: (+11 -0) README.txt | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.16 llvm/lib/Target/README.txt:1.17 --- llvm/lib/Target/README.txt:1.16 Sat Mar 11 14:17:08 2006 +++ llvm/lib/Target/README.txt Sat Mar 11 14:20:40 2006 @@ -121,6 +121,17 @@ //===---------------------------------------------------------------------===// +Interesting? testcase for add/shift/mul reassoc: + +int bar(int x, int y) { + return x*x*x+y+x*x*x*x*x*y*y*y*y; +} +int foo(int z, int n) { + return bar(z, n) + bar(2*z, 2*n); +} + +//===---------------------------------------------------------------------===// + These two functions should generate the same code on big-endian systems: int g(int *j,int *l) { return memcmp(j,l,4); } From lattner at cs.uiuc.edu Sat Mar 11 15:50:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 15:50:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Message-ID: <200603112150.PAA16172@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.7 -> 1.8 --- Log message: blr is a branch too --- Diffs of the changes: (+1 -0) PPCHazardRecognizers.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.7 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.8 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.7 Tue Mar 7 22:25:59 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Sat Mar 11 15:49:49 2006 @@ -79,6 +79,7 @@ case PPC::BCTRL: case PPC::BL: case PPC::BLA: + case PPC::BLR: return BR; case PPC::MCRF: case PPC::MFCR: From lattner at cs.uiuc.edu Sat Mar 11 16:24:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 16:24:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603112224.QAA16504@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.41 -> 1.42 --- Log message: merge preds/chainpreds -> preds set merge succs/chainsuccs -> succs set This has no functionality change, simplifies the code, and reduces the size of sunits. --- Diffs of the changes: (+63 -95) ScheduleDAGList.cpp | 158 ++++++++++++++++++++-------------------------------- 1 files changed, 63 insertions(+), 95 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.41 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.42 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.41 Fri Mar 10 01:42:02 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Mar 11 16:24:20 2006 @@ -41,10 +41,12 @@ struct SUnit { SDNode *Node; // Representative node. std::vector FlaggedNodes; // All nodes flagged to Node. - std::set Preds; // All real predecessors. - std::set ChainPreds; // All chain predecessors. - std::set Succs; // All real successors. - std::set ChainSuccs; // All chain successors. + + // Preds/Succs - The SUnits before/after us in the graph. The boolean value + // is true if the edge is a token chain edge, false if it is a value edge. + std::set > Preds; // All sunit predecessors. + std::set > Succs; // All sunit successors. + short NumPredsLeft; // # of preds not scheduled. short NumSuccsLeft; // # of succs not scheduled. short NumChainPredsLeft; // # of chain preds not scheduled. @@ -93,34 +95,24 @@ if (Preds.size() != 0) { std::cerr << " Predecessors:\n"; - for (std::set::const_iterator I = Preds.begin(), + for (std::set >::const_iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G); - } - } - if (ChainPreds.size() != 0) { - std::cerr << " Chained Preds:\n"; - for (std::set::const_iterator I = ChainPreds.begin(), - E = ChainPreds.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G); + if (I->second) + std::cerr << " ch "; + else + std::cerr << " val "; + I->first->dump(G); } } if (Succs.size() != 0) { std::cerr << " Successors:\n"; - for (std::set::const_iterator I = Succs.begin(), + for (std::set >::const_iterator I = Succs.begin(), E = Succs.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G); - } - } - if (ChainSuccs.size() != 0) { - std::cerr << " Chained succs:\n"; - for (std::set::const_iterator I = ChainSuccs.begin(), - E = ChainSuccs.end(); I != E; ++I) { - std::cerr << " "; - (*I)->dump(G); + if (I->second) + std::cerr << " ch "; + else + std::cerr << " val "; + I->first->dump(G); } } std::cerr << "\n"; @@ -205,8 +197,8 @@ private: SUnit *NewSUnit(SDNode *N); - void ReleasePred(SUnit *PredSU, bool isChain = false); - void ReleaseSucc(SUnit *SuccSU, bool isChain = false); + void ReleasePred(SUnit *PredSU, bool isChain); + void ReleaseSucc(SUnit *SuccSU, bool isChain); void ScheduleNodeBottomUp(SUnit *SU); void ScheduleNodeTopDown(SUnit *SU); void ListScheduleTopDown(); @@ -296,15 +288,12 @@ Sequence.push_back(SU); // Bottom up: release predecessors - for (std::set::iterator I1 = SU->Preds.begin(), - E1 = SU->Preds.end(); I1 != E1; ++I1) { - ReleasePred(*I1); - SU->NumPredsLeft--; - } - for (std::set::iterator I2 = SU->ChainPreds.begin(), - E2 = SU->ChainPreds.end(); I2 != E2; ++I2) - ReleasePred(*I2, true); - + for (std::set >::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) { + ReleasePred(I->first, I->second); + if (!I->second) + SU->NumPredsLeft--; + } CurrCycle++; } @@ -318,15 +307,12 @@ Sequence.push_back(SU); // Bottom up: release successors. - for (std::set::iterator I1 = SU->Succs.begin(), - E1 = SU->Succs.end(); I1 != E1; ++I1) { - ReleaseSucc(*I1); - SU->NumSuccsLeft--; - } - for (std::set::iterator I2 = SU->ChainSuccs.begin(), - E2 = SU->ChainSuccs.end(); I2 != E2; ++I2) - ReleaseSucc(*I2, true); - + for (std::set >::iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) { + ReleaseSucc(I->first, I->second); + if (!I->second) + SU->NumSuccsLeft--; + } CurrCycle++; } @@ -399,8 +385,7 @@ // All leaves to Available queue. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // It is available if it has no predecessors. - if ((SUnits[i].Preds.size() + SUnits[i].ChainPreds.size()) == 0 && - &SUnits[i] != Entry) + if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) PriorityQueue->push(&SUnits[i]); } @@ -586,26 +571,30 @@ MVT::ValueType OpVT = N->getOperand(i).getValueType(); assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); - - if (OpVT == MVT::Other) { - if (SU->ChainPreds.insert(OpSU).second) - SU->NumChainPredsLeft++; - if (OpSU->ChainSuccs.insert(SU).second) - OpSU->NumChainSuccsLeft++; - } else { - if (SU->Preds.insert(OpSU).second) + bool isChain = OpVT == MVT::Other; + + if (SU->Preds.insert(std::make_pair(OpSU, isChain)).second) { + if (!isChain) { SU->NumPredsLeft++; - if (OpSU->Succs.insert(SU).second) + } else { + SU->NumChainPredsLeft++; + } + } + if (OpSU->Succs.insert(std::make_pair(SU, isChain)).second) { + if (!isChain) { OpSU->NumSuccsLeft++; + } else { + OpSU->NumChainSuccsLeft++; + } } } } // Remove MainNode from FlaggedNodes again. SU->FlaggedNodes.pop_back(); - - DEBUG(SU->dumpAll(&DAG)); } + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) + SUnits[su].dumpAll(&DAG)); } /// EmitSchedule - Emit the machine code in scheduled order. @@ -779,9 +768,10 @@ SethiUllmanNumber = 1; } else { int Extra = 0; - for (std::set::const_iterator I = SU->Preds.begin(), - E = SU->Preds.end(); I != E; ++I) { - SUnit *PredSU = *I; + for (std::set >::const_iterator + I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { + if (I->second) continue; // ignore chain preds. + SUnit *PredSU = I->first; int PredSethiUllman = CalcNodePriority(PredSU); if (PredSethiUllman > SethiUllmanNumber) { SethiUllmanNumber = PredSethiUllman; @@ -950,13 +940,9 @@ return Latency; int MaxSuccLatency = 0; - for (std::set::const_iterator I = SU.Succs.begin(), + for (std::set >::const_iterator I = SU.Succs.begin(), E = SU.Succs.end(); I != E; ++I) - MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I)); - - for (std::set::const_iterator I = SU.ChainSuccs.begin(), - E = SU.ChainSuccs.end(); I != E; ++I) - MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(**I)); + MaxSuccLatency = std::max(MaxSuccLatency, CalcLatency(*I->first)); return Latency = MaxSuccLatency + SU.Latency; } @@ -974,24 +960,14 @@ /// of SU, return it, otherwise return null. static SUnit *getSingleUnscheduledPred(SUnit *SU) { SUnit *OnlyAvailablePred = 0; - for (std::set::const_iterator I = SU->Preds.begin(), + for (std::set >::const_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) - if (!(*I)->isScheduled) { + if (!I->first->isScheduled) { // We found an available, but not scheduled, predecessor. If it's the // only one we have found, keep track of it... otherwise give up. - if (OnlyAvailablePred && OnlyAvailablePred != *I) + if (OnlyAvailablePred && OnlyAvailablePred != I->first) return 0; - OnlyAvailablePred = *I; - } - - for (std::set::const_iterator I = SU->ChainSuccs.begin(), - E = SU->ChainSuccs.end(); I != E; ++I) - if (!(*I)->isScheduled) { - // We found an available, but not scheduled, predecessor. If it's the - // only one we have found, keep track of it... otherwise give up. - if (OnlyAvailablePred && OnlyAvailablePred != *I) - return 0; - OnlyAvailablePred = *I; + OnlyAvailablePred = I->first; } return OnlyAvailablePred; @@ -1001,15 +977,11 @@ // Look at all of the successors of this node. Count the number of nodes that // this node is the sole unscheduled node for. unsigned NumNodesBlocking = 0; - for (std::set::const_iterator I = SU->Succs.begin(), + for (std::set >::const_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - if (getSingleUnscheduledPred(*I) == SU) - ++NumNodesBlocking; - - for (std::set::const_iterator I = SU->ChainSuccs.begin(), - E = SU->ChainSuccs.end(); I != E; ++I) - if (getSingleUnscheduledPred(*I) == SU) + if (getSingleUnscheduledPred(I->first) == SU) ++NumNodesBlocking; + NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking; Queue.push(SU); } @@ -1020,13 +992,9 @@ // single predecessor has a higher priority, since scheduling it will make // the node available. void LatencyPriorityQueue::ScheduledNode(SUnit *SU) { - for (std::set::const_iterator I = SU->Succs.begin(), + for (std::set >::const_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - AdjustPriorityOfUnscheduledPreds(*I); - - for (std::set::const_iterator I = SU->ChainSuccs.begin(), - E = SU->ChainSuccs.end(); I != E; ++I) - AdjustPriorityOfUnscheduledPreds(*I); + AdjustPriorityOfUnscheduledPreds(I->first); } /// AdjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just From lattner at cs.uiuc.edu Sat Mar 11 16:28:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 16:28:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603112228.QAA16572@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.42 -> 1.43 --- Log message: Move some methods around so that BU specific code is together, TD specific code is together, and direction independent code is together. --- Diffs of the changes: (+245 -236) ScheduleDAGList.cpp | 481 ++++++++++++++++++++++++++-------------------------- 1 files changed, 245 insertions(+), 236 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.42 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.43 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.42 Sat Mar 11 16:24:20 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Mar 11 16:28:35 2006 @@ -217,6 +217,199 @@ return &SUnits.back(); } +/// BuildSchedUnits - Build SUnits from the selection dag that we are input. +/// This SUnit graph is similar to the SelectionDAG, but represents flagged +/// together nodes with a single SUnit. +void ScheduleDAGList::BuildSchedUnits() { + // Reserve entries in the vector for each of the SUnits we are creating. This + // ensure that reallocation of the vector won't happen, so SUnit*'s won't get + // invalidated. + SUnits.reserve(std::distance(DAG.allnodes_begin(), DAG.allnodes_end())); + + const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); + + for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(), + E = DAG.allnodes_end(); NI != E; ++NI) { + if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. + continue; + + // If this node has already been processed, stop now. + if (SUnitMap[NI]) continue; + + SUnit *NodeSUnit = NewSUnit(NI); + + // See if anything is flagged to this node, if so, add them to flagged + // nodes. Nodes can have at most one flag input and one flag output. Flags + // are required the be the last operand and result of a node. + + // Scan up, adding flagged preds to FlaggedNodes. + SDNode *N = NI; + while (N->getNumOperands() && + N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { + N = N->getOperand(N->getNumOperands()-1).Val; + NodeSUnit->FlaggedNodes.push_back(N); + SUnitMap[N] = NodeSUnit; + } + + // Scan down, adding this node and any flagged succs to FlaggedNodes if they + // have a user of the flag operand. + N = NI; + while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { + SDOperand FlagVal(N, N->getNumValues()-1); + + // There are either zero or one users of the Flag result. + bool HasFlagUse = false; + for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); + UI != E; ++UI) + if (FlagVal.isOperand(*UI)) { + HasFlagUse = true; + NodeSUnit->FlaggedNodes.push_back(N); + SUnitMap[N] = NodeSUnit; + N = *UI; + break; + } + if (!HasFlagUse) break; + } + + // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. + // Update the SUnit + NodeSUnit->Node = N; + SUnitMap[N] = NodeSUnit; + + // Compute the latency for the node. We use the sum of the latencies for + // all nodes flagged together into this SUnit. + if (InstrItins.isEmpty()) { + // No latency information. + NodeSUnit->Latency = 1; + } else { + NodeSUnit->Latency = 0; + if (N->isTargetOpcode()) { + unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode()); + InstrStage *S = InstrItins.begin(SchedClass); + InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + NodeSUnit->Latency += S->Cycles; + } + for (unsigned i = 0, e = NodeSUnit->FlaggedNodes.size(); i != e; ++i) { + SDNode *FNode = NodeSUnit->FlaggedNodes[i]; + if (FNode->isTargetOpcode()) { + unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode()); + InstrStage *S = InstrItins.begin(SchedClass); + InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + NodeSUnit->Latency += S->Cycles; + } + } + } + } + + // Pass 2: add the preds, succs, etc. + for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { + SUnit *SU = &SUnits[su]; + SDNode *MainNode = SU->Node; + + if (MainNode->isTargetOpcode() && + TII->isTwoAddrInstr(MainNode->getTargetOpcode())) + SU->isTwoAddress = true; + + // Find all predecessors and successors of the group. + // Temporarily add N to make code simpler. + SU->FlaggedNodes.push_back(MainNode); + + for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { + SDNode *N = SU->FlaggedNodes[n]; + + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDNode *OpN = N->getOperand(i).Val; + if (isPassiveNode(OpN)) continue; // Not scheduled. + SUnit *OpSU = SUnitMap[OpN]; + assert(OpSU && "Node has no SUnit!"); + if (OpSU == SU) continue; // In the same group. + + MVT::ValueType OpVT = N->getOperand(i).getValueType(); + assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); + bool isChain = OpVT == MVT::Other; + + if (SU->Preds.insert(std::make_pair(OpSU, isChain)).second) { + if (!isChain) { + SU->NumPredsLeft++; + } else { + SU->NumChainPredsLeft++; + } + } + if (OpSU->Succs.insert(std::make_pair(SU, isChain)).second) { + if (!isChain) { + OpSU->NumSuccsLeft++; + } else { + OpSU->NumChainSuccsLeft++; + } + } + } + } + + // Remove MainNode from FlaggedNodes again. + SU->FlaggedNodes.pop_back(); + } + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) + SUnits[su].dumpAll(&DAG)); +} + +/// EmitSchedule - Emit the machine code in scheduled order. +void ScheduleDAGList::EmitSchedule() { + std::map VRBaseMap; + for (unsigned i = 0, e = Sequence.size(); i != e; i++) { + if (SUnit *SU = Sequence[i]) { + for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) + EmitNode(SU->FlaggedNodes[j], VRBaseMap); + EmitNode(SU->Node, VRBaseMap); + } else { + // Null SUnit* is a noop. + EmitNoop(); + } + } +} + +/// dump - dump the schedule. +void ScheduleDAGList::dumpSchedule() const { + for (unsigned i = 0, e = Sequence.size(); i != e; i++) { + if (SUnit *SU = Sequence[i]) + SU->dump(&DAG); + else + std::cerr << "**** NOOP ****\n"; + } +} + +/// Schedule - Schedule the DAG using list scheduling. +/// FIXME: Right now it only supports the burr (bottom up register reducing) +/// heuristic. +void ScheduleDAGList::Schedule() { + DEBUG(std::cerr << "********** List Scheduling **********\n"); + + // Build scheduling units. + BuildSchedUnits(); + + PriorityQueue->initNodes(SUnits); + + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. + if (isBottomUp) + ListScheduleBottomUp(); + else + ListScheduleTopDown(); + + PriorityQueue->releaseState(); + + DEBUG(std::cerr << "*** Final schedule ***\n"); + DEBUG(dumpSchedule()); + DEBUG(std::cerr << "\n"); + + // Emit in scheduled order + EmitSchedule(); +} + +//===----------------------------------------------------------------------===// +// Bottom-Up Scheduling +//===----------------------------------------------------------------------===// + /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain) { @@ -248,36 +441,6 @@ } } } - -/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to -/// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - SuccSU->CycleBound = std::max(SuccSU->CycleBound,CurrCycle + SuccSU->Latency); - - if (!isChain) - SuccSU->NumPredsLeft--; - else - SuccSU->NumChainPredsLeft--; - -#ifndef NDEBUG - if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) { - std::cerr << "*** List scheduling failed! ***\n"; - SuccSU->dump(&DAG); - std::cerr << " has been released too many times!\n"; - abort(); - } -#endif - - if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) { - SuccSU->isAvailable = true; - PriorityQueue->push(SuccSU); - } -} - /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. @@ -297,25 +460,6 @@ CurrCycle++; } -/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending -/// count of its successors. If a successor pending count is zero, add it to -/// the Available queue. -void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) { - DEBUG(std::cerr << "*** Scheduling: "); - DEBUG(SU->dump(&DAG)); - - Sequence.push_back(SU); - - // Bottom up: release successors. - for (std::set >::iterator I = SU->Succs.begin(), - E = SU->Succs.end(); I != E; ++I) { - ReleaseSucc(I->first, I->second); - if (!I->second) - SU->NumSuccsLeft--; - } - CurrCycle++; -} - /// isReady - True if node's lower cycle bound is less or equal to the current /// scheduling cycle. Always true if all nodes have uniform latency 1. static inline bool isReady(SUnit *SU, unsigned CurrCycle) { @@ -374,6 +518,58 @@ #endif } +//===----------------------------------------------------------------------===// +// Top-Down Scheduling +//===----------------------------------------------------------------------===// + +/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to +/// the Available queue is the count reaches zero. Also update its cycle bound. +void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { + // FIXME: the distance between two nodes is not always == the predecessor's + // latency. For example, the reader can very well read the register written + // by the predecessor later than the issue cycle. It also depends on the + // interrupt model (drain vs. freeze). + SuccSU->CycleBound = std::max(SuccSU->CycleBound,CurrCycle + SuccSU->Latency); + + if (!isChain) + SuccSU->NumPredsLeft--; + else + SuccSU->NumChainPredsLeft--; + +#ifndef NDEBUG + if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) { + std::cerr << "*** List scheduling failed! ***\n"; + SuccSU->dump(&DAG); + std::cerr << " has been released too many times!\n"; + abort(); + } +#endif + + if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) { + SuccSU->isAvailable = true; + PriorityQueue->push(SuccSU); + } +} + +/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending +/// count of its successors. If a successor pending count is zero, add it to +/// the Available queue. +void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) { + DEBUG(std::cerr << "*** Scheduling: "); + DEBUG(SU->dump(&DAG)); + + Sequence.push_back(SU); + + // Bottom up: release successors. + for (std::set >::iterator I = SU->Succs.begin(), + E = SU->Succs.end(); I != E; ++I) { + ReleaseSucc(I->first, I->second); + if (!I->second) + SU->NumSuccsLeft--; + } + CurrCycle++; +} + /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. void ScheduleDAGList::ListScheduleTopDown() { @@ -462,193 +658,6 @@ #endif } - -void ScheduleDAGList::BuildSchedUnits() { - // Reserve entries in the vector for each of the SUnits we are creating. This - // ensure that reallocation of the vector won't happen, so SUnit*'s won't get - // invalidated. - SUnits.reserve(std::distance(DAG.allnodes_begin(), DAG.allnodes_end())); - - const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); - - for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(), - E = DAG.allnodes_end(); NI != E; ++NI) { - if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. - continue; - - // If this node has already been processed, stop now. - if (SUnitMap[NI]) continue; - - SUnit *NodeSUnit = NewSUnit(NI); - - // See if anything is flagged to this node, if so, add them to flagged - // nodes. Nodes can have at most one flag input and one flag output. Flags - // are required the be the last operand and result of a node. - - // Scan up, adding flagged preds to FlaggedNodes. - SDNode *N = NI; - while (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { - N = N->getOperand(N->getNumOperands()-1).Val; - NodeSUnit->FlaggedNodes.push_back(N); - SUnitMap[N] = NodeSUnit; - } - - // Scan down, adding this node and any flagged succs to FlaggedNodes if they - // have a user of the flag operand. - N = NI; - while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { - SDOperand FlagVal(N, N->getNumValues()-1); - - // There are either zero or one users of the Flag result. - bool HasFlagUse = false; - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); - UI != E; ++UI) - if (FlagVal.isOperand(*UI)) { - HasFlagUse = true; - NodeSUnit->FlaggedNodes.push_back(N); - SUnitMap[N] = NodeSUnit; - N = *UI; - break; - } - if (!HasFlagUse) break; - } - - // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. - // Update the SUnit - NodeSUnit->Node = N; - SUnitMap[N] = NodeSUnit; - - // Compute the latency for the node. We use the sum of the latencies for - // all nodes flagged together into this SUnit. - if (InstrItins.isEmpty()) { - // No latency information. - NodeSUnit->Latency = 1; - } else { - NodeSUnit->Latency = 0; - if (N->isTargetOpcode()) { - unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode()); - InstrStage *S = InstrItins.begin(SchedClass); - InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - NodeSUnit->Latency += S->Cycles; - } - for (unsigned i = 0, e = NodeSUnit->FlaggedNodes.size(); i != e; ++i) { - SDNode *FNode = NodeSUnit->FlaggedNodes[i]; - if (FNode->isTargetOpcode()) { - unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode()); - InstrStage *S = InstrItins.begin(SchedClass); - InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - NodeSUnit->Latency += S->Cycles; - } - } - } - } - - // Pass 2: add the preds, succs, etc. - for (unsigned su = 0, e = SUnits.size(); su != e; ++su) { - SUnit *SU = &SUnits[su]; - SDNode *MainNode = SU->Node; - - if (MainNode->isTargetOpcode() && - TII->isTwoAddrInstr(MainNode->getTargetOpcode())) - SU->isTwoAddress = true; - - // Find all predecessors and successors of the group. - // Temporarily add N to make code simpler. - SU->FlaggedNodes.push_back(MainNode); - - for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { - SDNode *N = SU->FlaggedNodes[n]; - - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - SDNode *OpN = N->getOperand(i).Val; - if (isPassiveNode(OpN)) continue; // Not scheduled. - SUnit *OpSU = SUnitMap[OpN]; - assert(OpSU && "Node has no SUnit!"); - if (OpSU == SU) continue; // In the same group. - - MVT::ValueType OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); - bool isChain = OpVT == MVT::Other; - - if (SU->Preds.insert(std::make_pair(OpSU, isChain)).second) { - if (!isChain) { - SU->NumPredsLeft++; - } else { - SU->NumChainPredsLeft++; - } - } - if (OpSU->Succs.insert(std::make_pair(SU, isChain)).second) { - if (!isChain) { - OpSU->NumSuccsLeft++; - } else { - OpSU->NumChainSuccsLeft++; - } - } - } - } - - // Remove MainNode from FlaggedNodes again. - SU->FlaggedNodes.pop_back(); - } - DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) - SUnits[su].dumpAll(&DAG)); -} - -/// EmitSchedule - Emit the machine code in scheduled order. -void ScheduleDAGList::EmitSchedule() { - std::map VRBaseMap; - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) { - for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++) - EmitNode(SU->FlaggedNodes[j], VRBaseMap); - EmitNode(SU->Node, VRBaseMap); - } else { - // Null SUnit* is a noop. - EmitNoop(); - } - } -} - -/// dump - dump the schedule. -void ScheduleDAGList::dumpSchedule() const { - for (unsigned i = 0, e = Sequence.size(); i != e; i++) { - if (SUnit *SU = Sequence[i]) - SU->dump(&DAG); - else - std::cerr << "**** NOOP ****\n"; - } -} - -/// Schedule - Schedule the DAG using list scheduling. -/// FIXME: Right now it only supports the burr (bottom up register reducing) -/// heuristic. -void ScheduleDAGList::Schedule() { - DEBUG(std::cerr << "********** List Scheduling **********\n"); - - // Build scheduling units. - BuildSchedUnits(); - - PriorityQueue->initNodes(SUnits); - - // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. - if (isBottomUp) - ListScheduleBottomUp(); - else - ListScheduleTopDown(); - - PriorityQueue->releaseState(); - - DEBUG(std::cerr << "*** Final schedule ***\n"); - DEBUG(dumpSchedule()); - DEBUG(std::cerr << "\n"); - - // Emit in scheduled order - EmitSchedule(); -} - //===----------------------------------------------------------------------===// // RegReductionPriorityQueue Implementation //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sat Mar 11 16:34:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 16:34:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603112234.QAA16624@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.43 -> 1.44 --- Log message: Make CurrCycle a local var instead of an instance var --- Diffs of the changes: (+20 -19) ScheduleDAGList.cpp | 39 ++++++++++++++++++++------------------- 1 files changed, 20 insertions(+), 19 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.43 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.44 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.43 Sat Mar 11 16:28:35 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Mar 11 16:34:41 2006 @@ -160,8 +160,6 @@ std::map SUnitMap; // The schedule. Null SUnit*'s represent noop instructions. std::vector Sequence; - // Current scheduling cycle. - unsigned CurrCycle; // The scheduling units. std::vector SUnits; @@ -181,8 +179,7 @@ const TargetMachine &tm, bool isbottomup, SchedulingPriorityQueue *priorityqueue, HazardRecognizer *HR) - : ScheduleDAG(dag, bb, tm), - CurrCycle(0), isBottomUp(isbottomup), + : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), PriorityQueue(priorityqueue), HazardRec(HR) { } @@ -197,10 +194,10 @@ private: SUnit *NewSUnit(SDNode *N); - void ReleasePred(SUnit *PredSU, bool isChain); - void ReleaseSucc(SUnit *SuccSU, bool isChain); - void ScheduleNodeBottomUp(SUnit *SU); - void ScheduleNodeTopDown(SUnit *SU); + void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle); + void ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle); + void ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle); + void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); void ListScheduleBottomUp(); void BuildSchedUnits(); @@ -412,7 +409,8 @@ /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain) { +void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain, + unsigned CurrCycle) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the @@ -444,7 +442,7 @@ /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU) { +void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurrCycle) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG)); @@ -453,11 +451,10 @@ // Bottom up: release predecessors for (std::set >::iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - ReleasePred(I->first, I->second); + ReleasePred(I->first, I->second, CurrCycle); if (!I->second) SU->NumPredsLeft--; } - CurrCycle++; } /// isReady - True if node's lower cycle bound is less or equal to the current @@ -469,6 +466,7 @@ /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up /// schedulers. void ScheduleDAGList::ListScheduleBottomUp() { + unsigned CurrCycle = 0; // Add root to Available queue. PriorityQueue->push(SUnitMap[DAG.getRoot().Val]); @@ -487,7 +485,8 @@ PriorityQueue->push_all(NotReady); NotReady.clear(); - ScheduleNodeBottomUp(CurrNode); + ScheduleNodeBottomUp(CurrNode, CurrCycle); + CurrCycle++; CurrNode->isScheduled = true; PriorityQueue->ScheduledNode(CurrNode); } @@ -524,7 +523,8 @@ /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { +void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain, + unsigned CurrCycle) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the @@ -554,7 +554,7 @@ /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU) { +void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurrCycle) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG)); @@ -563,19 +563,19 @@ // Bottom up: release successors. for (std::set >::iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - ReleaseSucc(I->first, I->second); + ReleaseSucc(I->first, I->second, CurrCycle); if (!I->second) SU->NumSuccsLeft--; } - CurrCycle++; } /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. void ScheduleDAGList::ListScheduleTopDown() { + unsigned CurrCycle = 0; // Emit the entry node first. SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; - ScheduleNodeTopDown(Entry); + ScheduleNodeTopDown(Entry, CurrCycle); HazardRec->EmitInstruction(Entry->Node); // All leaves to Available queue. @@ -621,7 +621,8 @@ // If we found a node to schedule, do it now. if (FoundNode) { - ScheduleNodeTopDown(FoundNode); + ScheduleNodeTopDown(FoundNode, CurrCycle); + CurrCycle++; // Fixme don't increment for pseudo-ops! HazardRec->EmitInstruction(FoundNode->Node); FoundNode->isScheduled = true; PriorityQueue->ScheduledNode(FoundNode); From lattner at cs.uiuc.edu Sat Mar 11 16:44:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 16:44:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603112244.QAA16706@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.44 -> 1.45 --- Log message: rename priorityqueue -> availablequeue. When a node is scheduled, remember which cycle it lands on. --- Diffs of the changes: (+37 -34) ScheduleDAGList.cpp | 71 +++++++++++++++++++++++++++------------------------- 1 files changed, 37 insertions(+), 34 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.44 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.45 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.44 Sat Mar 11 16:34:41 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Mar 11 16:44:37 2006 @@ -57,6 +57,7 @@ bool isScheduled : 1; // True once scheduled. unsigned short Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. + unsigned Cycle; // Once scheduled, the cycle of the op. unsigned NodeNum; // Entry # of node in the node vector. SUnit(SDNode *node, unsigned nodenum) @@ -64,7 +65,7 @@ NumChainPredsLeft(0), NumChainSuccsLeft(0), isTwoAddress(false), isDefNUseOperand(false), isAvailable(false), isScheduled(false), - Latency(0), CycleBound(0), NodeNum(nodenum) {} + Latency(0), CycleBound(0), Cycle(0), NodeNum(nodenum) {} void dump(const SelectionDAG *G) const; void dumpAll(const SelectionDAG *G) const; @@ -168,8 +169,9 @@ /// it is top-down. bool isBottomUp; - /// PriorityQueue - The priority queue to use. - SchedulingPriorityQueue *PriorityQueue; + /// AvailableQueue - The priority queue to use for the available SUnits. + /// + SchedulingPriorityQueue *AvailableQueue; /// HazardRec - The hazard recognizer to use. HazardRecognizer *HazardRec; @@ -177,15 +179,15 @@ public: ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, - SchedulingPriorityQueue *priorityqueue, + SchedulingPriorityQueue *availqueue, HazardRecognizer *HR) : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), - PriorityQueue(priorityqueue), HazardRec(HR) { + AvailableQueue(availqueue), HazardRec(HR) { } ~ScheduleDAGList() { delete HazardRec; - delete PriorityQueue; + delete AvailableQueue; } void Schedule(); @@ -385,7 +387,7 @@ // Build scheduling units. BuildSchedUnits(); - PriorityQueue->initNodes(SUnits); + AvailableQueue->initNodes(SUnits); // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) @@ -393,7 +395,7 @@ else ListScheduleTopDown(); - PriorityQueue->releaseState(); + AvailableQueue->releaseState(); DEBUG(std::cerr << "*** Final schedule ***\n"); DEBUG(dumpSchedule()); @@ -410,12 +412,12 @@ /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain, - unsigned CurrCycle) { + unsigned CurCycle) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound,CurrCycle + PredSU->Latency); + PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency); if (!isChain) PredSU->NumSuccsLeft--; @@ -435,23 +437,26 @@ // EntryToken has to go last! Special case it here. if (PredSU->Node->getOpcode() != ISD::EntryToken) { PredSU->isAvailable = true; - PriorityQueue->push(PredSU); + AvailableQueue->push(PredSU); } } } /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurrCycle) { +void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG)); + SU->Cycle = CurCycle; Sequence.push_back(SU); // Bottom up: release predecessors for (std::set >::iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - ReleasePred(I->first, I->second, CurrCycle); + ReleasePred(I->first, I->second, CurCycle); + // FIXME: This is something used by the priority function that it should + // calculate directly. if (!I->second) SU->NumPredsLeft--; } @@ -468,27 +473,27 @@ void ScheduleDAGList::ListScheduleBottomUp() { unsigned CurrCycle = 0; // Add root to Available queue. - PriorityQueue->push(SUnitMap[DAG.getRoot().Val]); + AvailableQueue->push(SUnitMap[DAG.getRoot().Val]); // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; - while (!PriorityQueue->empty()) { - SUnit *CurrNode = PriorityQueue->pop(); + while (!AvailableQueue->empty()) { + SUnit *CurrNode = AvailableQueue->pop(); while (!isReady(CurrNode, CurrCycle)) { NotReady.push_back(CurrNode); - CurrNode = PriorityQueue->pop(); + CurrNode = AvailableQueue->pop(); } // Add the nodes that aren't ready back onto the available list. - PriorityQueue->push_all(NotReady); + AvailableQueue->push_all(NotReady); NotReady.clear(); ScheduleNodeBottomUp(CurrNode, CurrCycle); CurrCycle++; CurrNode->isScheduled = true; - PriorityQueue->ScheduledNode(CurrNode); + AvailableQueue->ScheduledNode(CurrNode); } // Add entry node last @@ -524,12 +529,12 @@ /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain, - unsigned CurrCycle) { + unsigned CurCycle) { // FIXME: the distance between two nodes is not always == the predecessor's // latency. For example, the reader can very well read the register written // by the predecessor later than the issue cycle. It also depends on the // interrupt model (drain vs. freeze). - SuccSU->CycleBound = std::max(SuccSU->CycleBound,CurrCycle + SuccSU->Latency); + SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency); if (!isChain) SuccSU->NumPredsLeft--; @@ -547,26 +552,24 @@ if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) { SuccSU->isAvailable = true; - PriorityQueue->push(SuccSU); + AvailableQueue->push(SuccSU); } } /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurrCycle) { +void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { DEBUG(std::cerr << "*** Scheduling: "); DEBUG(SU->dump(&DAG)); Sequence.push_back(SU); + SU->Cycle = CurCycle; // Bottom up: release successors. for (std::set >::iterator I = SU->Succs.begin(), - E = SU->Succs.end(); I != E; ++I) { - ReleaseSucc(I->first, I->second, CurrCycle); - if (!I->second) - SU->NumSuccsLeft--; - } + E = SU->Succs.end(); I != E; ++I) + ReleaseSucc(I->first, I->second, CurCycle); } /// ListScheduleTopDown - The main loop of list scheduling for top-down @@ -582,18 +585,18 @@ for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // It is available if it has no predecessors. if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) - PriorityQueue->push(&SUnits[i]); + AvailableQueue->push(&SUnits[i]); } // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; - while (!PriorityQueue->empty()) { + while (!AvailableQueue->empty()) { SUnit *FoundNode = 0; bool HasNoopHazards = false; do { - SUnit *CurNode = PriorityQueue->pop(); + SUnit *CurNode = AvailableQueue->pop(); // Get the node represented by this SUnit. SDNode *N = CurNode->Node; @@ -613,10 +616,10 @@ HasNoopHazards |= HT == HazardRecognizer::NoopHazard; NotReady.push_back(CurNode); - } while (!PriorityQueue->empty()); + } while (!AvailableQueue->empty()); // Add the nodes that aren't ready back onto the available list. - PriorityQueue->push_all(NotReady); + AvailableQueue->push_all(NotReady); NotReady.clear(); // If we found a node to schedule, do it now. @@ -625,7 +628,7 @@ CurrCycle++; // Fixme don't increment for pseudo-ops! HazardRec->EmitInstruction(FoundNode->Node); FoundNode->isScheduled = true; - PriorityQueue->ScheduledNode(FoundNode); + AvailableQueue->ScheduledNode(FoundNode); } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. From lattner at cs.uiuc.edu Sat Mar 11 18:04:40 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 18:04:40 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.td Message-ID: <200603120004.SAA17158@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.td updated: 1.4 -> 1.5 --- Log message: Mark llvm.stacksave as only reading memory, this fixes Regression/Transforms/InstCombine/stacksaverestore.ll --- Diffs of the changes: (+1 -1) Intrinsics.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Intrinsics.td diff -u llvm/include/llvm/Intrinsics.td:1.4 llvm/include/llvm/Intrinsics.td:1.5 --- llvm/include/llvm/Intrinsics.td:1.4 Fri Mar 10 12:01:03 2006 +++ llvm/include/llvm/Intrinsics.td Sat Mar 11 18:04:28 2006 @@ -112,7 +112,7 @@ // def int_returnaddress : Intrinsic<[llvm_ptr_ty, llvm_uint_ty], [InstrNoMem]>; def int_frameaddress : Intrinsic<[llvm_ptr_ty, llvm_uint_ty], [InstrNoMem]>; -def int_stacksave : Intrinsic<[llvm_ptr_ty]>; +def int_stacksave : Intrinsic<[llvm_ptr_ty], [IntrReadMem]>; def int_stackrestore : Intrinsic<[llvm_void_ty, llvm_ptr_ty]>; def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_uint_ty, llvm_uint_ty]>; From lattner at cs.uiuc.edu Sat Mar 11 18:39:09 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 18:39:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603120039.SAA17475@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.45 -> 1.46 --- Log message: As a pending queue data structure to keep track of instructions whose operands have all issued, but whose results are not yet available. This allows us to compile: int G; int test(int A, int B, int* P) { return (G+A)*(B+1); } to: _test: lis r2, ha16(L_G$non_lazy_ptr) addi r4, r4, 1 lwz r2, lo16(L_G$non_lazy_ptr)(r2) lwz r2, 0(r2) add r2, r2, r3 mullw r3, r2, r4 blr instead of this, which has a stall between the lis/lwz: _test: lis r2, ha16(L_G$non_lazy_ptr) lwz r2, lo16(L_G$non_lazy_ptr)(r2) addi r4, r4, 1 lwz r2, 0(r2) add r2, r2, r3 mullw r3, r2, r4 blr --- Diffs of the changes: (+62 -36) ScheduleDAGList.cpp | 98 ++++++++++++++++++++++++++++++++-------------------- 1 files changed, 62 insertions(+), 36 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.45 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.46 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.45 Sat Mar 11 16:44:37 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Mar 11 18:38:57 2006 @@ -53,6 +53,7 @@ short NumChainSuccsLeft; // # of chain succs not scheduled. bool isTwoAddress : 1; // Is a two-address instruction. bool isDefNUseOperand : 1; // Is a def&use operand. + bool isPending : 1; // True once pending. bool isAvailable : 1; // True once available. bool isScheduled : 1; // True once scheduled. unsigned short Latency; // Node latency. @@ -64,7 +65,7 @@ : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), isTwoAddress(false), isDefNUseOperand(false), - isAvailable(false), isScheduled(false), + isPending(false), isAvailable(false), isScheduled(false), Latency(0), CycleBound(0), Cycle(0), NodeNum(nodenum) {} void dump(const SelectionDAG *G) const; @@ -173,6 +174,13 @@ /// SchedulingPriorityQueue *AvailableQueue; + /// PendingQueue - This contains all of the instructions whose operands have + /// been issued, but their results are not ready yet (due to the latency of + /// the operation). Once the operands becomes available, the instruction is + /// added to the AvailableQueue. This keeps track of each SUnit and the + /// number of cycles left to execute before the operation is available. + std::vector > PendingQueue; + /// HazardRec - The hazard recognizer to use. HazardRecognizer *HazardRec; @@ -197,7 +205,7 @@ private: SUnit *NewSUnit(SDNode *N); void ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle); - void ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle); + void ReleaseSucc(SUnit *SuccSU, bool isChain); void ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); @@ -445,7 +453,7 @@ /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. void ScheduleDAGList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { - DEBUG(std::cerr << "*** Scheduling: "); + DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(&DAG)); SU->Cycle = CurCycle; @@ -527,32 +535,29 @@ //===----------------------------------------------------------------------===// /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to -/// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain, - unsigned CurCycle) { - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - SuccSU->CycleBound = std::max(SuccSU->CycleBound, CurCycle + SuccSU->Latency); - +/// the PendingQueue if the count reaches zero. +void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) { if (!isChain) SuccSU->NumPredsLeft--; else SuccSU->NumChainPredsLeft--; -#ifndef NDEBUG - if (SuccSU->NumPredsLeft < 0 || SuccSU->NumChainPredsLeft < 0) { - std::cerr << "*** List scheduling failed! ***\n"; - SuccSU->dump(&DAG); - std::cerr << " has been released too many times!\n"; - abort(); - } -#endif + assert(SuccSU->NumPredsLeft >= 0 && SuccSU->NumChainPredsLeft >= 0 && + "List scheduling internal error"); if ((SuccSU->NumPredsLeft + SuccSU->NumChainPredsLeft) == 0) { - SuccSU->isAvailable = true; - AvailableQueue->push(SuccSU); + // Compute how many cycles it will be before this actually becomes + // available. This is the max of the start time of all predecessors plus + // their latencies. + unsigned AvailableCycle = 0; + for (std::set >::iterator I = SuccSU->Preds.begin(), + E = SuccSU->Preds.end(); I != E; ++I) { + AvailableCycle = std::max(AvailableCycle, + I->first->Cycle + I->first->Latency); + } + + PendingQueue.push_back(std::make_pair(AvailableCycle, SuccSU)); + SuccSU->isPending = true; } } @@ -560,7 +565,7 @@ /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { - DEBUG(std::cerr << "*** Scheduling: "); + DEBUG(std::cerr << "*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(&DAG)); Sequence.push_back(SU); @@ -569,33 +574,49 @@ // Bottom up: release successors. for (std::set >::iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) - ReleaseSucc(I->first, I->second, CurCycle); + ReleaseSucc(I->first, I->second); } /// ListScheduleTopDown - The main loop of list scheduling for top-down /// schedulers. void ScheduleDAGList::ListScheduleTopDown() { - unsigned CurrCycle = 0; - // Emit the entry node first. + unsigned CurCycle = 0; SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; - ScheduleNodeTopDown(Entry, CurrCycle); - HazardRec->EmitInstruction(Entry->Node); - + // All leaves to Available queue. for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { // It is available if it has no predecessors. - if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) + if (SUnits[i].Preds.size() == 0 && &SUnits[i] != Entry) { AvailableQueue->push(&SUnits[i]); + SUnits[i].isAvailable = SUnits[i].isPending = true; + } } + // Emit the entry node first. + ScheduleNodeTopDown(Entry, CurCycle); + HazardRec->EmitInstruction(Entry->Node); + // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; - while (!AvailableQueue->empty()) { + while (!AvailableQueue->empty() || !PendingQueue.empty()) { + // Check to see if any of the pending instructions are ready to issue. If + // so, add them to the available queue. + for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) + if (PendingQueue[i].first == CurCycle) { + AvailableQueue->push(PendingQueue[i].second); + PendingQueue[i].second->isAvailable = true; + PendingQueue[i] = PendingQueue.back(); + PendingQueue.pop_back(); + --i; --e; + } else { + assert(PendingQueue[i].first > CurCycle && "Negative latency?"); + } + SUnit *FoundNode = 0; bool HasNoopHazards = false; - do { + while (!AvailableQueue->empty()) { SUnit *CurNode = AvailableQueue->pop(); // Get the node represented by this SUnit. @@ -616,7 +637,7 @@ HasNoopHazards |= HT == HazardRecognizer::NoopHazard; NotReady.push_back(CurNode); - } while (!AvailableQueue->empty()); + } // Add the nodes that aren't ready back onto the available list. AvailableQueue->push_all(NotReady); @@ -624,11 +645,15 @@ // If we found a node to schedule, do it now. if (FoundNode) { - ScheduleNodeTopDown(FoundNode, CurrCycle); - CurrCycle++; // Fixme don't increment for pseudo-ops! + ScheduleNodeTopDown(FoundNode, CurCycle); HazardRec->EmitInstruction(FoundNode->Node); FoundNode->isScheduled = true; AvailableQueue->ScheduledNode(FoundNode); + + // If this is a pseudo-op node, we don't want to increment the current + // cycle. + if (FoundNode->Latency == 0) + continue; // Don't increment for pseudo-ops! } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. @@ -644,6 +669,7 @@ Sequence.push_back(0); // NULL SUnit* -> noop ++NumNoops; } + ++CurCycle; } #ifndef NDEBUG @@ -1017,7 +1043,7 @@ /// scheduled will make this node available, so it is better than some other /// node of the same priority that will not make a node available. void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { - if (SU->isAvailable) return; // All preds scheduled. + if (SU->isPending) return; // All preds scheduled. SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU); if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return; From lattner at cs.uiuc.edu Sat Mar 11 21:52:21 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 11 Mar 2006 21:52:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603120352.VAA18238@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.46 -> 1.47 --- Log message: Chain operands aren't real uses: they don't require the full latency of the predecessor to finish before they can start. --- Diffs of the changes: (+10 -4) ScheduleDAGList.cpp | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.46 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.47 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.46 Sat Mar 11 18:38:57 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Mar 11 21:52:09 2006 @@ -387,8 +387,6 @@ } /// Schedule - Schedule the DAG using list scheduling. -/// FIXME: Right now it only supports the burr (bottom up register reducing) -/// heuristic. void ScheduleDAGList::Schedule() { DEBUG(std::cerr << "********** List Scheduling **********\n"); @@ -552,8 +550,16 @@ unsigned AvailableCycle = 0; for (std::set >::iterator I = SuccSU->Preds.begin(), E = SuccSU->Preds.end(); I != E; ++I) { - AvailableCycle = std::max(AvailableCycle, - I->first->Cycle + I->first->Latency); + // If this is a token edge, we don't need to wait for the full latency of + // the preceeding instruction (e.g. a long-latency load) unless there is + // also some other data dependence. + unsigned PredDoneCycle = I->first->Cycle; + if (!I->second) + PredDoneCycle += I->first->Latency; + else + PredDoneCycle += 1; + + AvailableCycle = std::max(AvailableCycle, PredDoneCycle); } PendingQueue.push_back(std::make_pair(AvailableCycle, SuccSU)); From lattner at cs.uiuc.edu Sun Mar 12 03:01:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 12 Mar 2006 03:01:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603120901.DAA29408@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.47 -> 1.48 --- Log message: Don't advance the hazard recognizer when there are no hazards and no instructions to be emitted. Don't add one to the latency of a completed instruction if the latency of the op is 0. --- Diffs of the changes: (+40 -25) ScheduleDAGList.cpp | 65 ++++++++++++++++++++++++++++++++-------------------- 1 files changed, 40 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.47 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.48 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.47 Sat Mar 11 21:52:09 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sun Mar 12 03:01:41 2006 @@ -357,6 +357,8 @@ // Remove MainNode from FlaggedNodes again. SU->FlaggedNodes.pop_back(); } + + return; DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(&DAG)); } @@ -550,14 +552,14 @@ unsigned AvailableCycle = 0; for (std::set >::iterator I = SuccSU->Preds.begin(), E = SuccSU->Preds.end(); I != E; ++I) { - // If this is a token edge, we don't need to wait for the full latency of - // the preceeding instruction (e.g. a long-latency load) unless there is - // also some other data dependence. + // If this is a token edge, we don't need to wait for the latency of the + // preceeding instruction (e.g. a long-latency load) unless there is also + // some other data dependence. unsigned PredDoneCycle = I->first->Cycle; if (!I->second) PredDoneCycle += I->first->Latency; - else - PredDoneCycle += 1; + else if (I->first->Latency) + PredDoneCycle += 1; AvailableCycle = std::max(AvailableCycle, PredDoneCycle); } @@ -608,7 +610,7 @@ while (!AvailableQueue->empty() || !PendingQueue.empty()) { // Check to see if any of the pending instructions are ready to issue. If // so, add them to the available queue. - for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) + for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { if (PendingQueue[i].first == CurCycle) { AvailableQueue->push(PendingQueue[i].second); PendingQueue[i].second->isAvailable = true; @@ -618,54 +620,67 @@ } else { assert(PendingQueue[i].first > CurCycle && "Negative latency?"); } + } - SUnit *FoundNode = 0; + // If there are no instructions available, don't try to issue anything, and + // don't advance the hazard recognizer. + if (AvailableQueue->empty()) { + ++CurCycle; + continue; + } + SUnit *FoundSUnit = 0; + SDNode *FoundNode = 0; + bool HasNoopHazards = false; while (!AvailableQueue->empty()) { - SUnit *CurNode = AvailableQueue->pop(); + SUnit *CurSUnit = AvailableQueue->pop(); // Get the node represented by this SUnit. - SDNode *N = CurNode->Node; + FoundNode = CurSUnit->Node; + // If this is a pseudo op, like copyfromreg, look to see if there is a // real target node flagged to it. If so, use the target node. - for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); - N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i) - N = CurNode->FlaggedNodes[i]; + for (unsigned i = 0, e = CurSUnit->FlaggedNodes.size(); + FoundNode->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i) + FoundNode = CurSUnit->FlaggedNodes[i]; - HazardRecognizer::HazardType HT = HazardRec->getHazardType(N); + HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode); if (HT == HazardRecognizer::NoHazard) { - FoundNode = CurNode; + FoundSUnit = CurSUnit; break; } // Remember if this is a noop hazard. HasNoopHazards |= HT == HazardRecognizer::NoopHazard; - NotReady.push_back(CurNode); + NotReady.push_back(CurSUnit); } // Add the nodes that aren't ready back onto the available list. - AvailableQueue->push_all(NotReady); - NotReady.clear(); + if (!NotReady.empty()) { + AvailableQueue->push_all(NotReady); + NotReady.clear(); + } // If we found a node to schedule, do it now. - if (FoundNode) { - ScheduleNodeTopDown(FoundNode, CurCycle); - HazardRec->EmitInstruction(FoundNode->Node); - FoundNode->isScheduled = true; - AvailableQueue->ScheduledNode(FoundNode); + if (FoundSUnit) { + ScheduleNodeTopDown(FoundSUnit, CurCycle); + HazardRec->EmitInstruction(FoundNode); + FoundSUnit->isScheduled = true; + AvailableQueue->ScheduledNode(FoundSUnit); // If this is a pseudo-op node, we don't want to increment the current // cycle. - if (FoundNode->Latency == 0) - continue; // Don't increment for pseudo-ops! + if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops! + ++CurCycle; } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. DEBUG(std::cerr << "*** Advancing cycle, no work to do\n"); HazardRec->AdvanceCycle(); ++NumStalls; + ++CurCycle; } else { // Otherwise, we have no instructions to issue and we have instructions // that will fault if we don't do this right. This is the case for @@ -674,8 +689,8 @@ HazardRec->EmitNoop(); Sequence.push_back(0); // NULL SUnit* -> noop ++NumNoops; + ++CurCycle; } - ++CurCycle; } #ifndef NDEBUG From lattner at cs.uiuc.edu Sun Mar 12 03:14:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 12 Mar 2006 03:14:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.td PPCHazardRecognizers.cpp PPCHazardRecognizers.h PPCISelDAGToDAG.cpp PPCInstrFormats.td PPCInstrInfo.h PPCInstrInfo.td Message-ID: <200603120914.DAA18637@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.td updated: 1.12 -> 1.13 PPCHazardRecognizers.cpp updated: 1.8 -> 1.9 PPCHazardRecognizers.h updated: 1.4 -> 1.5 PPCISelDAGToDAG.cpp updated: 1.163 -> 1.164 PPCInstrFormats.td updated: 1.64 -> 1.65 PPCInstrInfo.h updated: 1.12 -> 1.13 PPCInstrInfo.td updated: 1.179 -> 1.180 --- Log message: Several big changes: 1. Use flags on the instructions in the .td file to indicate the PPC970 unit type instead of a table in the .cpp file. Much cleaner. 2. Change the hazard recognizer to build d-groups according to the actual algorithm used, not my flawed understanding of it. 3. Model "must be in the first slot" and "must be the only instr in a group" accurately. --- Diffs of the changes: (+317 -213) PPC.td | 21 +++ PPCHazardRecognizers.cpp | 282 ++++++++++++++++++++++++----------------------- PPCHazardRecognizers.h | 32 ++--- PPCISelDAGToDAG.cpp | 4 PPCInstrFormats.td | 22 +++ PPCInstrInfo.h | 37 ++++++ PPCInstrInfo.td | 132 +++++++++++++--------- 7 files changed, 317 insertions(+), 213 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.td diff -u llvm/lib/Target/PowerPC/PPC.td:1.12 llvm/lib/Target/PowerPC/PPC.td:1.13 --- llvm/lib/Target/PowerPC/PPC.td:1.12 Tue Feb 28 01:08:22 2006 +++ llvm/lib/Target/PowerPC/PPC.td Sun Mar 12 03:13:49 2006 @@ -67,17 +67,32 @@ Feature64Bit /*, Feature64BitRegs */]>; +def PPCInstrInfo : InstrInfo { + // Define how we want to layout our TargetSpecific information field... This + // should be kept up-to-date with the fields in the PPCInstrInfo.h file. + let TSFlagsFields = ["PPC970_First", + "PPC970_Single", + "PPC970_Unit"]; + let TSFlagsShifts = [0, + 1, + 2]; + + let isLittleEndianEncoding = 1; +} + + def PPC : Target { // Pointers on PPC are 32-bits in size. let PointerType = i32; + // Information about the instructions. + let InstructionSet = PPCInstrInfo; + + // According to the Mach-O Runtime ABI, these regs are nonvolatile across // calls let CalleeSavedRegisters = [R1, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31, CR2, CR3, CR4, LR]; - - // Pull in Instruction Info: - let InstructionSet = PowerPCInstrInfo; } Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.8 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.9 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.8 Sat Mar 11 15:49:49 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Sun Mar 12 03:13:49 2006 @@ -14,6 +14,7 @@ #define DEBUG_TYPE "sched" #include "PPCHazardRecognizers.h" #include "PPC.h" +#include "PPCInstrInfo.h" #include "llvm/Support/Debug.h" #include using namespace llvm; @@ -23,15 +24,14 @@ // PowerPC 970 Hazard Recognizer // // This models the dispatch group formation of the PPC970 processor. Dispatch -// groups are bundles of up to five instructions that can contain up to two ALU -// (aka FXU) ops, two FPU ops, two Load/Store ops, one CR op, one VALU op, one -// VPERM op, and one BRANCH op. If the code contains more instructions in a -// sequence than the dispatch group can contain (e.g. three loads in a row) the -// processor terminates the dispatch group early, wasting execution resources. +// groups are bundles of up to five instructions that can contain various mixes +// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one +// branch instruction per-cycle. // -// In addition to these restrictions, there are a number of other restrictions: -// some instructions, e.g. branches, are required to be the last instruction in -// a group. Additionally, only branches can issue in the 5th (last) slot. +// There are a number of restrictions to dispatch group formation: some +// instructions can only be issued in the first slot of a dispatch group, & some +// instructions fill an entire dispatch group. Additionally, only branches can +// issue in the 5th (last) slot. // // Finally, there are a number of "structural" hazards on the PPC970. These // conditions cause large performance penalties due to misprediction, recovery, @@ -41,8 +41,6 @@ // conditions, we insert no-op instructions when appropriate. // // FIXME: This is missing some significant cases: -// -1. Handle all of the instruction types in GetInstrType. -// 0. Handling of instructions that must be the first/last in a group. // 1. Modeling of microcoded instructions. // 2. Handling of cracked instructions. // 3. Handling of serialized operations. @@ -50,103 +48,70 @@ // e.g. integer divides that only execute in the second slot. // -PPCHazardRecognizer970::PPCHazardRecognizer970() { +PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii) + : TII(tii) { EndDispatchGroup(); } void PPCHazardRecognizer970::EndDispatchGroup() { DEBUG(std::cerr << "=== Start of dispatch group\n"); - // Pipeline units. - NumFXU = NumLSU = NumFPU = 0; - HasCR = HasSPR = HasVALU = HasVPERM = false; NumIssued = 0; // Structural hazard info. HasCTRSet = false; - StorePtr1 = StorePtr2 = SDOperand(); - StoreSize = 0; + NumStores = 0; } -PPCHazardRecognizer970::PPC970InstrType -PPCHazardRecognizer970::GetInstrType(unsigned Opcode) { - if (Opcode < ISD::BUILTIN_OP_END) - return PseudoInst; +PPCII::PPC970_Unit +PPCHazardRecognizer970::GetInstrType(unsigned Opcode, + bool &isFirst, bool &isSingle, + bool &isLoad, bool &isStore){ + if (Opcode < ISD::BUILTIN_OP_END) { + isFirst = isSingle = isLoad = isStore = false; + return PPCII::PPC970_Pseudo; + } Opcode -= ISD::BUILTIN_OP_END; - switch (Opcode) { - case PPC::FMRSD: return PseudoInst; // Usually coallesced away. - case PPC::BCTRL: - case PPC::BL: - case PPC::BLA: - case PPC::BLR: - return BR; - case PPC::MCRF: - case PPC::MFCR: - case PPC::MFOCRF: - return CR; - case PPC::MFLR: - case PPC::MFCTR: - case PPC::MTLR: - case PPC::MTCTR: - return SPR; - case PPC::LFS: - case PPC::LFD: - case PPC::LWZ: - case PPC::LFSX: - case PPC::LWZX: - case PPC::LBZ: - case PPC::LHA: - case PPC::LHZ: - case PPC::LWZU: - return LSU_LD; - case PPC::STFS: - case PPC::STFD: - case PPC::STW: - case PPC::STB: - case PPC::STH: - case PPC::STWU: - return LSU_ST; - case PPC::DIVW: - case PPC::DIVWU: - case PPC::DIVD: - case PPC::DIVDU: - return FXU_FIRST; - case PPC::FADDS: - case PPC::FCTIWZ: - case PPC::FRSP: - case PPC::FSUB: - return FPU; - } + const TargetInstrDescriptor &TID = TII.get(Opcode); + + isLoad = TID.Flags & M_LOAD_FLAG; + isStore = TID.Flags & M_STORE_FLAG; - return FXU; + unsigned TSFlags = TID.TSFlags; + + isFirst = TSFlags & PPCII::PPC970_First; + isSingle = TSFlags & PPCII::PPC970_Single; + return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); } /// isLoadOfStoredAddress - If we have a load from the previously stored pointer /// as indicated by StorePtr1/StorePtr2/StoreSize, return true. bool PPCHazardRecognizer970:: isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const { - // Handle exact and commuted addresses. - if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2) - return true; - if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2) - return true; - - // Okay, we don't have an exact match, if this is an indexed offset, see if we - // have overlap (which happens during fp->int conversion for example). - if (StorePtr2 == Ptr2) { - if (ConstantSDNode *StoreOffset = dyn_cast(StorePtr1)) - if (ConstantSDNode *LoadOffset = dyn_cast(Ptr1)) { - // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check to - // see if the load and store actually overlap. - int StoreOffs = StoreOffset->getValue(); - int LoadOffs = LoadOffset->getValue(); - if (StoreOffs < LoadOffs) { - if (int(StoreOffs+StoreSize) > LoadOffs) return true; - } else { - if (int(LoadOffs+LoadSize) > StoreOffs) return true; + for (unsigned i = 0, e = NumStores; i != e; ++i) { + // Handle exact and commuted addresses. + if (Ptr1 == StorePtr1[i] && Ptr2 == StorePtr2[i]) + return true; + if (Ptr2 == StorePtr1[i] && Ptr1 == StorePtr2[i]) + return true; + + // Okay, we don't have an exact match, if this is an indexed offset, see if + // we have overlap (which happens during fp->int conversion for example). + if (StorePtr2[i] == Ptr2) { + if (ConstantSDNode *StoreOffset = dyn_cast(StorePtr1[i])) + if (ConstantSDNode *LoadOffset = dyn_cast(Ptr1)) { + // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check + // to see if the load and store actually overlap. + int StoreOffs = StoreOffset->getValue(); + int LoadOffs = LoadOffset->getValue(); + if (StoreOffs < LoadOffs) { + if (int(StoreOffs+StoreSize) > LoadOffs) return true; + } else { + if (int(LoadOffs+LoadSize) > StoreOffs) return true; + } } - } + } } return false; } @@ -157,53 +122,76 @@ /// pipeline flush. HazardRecognizer::HazardType PPCHazardRecognizer970:: getHazardType(SDNode *Node) { - PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); - if (InstrType == PseudoInst) return NoHazard; + bool isFirst, isSingle, isLoad, isStore; + PPCII::PPC970_Unit InstrType = + GetInstrType(Node->getOpcode(), isFirst, isSingle, isLoad, isStore); + if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; + // We can only issue a PPC970_First/PPC970_Single instruction (such as + // crand/mtspr/etc) if this is the first cycle of the dispatch group. + if (NumIssued != 0 && (isFirst || isSingle) ) + return Hazard; + switch (InstrType) { default: assert(0 && "Unknown instruction type!"); - case FXU: - case FXU_FIRST: if (NumFXU == 2) return Hazard; - case LSU_ST: - case LSU_LD: if (NumLSU == 2) return Hazard; - case FPU: if (NumFPU == 2) return Hazard; - case CR: if (HasCR) return Hazard; - case SPR: if (HasSPR) return Hazard; - case VALU: if (HasVALU) return Hazard; - case VPERM: if (HasVPERM) return Hazard; - case BR: break; + case PPCII::PPC970_FXU: + case PPCII::PPC970_LSU: + case PPCII::PPC970_FPU: + case PPCII::PPC970_VALU: + case PPCII::PPC970_VPERM: + // We can only issue a branch as the last instruction in a group. + if (NumIssued == 4) return Hazard; + break; + case PPCII::PPC970_CRU: + // We can only issue a CR instruction in the first two slots. + if (NumIssued >= 2) return Hazard; + break; + case PPCII::PPC970_BRU: + break; } - - // We can only issue a CR or SPR instruction, or an FXU instruction that needs - // to lead a dispatch group as the first instruction in the group. - if (NumIssued != 0 && - (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST)) - return Hazard; - - // We can only issue a branch as the last instruction in a group. - if (NumIssued == 4 && InstrType != BR) - return Hazard; - + // Do not allow MTCTR and BCTRL to be in the same dispatch group. if (HasCTRSet && Opcode == PPC::BCTRL) return NoopHazard; // If this is a load following a store, make sure it's not to the same or // overlapping address. - if (InstrType == LSU_LD && StoreSize) { + if (isLoad && StoreSize) { unsigned LoadSize; switch (Opcode) { default: assert(0 && "Unknown load!"); - case PPC::LBZ: LoadSize = 1; break; + case PPC::LBZ: + case PPC::LBZX: + case PPC::LVEBX: + LoadSize = 1; + break; case PPC::LHA: - case PPC::LHZ: LoadSize = 2; break; - case PPC::LWZU: - case PPC::LFSX: + case PPC::LHAX: + case PPC::LHZ: + case PPC::LHZX: + case PPC::LVEHX: + LoadSize = 2; + break; case PPC::LFS: + case PPC::LFSX: + case PPC::LWZ: case PPC::LWZX: - case PPC::LWZ: LoadSize = 4; break; - case PPC::LFD: LoadSize = 8; break; + case PPC::LWZU: + case PPC::LWA: + case PPC::LWAX: + case PPC::LVEWX: + LoadSize = 4; + break; + case PPC::LFD: + case PPC::LFDX: + case PPC::LD: + case PPC::LDX: + LoadSize = 8; + break; + case PPC::LVX: + LoadSize = 16; + break; } if (isLoadOfStoredAddress(LoadSize, @@ -215,41 +203,61 @@ } void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) { - PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); - if (InstrType == PseudoInst) return; + bool isFirst, isSingle, isLoad, isStore; + PPCII::PPC970_Unit InstrType = + GetInstrType(Node->getOpcode(), isFirst, isSingle, isLoad, isStore); + if (InstrType == PPCII::PPC970_Pseudo) return; unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; // Update structural hazard information. if (Opcode == PPC::MTCTR) HasCTRSet = true; // Track the address stored to. - if (InstrType == LSU_ST) { - StorePtr1 = Node->getOperand(1); - StorePtr2 = Node->getOperand(2); + if (isStore) { + unsigned ThisStoreSize; switch (Opcode) { default: assert(0 && "Unknown store instruction!"); - case PPC::STB: StoreSize = 1; break; - case PPC::STH: StoreSize = 2; break; + case PPC::STBX: + case PPC::STB: + case PPC::STVEBX: + ThisStoreSize = 1; + break; + case PPC::STHX: + case PPC::STH: + case PPC::STVEHX: + ThisStoreSize = 2; + break; case PPC::STFS: + case PPC::STFSX: case PPC::STWU: - case PPC::STW: StoreSize = 4; break; - case PPC::STFD: StoreSize = 8; break; + case PPC::STWX: + case PPC::STWUX: + case PPC::STW: + case PPC::STVEWX: + case PPC::STFIWX: + ThisStoreSize = 4; + break; + case PPC::STD: + case PPC::STDU: + case PPC::STFD: + case PPC::STFDX: + case PPC::STDX: + case PPC::STDUX: + ThisStoreSize = 8; + break; + case PPC::STVX: + ThisStoreSize = 16; + break; } + + StoreSize[NumStores] = ThisStoreSize; + StorePtr1[NumStores] = Node->getOperand(1); + StorePtr2[NumStores] = Node->getOperand(2); + ++NumStores; } - switch (InstrType) { - default: assert(0 && "Unknown instruction type!"); - case FXU: - case FXU_FIRST: ++NumFXU; break; - case LSU_LD: - case LSU_ST: ++NumLSU; break; - case FPU: ++NumFPU; break; - case CR: HasCR = true; break; - case SPR: HasSPR = true; break; - case VALU: HasVALU = true; break; - case VPERM: HasVPERM = true; break; - case BR: NumIssued = 4; return; // ends a d-group. - } + if (InstrType == PPCII::PPC970_BRU || isSingle) + NumIssued = 4; // Terminate a d-group. ++NumIssued; if (NumIssued == 5) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.4 llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.5 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.4 Tue Mar 7 22:25:59 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.h Sun Mar 12 03:13:49 2006 @@ -15,6 +15,7 @@ #define PPCHAZRECS_H #include "llvm/CodeGen/ScheduleDAG.h" +#include "PPCInstrInfo.h" namespace llvm { @@ -25,16 +26,9 @@ /// setting the CTR register then branching through it within a dispatch group), /// or storing then loading from the same address within a dispatch group. class PPCHazardRecognizer970 : public HazardRecognizer { - unsigned NumIssued; // Number of insts issued, including advanced cycles. + const TargetInstrInfo &TII; - // Number of various types of instructions in the current dispatch group. - unsigned NumFXU; // Number of Fixed Point (integer) instructions - unsigned NumLSU; // Number of Load/Store instructions - unsigned NumFPU; // Number of Floating Point instructions - bool HasCR; // True if Condition Register instruction issued - bool HasSPR; // True if Special-Purpose Register instruction used - bool HasVALU; // True if Vector Arithmetic instruction issued - bool HasVPERM; // True if Vector Permute instruction issued + unsigned NumIssued; // Number of insts issued, including advanced cycles. // Various things that can cause a structural hazard. @@ -42,17 +36,17 @@ bool HasCTRSet; // StoredPtr - Keep track of the address of any store. If we see a load from - // the same address (or one that aliases it), disallow the store. We only - // need one pointer here, because there can only be two LSU operations and we - // only get an LSU reject if the first is a store and the second is a load. + // the same address (or one that aliases it), disallow the store. We can have + // up to four stores in one dispatch group, hence we track up to 4. // // This is null if we haven't seen a store yet. We keep track of both // operands of the store here, since we support [r+r] and [r+i] addressing. - SDOperand StorePtr1, StorePtr2; - unsigned StoreSize; + SDOperand StorePtr1[4], StorePtr2[4]; + unsigned StoreSize[4]; + unsigned NumStores; public: - PPCHazardRecognizer970(); + PPCHazardRecognizer970(const TargetInstrInfo &TII); virtual HazardType getHazardType(SDNode *Node); virtual void EmitInstruction(SDNode *Node); virtual void AdvanceCycle(); @@ -63,13 +57,11 @@ /// void EndDispatchGroup(); - enum PPC970InstrType { - FXU, FXU_FIRST, LSU_LD, LSU_ST, FPU, CR, SPR, VALU, VPERM, BR, PseudoInst - }; - /// GetInstrType - Classify the specified powerpc opcode according to its /// pipeline. - PPC970InstrType GetInstrType(unsigned Opcode); + PPCII::PPC970_Unit GetInstrType(unsigned Opcode, + bool &isFirst, bool &isSingle, + bool &isLoad, bool &isStore); bool isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const; Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.163 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.164 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.163 Tue Mar 7 22:25:59 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sun Mar 12 03:13:49 2006 @@ -129,7 +129,9 @@ virtual HazardRecognizer *CreateTargetHazardRecognizer() { // Should use subtarget info to pick the right hazard recognizer. For // now, always return a PPC970 recognizer. - return new PPCHazardRecognizer970(); + const TargetInstrInfo *II = PPCLowering.getTargetMachine().getInstrInfo(); + assert(II && "No InstrInfo?"); + return new PPCHazardRecognizer970(*II); } // Include the pieces autogenerated from the target description. Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.64 llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.65 --- llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.64 Thu Jan 26 19:46:15 2006 +++ llvm/lib/Target/PowerPC/PPCInstrFormats.td Sun Mar 12 03:13:49 2006 @@ -27,7 +27,27 @@ let OperandList = OL; let AsmString = asmstr; let Itinerary = itin; -} + + /// These fields correspond to the fields in PPCInstrInfo.h. Any changes to + /// these must be reflected there! See comments there for what these are. + bits<1> PPC970_First = 0; + bits<1> PPC970_Single = 0; + bits<3> PPC970_Unit = 0; +} + +class PPC970_DGroup_First { bits<1> PPC970_First = 1; } +class PPC970_DGroup_Single { bits<1> PPC970_Single = 1; } +class PPC970_MicroCode; + +class PPC970_Unit_Pseudo { bits<3> PPC970_Unit = 0; } +class PPC970_Unit_FXU { bits<3> PPC970_Unit = 1; } +class PPC970_Unit_LSU { bits<3> PPC970_Unit = 2; } +class PPC970_Unit_FPU { bits<3> PPC970_Unit = 3; } +class PPC970_Unit_CRU { bits<3> PPC970_Unit = 4; } +class PPC970_Unit_VALU { bits<3> PPC970_Unit = 5; } +class PPC970_Unit_VPERM { bits<3> PPC970_Unit = 6; } +class PPC970_Unit_BRU { bits<3> PPC970_Unit = 7; } + // 1.7.1 I-Form class IForm opcode, bit aa, bit lk, dag OL, string asmstr, Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.12 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.13 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.12 Sun Mar 5 17:49:55 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Sun Mar 12 03:13:49 2006 @@ -19,6 +19,43 @@ #include "PPCRegisterInfo.h" namespace llvm { + +/// PPCII - This namespace holds all of the PowerPC target-specific +/// per-instruction flags. These must match the corresponding definitions in +/// PPC.td and PPCInstrFormats.td. +namespace PPCII { +enum { + // PPC970 Instruction Flags. These flags describe the characteristics of the + // PowerPC 970 (aka G5) dispatch groups and how they are formed out of + // raw machine instructions. + + /// PPC970_First - This instruction starts a new dispatch group, so it will + /// always be the first one in the group. + PPC970_First = 0x1, + + /// PPC970_Single - This instruction starts a new dispatch group and + /// terminates it, so it will be the sole instruction in the group. + PPC970_Single = 0x2, + + /// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that + /// an instruction is issued to. + PPC970_Shift = 2, + PPC970_Mask = 0x07 << PPC970_Shift, +}; +enum PPC970_Unit { + /// These are the various PPC970 execution unit pipelines. Each instruction + /// is one of these. + PPC970_Pseudo = 0 << PPC970_Shift, // Pseudo instruction + PPC970_FXU = 1 << PPC970_Shift, // Fixed Point (aka Integer/ALU) Unit + PPC970_LSU = 2 << PPC970_Shift, // Load Store Unit + PPC970_FPU = 3 << PPC970_Shift, // Floating Point Unit + PPC970_CRU = 4 << PPC970_Shift, // Control Register Unit + PPC970_VALU = 5 << PPC970_Shift, // Vector ALU + PPC970_VPERM = 6 << PPC970_Shift, // Vector Permute Unit + PPC970_BRU = 7 << PPC970_Shift, // Branch Unit +}; +} + class PPCInstrInfo : public TargetInstrInfo { const PPCRegisterInfo RI; Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.179 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.180 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.179 Sun Mar 5 17:49:55 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sun Mar 12 03:13:49 2006 @@ -203,7 +203,7 @@ // Pseudo-instructions: -let isLoad = 1, hasCtrlDep = 1 in { +let hasCtrlDep = 1 in { def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN", [(callseq_start imm:$amt)]>; @@ -220,7 +220,8 @@ // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the // scheduler into a branch sequence. -let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. +let usesCustomDAGSchedInserter = 1, // Expanded by the scheduler. + PPC970_Single = 1 in { def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F, i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>; def SELECT_CC_F4 : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F, @@ -229,16 +230,18 @@ i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>; } -let isTerminator = 1, noResults = 1 in { +let isTerminator = 1, noResults = 1, PPC970_Unit = 7 in { let isReturn = 1 in def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(retflag)]>; def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>; } let Defs = [LR] in - def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>; + def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>, + PPC970_Unit_BRU; -let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in { +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, + noResults = 1, PPC970_Unit = 7 in { def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc, target:$true, target:$false), "; COND_BRANCH", []>; @@ -266,7 +269,7 @@ "bnu $crS, $block", BrB>; } -let isCall = 1, noResults = 1, +let isCall = 1, noResults = 1, PPC970_Unit = 7, // All calls clobber the non-callee saved registers... Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12, F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13, @@ -284,7 +287,7 @@ // D-Form instructions. Most instructions that perform an operation on a // register and an immediate are of this type. // -let isLoad = 1 in { +let isLoad = 1, PPC970_Unit = 2 in { def LBZ : DForm_1<34, (ops GPRC:$rD, memri:$src), "lbz $rD, $src", LdStGeneral, [(set GPRC:$rD, (zextload iaddr:$src, i8))]>; @@ -304,6 +307,7 @@ "lwzu $rD, $disp($rA)", LdStGeneral, []>; } +let PPC970_Unit = 1 in { // FXU Operations. def ADDI : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "addi $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; @@ -332,7 +336,8 @@ def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm), "lis $rD, $imm", IntGeneral, [(set GPRC:$rD, imm16Shifted:$imm)]>; -let isStore = 1, noResults = 1 in { +} +let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), "stmw $rS, $disp($rA)", LdStLMW, []>; @@ -349,6 +354,7 @@ "stwu $rS, $disp($rA)", LdStGeneral, []>; } +let PPC970_Unit = 1 in { // FXU Operations. def ANDIo : DForm_4<28, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), "andi. $dst, $src1, $src2", IntGeneral, [(set GPRC:$dst, (and GPRC:$src1, immZExt16:$src2))]>, @@ -383,7 +389,8 @@ "cmplwi $dst, $src1, $src2", IntCompare>; def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), "cmpldi $dst, $src1, $src2", IntCompare>, isPPC64; -let isLoad = 1 in { +} +let isLoad = 1, PPC970_Unit = 2 in { def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src), "lfs $rD, $src", LdStLFDU, [(set F4RC:$rD, (load iaddr:$src))]>; @@ -391,7 +398,7 @@ "lfd $rD, $src", LdStLFD, [(set F8RC:$rD, (load iaddr:$src))]>; } -let isStore = 1, noResults = 1 in { +let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst), "stfs $rS, $dst", LdStUX, [(store F4RC:$rS, iaddr:$dst)]>; @@ -402,7 +409,7 @@ // DS-Form instructions. Load/Store instructions available in PPC-64 // -let isLoad = 1 in { +let isLoad = 1, PPC970_Unit = 2 in { def LWA : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), "lwa $rT, $DS($rA)", LdStLWA, []>, isPPC64; @@ -410,7 +417,7 @@ "ld $rT, $DS($rA)", LdStLD, []>, isPPC64; } -let isStore = 1, noResults = 1 in { +let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STD : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), "std $rT, $DS($rA)", LdStSTD, []>, isPPC64; @@ -422,7 +429,7 @@ // X-Form instructions. Most instructions that perform an operation on a // register and another register are of this type. // -let isLoad = 1 in { +let isLoad = 1, PPC970_Unit = 2 in { def LBZX : XForm_1<31, 87, (ops GPRC:$rD, memrr:$src), "lbzx $rD, $src", LdStGeneral, [(set GPRC:$rD, (zextload xaddr:$src, i8))]>; @@ -456,10 +463,11 @@ } def LVSL : XForm_1<31, 6, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), "lvsl $vD, $base, $rA", LdStGeneral, - []>; + []>, PPC970_Unit_LSU; def LVSR : XForm_1<31, 38, (ops VRRC:$vD, GPRC:$base, GPRC:$rA), "lvsl $vD, $base, $rA", LdStGeneral, - []>; + []>, PPC970_Unit_LSU; +let PPC970_Unit = 1 in { // FXU Operations. def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "nand $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>; @@ -517,7 +525,8 @@ def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", IntShift, [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>; -let isStore = 1, noResults = 1 in { +} +let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, memrr:$dst), "stbx $rS, $dst", LdStGeneral, [(truncstore GPRC:$rS, xaddr:$dst, i8)]>; @@ -549,6 +558,7 @@ "stvx $rS, $dst", LdStGeneral, [(store (v4f32 VRRC:$rS), xoaddr:$dst)]>; } +let PPC970_Unit = 1 in { // FXU Operations. def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), "srawi $rA, $rS, $SH", IntShift, [(set GPRC:$rA, (sra GPRC:$rS, (i32 imm:$SH)))]>; @@ -576,14 +586,16 @@ "cmplw $crD, $rA, $rB", IntCompare>; def CMPLD : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB), "cmpld $crD, $rA, $rB", IntCompare>, isPPC64; +} +let PPC970_Unit = 3 in { // FPU Operations. //def FCMPO : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB), // "fcmpo $crD, $fA, $fB", FPCompare>; def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB), "fcmpu $crD, $fA, $fB", FPCompare>; def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB), "fcmpu $crD, $fA, $fB", FPCompare>; - -let isLoad = 1 in { +} +let isLoad = 1, PPC970_Unit = 2 in { def LFSX : XForm_25<31, 535, (ops F4RC:$frD, memrr:$src), "lfsx $frD, $src", LdStLFDU, [(set F4RC:$frD, (load xaddr:$src))]>; @@ -591,6 +603,7 @@ "lfdx $frD, $src", LdStLFDU, [(set F8RC:$frD, (load xaddr:$src))]>; } +let PPC970_Unit = 3 in { // FPU Operations. def FCFID : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB), "fcfid $frD, $frB", FPGeneral, [(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64; @@ -609,18 +622,28 @@ def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB), "fsqrts $frD, $frB", FPSqrt, [(set F4RC:$frD, (fsqrt F4RC:$frB))]>; +} /// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending. +/// +/// Note that these are defined as pseudo-ops on the PPC970 because they are +/// often coallesced away and we don't want the dispatch group builder to think +/// that they will fill slots (which could cause the load of a LSU reject to +/// sneak into a d-group with a store). def FMRS : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB), "fmr $frD, $frB", FPGeneral, - []>; // (set F4RC:$frD, F4RC:$frB) + []>, // (set F4RC:$frD, F4RC:$frB) + PPC970_Unit_Pseudo; def FMRD : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB), "fmr $frD, $frB", FPGeneral, - []>; // (set F8RC:$frD, F8RC:$frB) + []>, // (set F8RC:$frD, F8RC:$frB) + PPC970_Unit_Pseudo; def FMRSD : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB), "fmr $frD, $frB", FPGeneral, - [(set F8RC:$frD, (fextend F4RC:$frB))]>; + [(set F8RC:$frD, (fextend F4RC:$frB))]>, + PPC970_Unit_Pseudo; +let PPC970_Unit = 3 in { // FPU Operations. // These are artificially split into two different forms, for 4/8 byte FP. def FABSS : XForm_26<63, 264, (ops F4RC:$frD, F4RC:$frB), "fabs $frD, $frB", FPGeneral, @@ -640,9 +663,9 @@ def FNEGD : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB), "fneg $frD, $frB", FPGeneral, [(set F8RC:$frD, (fneg F8RC:$frB))]>; +} - -let isStore = 1, noResults = 1 in { +let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STFIWX: XForm_28<31, 983, (ops F8RC:$frS, memrr:$dst), "stfiwx $frS, $dst", LdStUX, [(PPCstfiwx F8RC:$frS, xoaddr:$dst)]>; @@ -657,27 +680,34 @@ // XL-Form instructions. condition register logical ops. // def MCRF : XLForm_3<19, 0, (ops CRRC:$BF, CRRC:$BFA), - "mcrf $BF, $BFA", BrMCR>; + "mcrf $BF, $BFA", BrMCR>, + PPC970_DGroup_First, PPC970_Unit_CRU; -// XFX-Form instructions. Instructions that deal with SPRs +// XFX-Form instructions. Instructions that deal with SPRs. // -// Note that although LR should be listed as `8' and CTR as `9' in the SPR -// field, the manual lists the groups of bits as [5-9] = 0, [0-4] = 8 or 9 -// which means the SPR value needs to be multiplied by a factor of 32. -def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>; -def MFLR : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT", SprMFSPR>; -def MFCR : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>; +def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>, + PPC970_DGroup_First, PPC970_Unit_FXU; +def MFLR : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT", SprMFSPR>, + PPC970_DGroup_First, PPC970_Unit_FXU; +def MFCR : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>, + PPC970_MicroCode, PPC970_Unit_CRU; def MTCRF : XFXForm_5<31, 144, (ops crbitm:$FXM, GPRC:$rS), - "mtcrf $FXM, $rS", BrMCRX>; + "mtcrf $FXM, $rS", BrMCRX>, + PPC970_MicroCode, PPC970_Unit_CRU; def MFOCRF: XFXForm_5a<31, 19, (ops GPRC:$rT, crbitm:$FXM), - "mfcr $rT, $FXM", SprMFCR>; -def MTCTR : XFXForm_7_ext<31, 467, 9, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>; -def MTLR : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>; + "mfcr $rT, $FXM", SprMFCR>, + PPC970_DGroup_First, PPC970_Unit_CRU; +def MTCTR : XFXForm_7_ext<31, 467, 9, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>, + PPC970_DGroup_First, PPC970_Unit_FXU; +def MTLR : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>, + PPC970_DGroup_First, PPC970_Unit_FXU; def MTSPR : XFXForm_7<31, 467, (ops GPRC:$rS, u16imm:$UIMM), "mtspr $UIMM, $rS", - SprMTSPR>; + SprMTSPR>, + PPC970_DGroup_Single, PPC970_Unit_FXU; // XS-Form instructions. Just 'sradi' // +let PPC970_Unit = 1 in { // FXU Operations. def SRADI : XSForm_1<31, 413, (ops GPRC:$rA, GPRC:$rS, u6imm:$SH), "sradi $rA, $rS, $SH", IntRotateD>, isPPC64; @@ -697,16 +727,20 @@ [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>; def DIVD : XOForm_1<31, 489, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), "divd $rT, $rA, $rB", IntDivD, - [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64; + [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64, + PPC970_DGroup_First; def DIVDU : XOForm_1<31, 457, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), "divdu $rT, $rA, $rB", IntDivD, - [(set G8RC:$rT, (udiv G8RC:$rA, G8RC:$rB))]>, isPPC64; + [(set G8RC:$rT, (udiv G8RC:$rA, G8RC:$rB))]>, isPPC64, + PPC970_DGroup_First; def DIVW : XOForm_1<31, 491, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "divw $rT, $rA, $rB", IntDivW, - [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>; + [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>, + PPC970_DGroup_First; def DIVWU : XOForm_1<31, 459, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "divwu $rT, $rA, $rB", IntDivW, - [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>; + [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>, + PPC970_DGroup_First; def MULHD : XOForm_1<31, 73, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), "mulhd $rT, $rA, $rB", IntMulHW, [(set G8RC:$rT, (mulhs G8RC:$rA, G8RC:$rB))]>; @@ -749,10 +783,12 @@ def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA), "subfze $rT, $rA", IntGeneral, [(set GPRC:$rT, (sube 0, GPRC:$rA))]>; +} // A-Form instructions. Most of the instructions executed in the FPU are of // this type. // +let PPC970_Unit = 3 in { // FPU Operations. def FMADD : AForm_1<63, 29, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), "fmadd $FRT, $FRA, $FRC, $FRB", FPFused, @@ -845,7 +881,9 @@ (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), "fsubs $FRT, $FRA, $FRB", FPGeneral, [(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>; +} +let PPC970_Unit = 1 in { // FXU Operations. // M-Form instructions. rotate and mask instructions. // let isTwoAddress = 1, isCommutable = 1 in { @@ -882,7 +920,9 @@ (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME), "rldicr $rA, $rS, $SH, $ME", IntRotateD, []>, isPPC64; +} +let PPC970_Unit = 5 in { // VALU Operations. // VA-Form instructions. 3-input AltiVec ops. def VMADDFP : VAForm_1<46, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC), "vmaddfp $vD, $vA, $vC, $vB", VecFP, @@ -957,7 +997,7 @@ def V_SET0 : VXForm_setzero<1220, (ops VRRC:$vD), "vxor $vD, $vD, $vD", VecFP, []>; - +} //===----------------------------------------------------------------------===// // DWARF Pseudo Instructions @@ -1097,13 +1137,3 @@ (XORIS GPRC:$tmp, (HI16 imm:$imm))]>; */ -//===----------------------------------------------------------------------===// -// PowerPCInstrInfo Definition -// -def PowerPCInstrInfo : InstrInfo { - let TSFlagsFields = [ "VMX", "PPC64" ]; - let TSFlagsShifts = [ 0, 1 ]; - - let isLittleEndianEncoding = 1; -} - From lattner at cs.uiuc.edu Sun Mar 12 23:15:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 12 Mar 2006 23:15:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.td PPCInstrFormats.td PPCInstrInfo.h PPCInstrInfo.td Message-ID: <200603130515.XAA13639@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.td updated: 1.13 -> 1.14 PPCInstrFormats.td updated: 1.65 -> 1.66 PPCInstrInfo.h updated: 1.13 -> 1.14 PPCInstrInfo.td updated: 1.180 -> 1.181 --- Log message: Mark instructions that are cracked by the PPC970 decoder as such. --- Diffs of the changes: (+37 -26) PPC.td | 5 ++--- PPCInstrFormats.td | 9 ++++----- PPCInstrInfo.h | 6 +++++- PPCInstrInfo.td | 43 ++++++++++++++++++++++++++----------------- 4 files changed, 37 insertions(+), 26 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.td diff -u llvm/lib/Target/PowerPC/PPC.td:1.13 llvm/lib/Target/PowerPC/PPC.td:1.14 --- llvm/lib/Target/PowerPC/PPC.td:1.13 Sun Mar 12 03:13:49 2006 +++ llvm/lib/Target/PowerPC/PPC.td Sun Mar 12 23:15:10 2006 @@ -72,10 +72,9 @@ // should be kept up-to-date with the fields in the PPCInstrInfo.h file. let TSFlagsFields = ["PPC970_First", "PPC970_Single", + "PPC970_Cracked", "PPC970_Unit"]; - let TSFlagsShifts = [0, - 1, - 2]; + let TSFlagsShifts = [0, 1, 2, 3]; let isLittleEndianEncoding = 1; } Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.65 llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.66 --- llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.65 Sun Mar 12 03:13:49 2006 +++ llvm/lib/Target/PowerPC/PPCInstrFormats.td Sun Mar 12 23:15:10 2006 @@ -6,9 +6,6 @@ // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// -//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // @@ -32,11 +29,13 @@ /// these must be reflected there! See comments there for what these are. bits<1> PPC970_First = 0; bits<1> PPC970_Single = 0; + bits<1> PPC970_Cracked = 0; bits<3> PPC970_Unit = 0; } -class PPC970_DGroup_First { bits<1> PPC970_First = 1; } -class PPC970_DGroup_Single { bits<1> PPC970_Single = 1; } +class PPC970_DGroup_First { bits<1> PPC970_First = 1; } +class PPC970_DGroup_Single { bits<1> PPC970_Single = 1; } +class PPC970_DGroup_Cracked { bits<1> PPC970_Cracked = 1; } class PPC970_MicroCode; class PPC970_Unit_Pseudo { bits<3> PPC970_Unit = 0; } Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.13 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.14 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.13 Sun Mar 12 03:13:49 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Sun Mar 12 23:15:10 2006 @@ -37,9 +37,13 @@ /// terminates it, so it will be the sole instruction in the group. PPC970_Single = 0x2, + /// PPC970_Cracked - This instruction is cracked into two pieces, requiring + /// two dispatch pipes to be available to issue. + PPC970_Cracked = 0x4, + /// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that /// an instruction is issued to. - PPC970_Shift = 2, + PPC970_Shift = 3, PPC970_Mask = 0x07 << PPC970_Shift, }; enum PPC970_Unit { Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.180 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.181 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.180 Sun Mar 12 03:13:49 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sun Mar 12 23:15:10 2006 @@ -293,7 +293,8 @@ [(set GPRC:$rD, (zextload iaddr:$src, i8))]>; def LHA : DForm_1<42, (ops GPRC:$rD, memri:$src), "lha $rD, $src", LdStLHA, - [(set GPRC:$rD, (sextload iaddr:$src, i16))]>; + [(set GPRC:$rD, (sextload iaddr:$src, i16))]>, + PPC970_DGroup_Cracked; def LHZ : DForm_1<40, (ops GPRC:$rD, memri:$src), "lhz $rD, $src", LdStGeneral, [(set GPRC:$rD, (zextload iaddr:$src, i16))]>; @@ -313,7 +314,8 @@ [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; def ADDIC : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "addic $rD, $rA, $imm", IntGeneral, - [(set GPRC:$rD, (addc GPRC:$rA, immSExt16:$imm))]>; + [(set GPRC:$rD, (addc GPRC:$rA, immSExt16:$imm))]>, + PPC970_DGroup_Cracked; def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "addic. $rD, $rA, $imm", IntGeneral, []>; @@ -412,7 +414,7 @@ let isLoad = 1, PPC970_Unit = 2 in { def LWA : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), "lwa $rT, $DS($rA)", LdStLWA, - []>, isPPC64; + []>, isPPC64, PPC970_DGroup_Cracked; def LD : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), "ld $rT, $DS($rA)", LdStLD, []>, isPPC64; @@ -435,13 +437,15 @@ [(set GPRC:$rD, (zextload xaddr:$src, i8))]>; def LHAX : XForm_1<31, 343, (ops GPRC:$rD, memrr:$src), "lhax $rD, $src", LdStLHA, - [(set GPRC:$rD, (sextload xaddr:$src, i16))]>; + [(set GPRC:$rD, (sextload xaddr:$src, i16))]>, + PPC970_DGroup_Cracked; def LHZX : XForm_1<31, 279, (ops GPRC:$rD, memrr:$src), "lhzx $rD, $src", LdStGeneral, [(set GPRC:$rD, (zextload xaddr:$src, i16))]>; def LWAX : XForm_1<31, 341, (ops G8RC:$rD, memrr:$src), "lwax $rD, $src", LdStLHA, - [(set G8RC:$rD, (sextload xaddr:$src, i32))]>, isPPC64; + [(set G8RC:$rD, (sextload xaddr:$src, i32))]>, isPPC64, + PPC970_DGroup_Cracked; def LWZX : XForm_1<31, 23, (ops GPRC:$rD, memrr:$src), "lwzx $rD, $src", LdStGeneral, [(set GPRC:$rD, (load xaddr:$src))]>; @@ -529,19 +533,22 @@ let isStore = 1, noResults = 1, PPC970_Unit = 2 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, memrr:$dst), "stbx $rS, $dst", LdStGeneral, - [(truncstore GPRC:$rS, xaddr:$dst, i8)]>; + [(truncstore GPRC:$rS, xaddr:$dst, i8)]>, + PPC970_DGroup_Cracked; def STHX : XForm_8<31, 407, (ops GPRC:$rS, memrr:$dst), "sthx $rS, $dst", LdStGeneral, - [(truncstore GPRC:$rS, xaddr:$dst, i16)]>; + [(truncstore GPRC:$rS, xaddr:$dst, i16)]>, + PPC970_DGroup_Cracked; def STWX : XForm_8<31, 151, (ops GPRC:$rS, memrr:$dst), "stwx $rS, $dst", LdStGeneral, - [(store GPRC:$rS, xaddr:$dst)]>; + [(store GPRC:$rS, xaddr:$dst)]>, + PPC970_DGroup_Cracked; def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stwux $rS, $rA, $rB", LdStGeneral, []>; def STDX : XForm_8<31, 149, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stdx $rS, $rA, $rB", LdStSTD, - []>, isPPC64; + []>, isPPC64, PPC970_DGroup_Cracked; def STDUX : XForm_8<31, 181, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stdux $rS, $rA, $rB", LdStSTD, []>, isPPC64; @@ -721,26 +728,27 @@ [(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>; def ADDC : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "addc $rT, $rA, $rB", IntGeneral, - [(set GPRC:$rT, (addc GPRC:$rA, GPRC:$rB))]>; + [(set GPRC:$rT, (addc GPRC:$rA, GPRC:$rB))]>, + PPC970_DGroup_Cracked; def ADDE : XOForm_1<31, 138, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "adde $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>; def DIVD : XOForm_1<31, 489, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), "divd $rT, $rA, $rB", IntDivD, [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64, - PPC970_DGroup_First; + PPC970_DGroup_First, PPC970_DGroup_Cracked; def DIVDU : XOForm_1<31, 457, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), "divdu $rT, $rA, $rB", IntDivD, [(set G8RC:$rT, (udiv G8RC:$rA, G8RC:$rB))]>, isPPC64, - PPC970_DGroup_First; + PPC970_DGroup_First, PPC970_DGroup_Cracked; def DIVW : XOForm_1<31, 491, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "divw $rT, $rA, $rB", IntDivW, [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>, - PPC970_DGroup_First; + PPC970_DGroup_First, PPC970_DGroup_Cracked; def DIVWU : XOForm_1<31, 459, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "divwu $rT, $rA, $rB", IntDivW, [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>, - PPC970_DGroup_First; + PPC970_DGroup_First, PPC970_DGroup_Cracked; def MULHD : XOForm_1<31, 73, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), "mulhd $rT, $rA, $rB", IntMulHW, [(set G8RC:$rT, (mulhs G8RC:$rA, G8RC:$rB))]>; @@ -764,7 +772,8 @@ [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>; def SUBFC : XOForm_1<31, 8, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "subfc $rT, $rA, $rB", IntGeneral, - [(set GPRC:$rT, (subc GPRC:$rB, GPRC:$rA))]>; + [(set GPRC:$rT, (subc GPRC:$rB, GPRC:$rA))]>, + PPC970_DGroup_Cracked; def SUBFE : XOForm_1<31, 136, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "subfe $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (sube GPRC:$rB, GPRC:$rA))]>; @@ -891,7 +900,7 @@ def RLWIMI : MForm_2<20, (ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME", IntRotate, - []>; + []>, PPC970_DGroup_Cracked; def RLDIMI : MDForm_1<30, 3, (ops G8RC:$rA, G8RC:$rSi, G8RC:$rS, u6imm:$SH, u6imm:$MB), "rldimi $rA, $rS, $SH, $MB", IntRotateD, @@ -904,7 +913,7 @@ def RLWINMo : MForm_2<21, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), "rlwinm. $rA, $rS, $SH, $MB, $ME", IntGeneral, - []>, isDOT; + []>, isDOT, PPC970_DGroup_Cracked; def RLWNM : MForm_2<23, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME), "rlwnm $rA, $rS, $rB, $MB, $ME", IntGeneral, From lattner at cs.uiuc.edu Sun Mar 12 23:20:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 12 Mar 2006 23:20:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp PPCHazardRecognizers.h Message-ID: <200603130520.XAA13706@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.9 -> 1.10 PPCHazardRecognizers.h updated: 1.5 -> 1.6 --- Log message: Handle cracked instructions in dispatch group formation. --- Diffs of the changes: (+28 -15) PPCHazardRecognizers.cpp | 41 +++++++++++++++++++++++++++-------------- PPCHazardRecognizers.h | 2 +- 2 files changed, 28 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.9 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.10 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.9 Sun Mar 12 03:13:49 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Sun Mar 12 23:20:04 2006 @@ -42,10 +42,8 @@ // // FIXME: This is missing some significant cases: // 1. Modeling of microcoded instructions. -// 2. Handling of cracked instructions. -// 3. Handling of serialized operations. -// 4. Handling of the esoteric cases in "Resource-based Instruction Grouping", -// e.g. integer divides that only execute in the second slot. +// 2. Handling of serialized operations. +// 3. Handling of the esoteric cases in "Resource-based Instruction Grouping". // PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii) @@ -66,9 +64,10 @@ PPCII::PPC970_Unit PPCHazardRecognizer970::GetInstrType(unsigned Opcode, bool &isFirst, bool &isSingle, - bool &isLoad, bool &isStore){ + bool &isCracked, + bool &isLoad, bool &isStore) { if (Opcode < ISD::BUILTIN_OP_END) { - isFirst = isSingle = isLoad = isStore = false; + isFirst = isSingle = isCracked = isLoad = isStore = false; return PPCII::PPC970_Pseudo; } Opcode -= ISD::BUILTIN_OP_END; @@ -80,8 +79,9 @@ unsigned TSFlags = TID.TSFlags; - isFirst = TSFlags & PPCII::PPC970_First; - isSingle = TSFlags & PPCII::PPC970_Single; + isFirst = TSFlags & PPCII::PPC970_First; + isSingle = TSFlags & PPCII::PPC970_Single; + isCracked = TSFlags & PPCII::PPC970_Cracked; return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); } @@ -122,17 +122,24 @@ /// pipeline flush. HazardRecognizer::HazardType PPCHazardRecognizer970:: getHazardType(SDNode *Node) { - bool isFirst, isSingle, isLoad, isStore; + bool isFirst, isSingle, isCracked, isLoad, isStore; PPCII::PPC970_Unit InstrType = - GetInstrType(Node->getOpcode(), isFirst, isSingle, isLoad, isStore); + GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, + isLoad, isStore); if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; // We can only issue a PPC970_First/PPC970_Single instruction (such as // crand/mtspr/etc) if this is the first cycle of the dispatch group. - if (NumIssued != 0 && (isFirst || isSingle) ) + if (NumIssued != 0 && (isFirst || isSingle)) return Hazard; + // If this instruction is cracked into two ops by the decoder, we know that + // it is not a branch and that it cannot issue if 3 other instructions are + // already in the dispatch group. + if (isCracked && NumIssued > 2) + return Hazard; + switch (InstrType) { default: assert(0 && "Unknown instruction type!"); case PPCII::PPC970_FXU: @@ -150,7 +157,7 @@ case PPCII::PPC970_BRU: break; } - + // Do not allow MTCTR and BCTRL to be in the same dispatch group. if (HasCTRSet && Opcode == PPC::BCTRL) return NoopHazard; @@ -203,9 +210,10 @@ } void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) { - bool isFirst, isSingle, isLoad, isStore; + bool isFirst, isSingle, isCracked, isLoad, isStore; PPCII::PPC970_Unit InstrType = - GetInstrType(Node->getOpcode(), isFirst, isSingle, isLoad, isStore); + GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, + isLoad, isStore); if (InstrType == PPCII::PPC970_Pseudo) return; unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; @@ -260,6 +268,11 @@ NumIssued = 4; // Terminate a d-group. ++NumIssued; + // If this instruction is cracked into two ops by the decoder, remember that + // we issued two pieces. + if (isCracked) + ++NumIssued; + if (NumIssued == 5) EndDispatchGroup(); } Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.5 llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.6 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.5 Sun Mar 12 03:13:49 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.h Sun Mar 12 23:20:04 2006 @@ -60,7 +60,7 @@ /// GetInstrType - Classify the specified powerpc opcode according to its /// pipeline. PPCII::PPC970_Unit GetInstrType(unsigned Opcode, - bool &isFirst, bool &isSingle, + bool &isFirst, bool &isSingle,bool &isCracked, bool &isLoad, bool &isStore); bool isLoadOfStoredAddress(unsigned LoadSize, From lattner at cs.uiuc.edu Sun Mar 12 23:24:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 12 Mar 2006 23:24:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Message-ID: <200603130524.XAA13769@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCHazardRecognizers.cpp updated: 1.10 -> 1.11 --- Log message: Fix a couple of bugs that broke the alpha tester build --- Diffs of the changes: (+2 -2) PPCHazardRecognizers.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.10 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.11 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.10 Sun Mar 12 23:20:04 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Sun Mar 12 23:23:59 2006 @@ -106,7 +106,7 @@ int StoreOffs = StoreOffset->getValue(); int LoadOffs = LoadOffset->getValue(); if (StoreOffs < LoadOffs) { - if (int(StoreOffs+StoreSize) > LoadOffs) return true; + if (int(StoreOffs+StoreSize[i]) > LoadOffs) return true; } else { if (int(LoadOffs+LoadSize) > StoreOffs) return true; } @@ -164,7 +164,7 @@ // If this is a load following a store, make sure it's not to the same or // overlapping address. - if (isLoad && StoreSize) { + if (isLoad && NumStores) { unsigned LoadSize; switch (Opcode) { default: assert(0 && "Unknown load!");