From evan.cheng at apple.com Mon Dec 3 03:58:50 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 03 Dec 2007 09:58:50 -0000 Subject: [llvm-commits] [llvm] r44531 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp VirtRegMap.cpp Message-ID: <200712030958.lB39wq5a031331@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 3 03:58:48 2007 New Revision: 44531 URL: http://llvm.org/viewvc/llvm-project?rev=44531&view=rev Log: Update kill info for uses of split intervals. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44531&r1=44530&r2=44531&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Dec 3 03:58:48 2007 @@ -923,7 +923,6 @@ unsigned NewVReg = 0; unsigned index = getBaseIndex(I->start); unsigned end = getBaseIndex(I->end-1) + InstrSlots::NUM; - bool TrySplitMI = TrySplit && vrm.getPreSplitReg(li.reg) == 0; for (; index != end; index += InstrSlots::NUM) { // skip deleted instructions while (index != end && !getInstructionFromIndex(index)) @@ -933,7 +932,7 @@ MachineInstr *MI = getInstructionFromIndex(index); MachineBasicBlock *MBB = MI->getParent(); NewVReg = 0; - if (TrySplitMI) { + if (TrySplit) { std::map::const_iterator NVI = MBBVRegsMap.find(MBB->getNumber()); if (NVI != MBBVRegsMap.end()) { @@ -977,7 +976,7 @@ // Update weight of spill interval. LiveInterval &nI = getOrCreateInterval(NewVReg); - if (!TrySplitMI) { + if (!TrySplit) { // The spill weight is now infinity as it cannot be spilled again. nI.weight = HUGE_VALF; continue; Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44531&r1=44530&r2=44531&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Mon Dec 3 03:58:48 2007 @@ -276,7 +276,7 @@ SmallSet &ReMatDefs, BitVector &RegKills, std::vector &KillOps, - VirtRegMap &VRM); + VirtRegMap &VRM, bool StoreMaybeDead); void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM); }; } @@ -860,7 +860,7 @@ SmallSet &ReMatDefs, BitVector &RegKills, std::vector &KillOps, - VirtRegMap &VRM) { + VirtRegMap &VRM, bool StoreMaybeDead) { MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); DOUT << "Store:\t" << *next(MII); @@ -896,14 +896,15 @@ } } - LastStore = next(MII); + MachineInstr *NewStore = next(MII); + LastStore = StoreMaybeDead ? NewStore : NULL; // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. Spills.ModifyStackSlotOrReMat(StackSlot); Spills.ClobberPhysReg(PhysReg); - Spills.addAvailable(StackSlot, LastStore, PhysReg); + Spills.addAvailable(StackSlot, NewStore, PhysReg); ++NumStores; } @@ -985,8 +986,8 @@ unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; - SpillRegToStackSlot(MBB, MII, i, Phys, StackSlot, RC, - LastStore, Spills, ReMatDefs, RegKills, KillOps, VRM); + SpillRegToStackSlot(MBB, MII, i, Phys, StackSlot, RC, LastStore, + Spills, ReMatDefs, RegKills, KillOps, VRM, false); } } @@ -1009,7 +1010,13 @@ assert(MRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual or a physical register?"); - + + // Assumes this is the last use of a split interval. IsKill will be unset + // if reg is use later unless it's a two-address operand. + if (MO.isUse() && VRM.getPreSplitReg(VirtReg) && + TID->getOperandConstraint(i, TOI::TIED_TO) == -1) + MI.getOperand(i).setIsKill(); + unsigned SubIdx = MO.getSubReg(); if (VRM.isAssignedReg(VirtReg)) { // This virtual register was assigned a physreg! @@ -1440,7 +1447,7 @@ if (!MO.isDead()) { MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, LastStore, - Spills, ReMatDefs, RegKills, KillOps, VRM); + Spills, ReMatDefs, RegKills, KillOps, VRM, true); // Check to see if this is a noop copy. If so, eliminate the // instruction before considering the dest reg to be changed. From evan.cheng at apple.com Mon Dec 3 04:00:01 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 03 Dec 2007 10:00:01 -0000 Subject: [llvm-commits] [llvm] r44532 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200712031000.lB3A02AX031389@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 3 04:00:00 2007 New Revision: 44532 URL: http://llvm.org/viewvc/llvm-project?rev=44532&view=rev Log: Typo Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44532&r1=44531&r2=44532&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Dec 3 04:00:00 2007 @@ -966,7 +966,7 @@ bool IsNew = NewVReg == 0; bool HasDef = false; bool HasUse = false; - rewriteInstructionForSpills(li, TrySplitMI, I->valno->id, index, end, + rewriteInstructionForSpills(li, TrySplit, I->valno->id, index, end, MI, ReMatOrigDefMI, ReMatDefMI, Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, CanDelete, vrm, RegMap, rc, ReMatIds, NewVReg, HasDef, HasUse, From asl at math.spbu.ru Mon Dec 3 08:28:27 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 14:28:27 -0000 Subject: [llvm-commits] [llvm] r44533 - /llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Message-ID: <200712031428.lB3ESS5e010268@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 3 08:28:26 2007 New Revision: 44533 URL: http://llvm.org/viewvc/llvm-project?rev=44533&view=rev Log: Open output file correctly. This is extremely important for windows-based hosts, where files are opened in text mode by default. Modified: llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp?rev=44533&r1=44532&r2=44533&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Mon Dec 3 08:28:26 2007 @@ -36,7 +36,7 @@ // non-GCC. Some C++ stdlibs even have ofstream::ofstream(int fd). int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) { __gnu_cxx::stdio_filebuf Buffer(FileHandle, std::ios_base::out); - std::ostream OS(&Buffer); + std::ostream OS(&Buffer, std::ios::out | std::ios::trunc | std::ios::binary); if (!OS.fail()) WriteBitcodeToFile(unwrap(M), OS); From asl at math.spbu.ru Mon Dec 3 08:35:57 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 14:35:57 -0000 Subject: [llvm-commits] [llvm] r44534 - /llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Message-ID: <200712031435.lB3EZvwl010570@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 3 08:35:57 2007 New Revision: 44534 URL: http://llvm.org/viewvc/llvm-project?rev=44534&view=rev Log: Sorry, typo :) Modified: llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp?rev=44534&r1=44533&r2=44534&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Mon Dec 3 08:35:57 2007 @@ -35,8 +35,10 @@ // libSystem? As is, the user will just get a linker error if they use this on // non-GCC. Some C++ stdlibs even have ofstream::ofstream(int fd). int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) { - __gnu_cxx::stdio_filebuf Buffer(FileHandle, std::ios_base::out); - std::ostream OS(&Buffer, std::ios::out | std::ios::trunc | std::ios::binary); + __gnu_cxx::stdio_filebuf Buffer(FileHandle, std::ios_base::out | + std::ios::trunc | + std::ios::binary); + std::ostream OS(&Buffer); if (!OS.fail()) WriteBitcodeToFile(unwrap(M), OS); From gordonhenriksen at mac.com Mon Dec 3 08:50:37 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 03 Dec 2007 14:50:37 -0000 Subject: [llvm-commits] [llvm] r44535 - /llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Message-ID: <200712031450.lB3EobRY011149@zion.cs.uiuc.edu> Author: gordon Date: Mon Dec 3 08:50:37 2007 New Revision: 44535 URL: http://llvm.org/viewvc/llvm-project?rev=44535&view=rev Log: Applying Anton's binmode fix to the other ofstream too. Modified: llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp?rev=44535&r1=44534&r2=44535&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitWriter.cpp Mon Dec 3 08:50:37 2007 @@ -17,7 +17,7 @@ /*===-- Operations on modules ---------------------------------------------===*/ int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) { - std::ofstream OS(Path); + std::ofstream OS(Path, std::ios_base::out|std::ios::trunc|std::ios::binary); if (!OS.fail()) WriteBitcodeToFile(unwrap(M), OS); From sabre at nondot.org Mon Dec 3 13:00:48 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Dec 2007 19:00:48 -0000 Subject: [llvm-commits] [llvm] r44537 - /llvm/trunk/docs/DeveloperPolicy.html Message-ID: <200712031900.lB3J0nVO021080@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 3 13:00:47 2007 New Revision: 44537 URL: http://llvm.org/viewvc/llvm-project?rev=44537&view=rev Log: Describe the notion of 'owners' of the code. Modified: llvm/trunk/docs/DeveloperPolicy.html Modified: llvm/trunk/docs/DeveloperPolicy.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/DeveloperPolicy.html?rev=44537&r1=44536&r2=44537&view=diff ============================================================================== --- llvm/trunk/docs/DeveloperPolicy.html (original) +++ llvm/trunk/docs/DeveloperPolicy.html Mon Dec 3 13:00:47 2007 @@ -15,6 +15,7 @@
  • Stay Informed
  • Making a Patch
  • Code Reviews
  • +
  • Code Owners
  • Test Cases
  • Quality
  • Obtaining Commit Access
  • @@ -146,6 +147,50 @@ + +
    + +

    The LLVM Project relies on two features of its process to maintain rapid + development in addition to the high quality of its source base: the + combination of code review plus post-commit review for trusted maintainers. + Having both is a great way for the project to take advantage of the fact + that most people do the right thing most of the time, and only commit + patches without pre-commit review when they are confident they are + right.

    + +

    The trick to this is that the project has to guarantee that all patches + that are committed are reviewed after they go in: you don't want everyone + to assume someone else will review it, allowing the patch to go unreviewed. + To solve this problem, we have a notion of an 'owner' for a piece of the + code. The sole responsibility of a code owner is to ensure that a commit + to their area of the code is appropriately reviewed, either by themself or + by someone else. The current code owners are:

    + +
      +
    1. Anton Korobeynikov: Exception handling, debug information, and + Windows codegen.
    2. +
    3. Duncan Sands: llvm-gcc 4.2.
    4. +
    5. Evan Cheng: Code generator and all targets.
    6. +
    7. Chris Lattner: Everything else.
    8. +
    + +

    Note that code ownership is completely different than reviewers: anyone can + review a piece of code, and we welcome code review from anyone who is + interested. Code owners are the "last line of defense" to guarantee that + all patches that are committed are actually reviewed.

    + +

    Being a code owner is a somewhat unglamorous position, but it is incredibly + important for the ongoing success of the project. Because people get busy, + interests change, and unexpected things happen, code ownership is purely + opt-in, and anyone can choose to resign their "title" at any time. For now, + we do not have an official policy on how one gets elected to be a code + owner. +

    + +
    + + +

    Developers are required to create test cases for any bugs fixed and any new From asl at math.spbu.ru Mon Dec 3 13:16:54 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 19:16:54 -0000 Subject: [llvm-commits] [llvm] r44538 - in /llvm/trunk/lib/AsmParser: llvmAsmParser.y llvmAsmParser.y.cvs Message-ID: <200712031916.lB3JGtkY021590@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 3 13:16:54 2007 New Revision: 44538 URL: http://llvm.org/viewvc/llvm-project?rev=44538&view=rev Log: More sanity checks for function types. Thanks goes to PyPy folks for generating broken stuff :) Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=44538&r1=44537&r2=44538&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Mon Dec 3 13:16:54 2007 @@ -1330,16 +1330,24 @@ | Types '(' ArgTypeListI ')' OptFuncAttrs { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. + const Type* RetTy = *$1; + if (!(RetTy->isFirstClassType() || isa(RetTy))) + GEN_ERROR("LLVM Functions cannot return aggregates"); + std::vector Params; TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); + if (!(Ty->isFirstClassType() || isa(Ty))) + GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } + CHECK_FOR_ERROR + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - FunctionType *FT = FunctionType::get(*$1, Params, isVarArg); + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete $3; // Delete the argument list delete $1; // Delete the return type handle $$ = new PATypeHolder(HandleUpRefs(FT)); @@ -1352,8 +1360,12 @@ TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); + if (!(Ty->isFirstClassType() || isa(Ty))) + GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } + CHECK_FOR_ERROR + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs?rev=44538&r1=44537&r2=44538&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs Mon Dec 3 13:16:54 2007 @@ -1330,16 +1330,24 @@ | Types '(' ArgTypeListI ')' OptFuncAttrs { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. + const Type* RetTy = *$1; + if (!(RetTy->isFirstClassType() || isa(RetTy))) + GEN_ERROR("LLVM Functions cannot return aggregates"); + std::vector Params; TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); + if (!(Ty->isFirstClassType() || isa(Ty))) + GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } + CHECK_FOR_ERROR + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - FunctionType *FT = FunctionType::get(*$1, Params, isVarArg); + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete $3; // Delete the argument list delete $1; // Delete the return type handle $$ = new PATypeHolder(HandleUpRefs(FT)); @@ -1352,8 +1360,12 @@ TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); + if (!(Ty->isFirstClassType() || isa(Ty))) + GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } + CHECK_FOR_ERROR + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); From dpatel at apple.com Mon Dec 3 13:17:21 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 03 Dec 2007 19:17:21 -0000 Subject: [llvm-commits] [llvm] r44539 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll Message-ID: <200712031917.lB3JHLnZ021617@zion.cs.uiuc.edu> Author: dpatel Date: Mon Dec 3 13:17:21 2007 New Revision: 44539 URL: http://llvm.org/viewvc/llvm-project?rev=44539&view=rev Log: If ExitValue operand is also defined in Loop header then insert new ExitValue after this operand definition. This fixes PR1828. Added: llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=44539&r1=44538&r2=44539&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Mon Dec 3 13:17:21 2007 @@ -1330,6 +1330,23 @@ // A_ExitValue = min(SplitValue, OrignalLoopExitValue) // B_StartValue = max(SplitValue, OriginalLoopStartValue) Instruction *InsertPt = L->getHeader()->getFirstNonPHI(); + + // If ExitValue operand is also defined in Loop header then + // insert new ExitValue after this operand definition. + if (Instruction *EVN = + dyn_cast(ExitCondition->getOperand(ExitValueNum))) { + if (!isa(EVN)) + if (InsertPt->getParent() == EVN->getParent()) { + BasicBlock::iterator LHBI = L->getHeader()->begin(); + BasicBlock::iterator LHBE = L->getHeader()->end(); + for(;LHBI != LHBE; ++LHBI) { + Instruction *I = LHBI; + if (I == EVN) + break; + } + InsertPt = ++LHBI; + } + } Value *C1 = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, AEV, Added: llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll?rev=44539&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll (added) +++ llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll Mon Dec 3 13:17:21 2007 @@ -0,0 +1,44 @@ +; RUN: llvm-as < %s | opt -loop-index-split -disable-output +; PR1828.bc +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + %RPyOpaque_RuntimeTypeInfo = type opaque* + %arraytype_Char_1 = type { i32, [0 x i8] } + %arraytype_Signed = type { i32, [0 x i32] } + %functiontype_11 = type %structtype_object* () + %functiontype_360 = type %structtype_rpy_string* (%structtype_pypy.rlib.rbigint.rbigint*, %structtype_rpy_string*, %structtype_rpy_string*, %structtype_rpy_string*) + %structtype_list_18 = type { i32, %arraytype_Signed* } + %structtype_object = type { %structtype_object_vtable* } + %structtype_object_vtable = type { i32, i32, %RPyOpaque_RuntimeTypeInfo*, %arraytype_Char_1*, %functiontype_11* } + %structtype_pypy.rlib.rbigint.rbigint = type { %structtype_object, %structtype_list_18*, i32 } + %structtype_rpy_string = type { i32, %arraytype_Char_1 } + +define fastcc %structtype_rpy_string* @pypy__format(%structtype_pypy.rlib.rbigint.rbigint* %a_1, %structtype_rpy_string* %digits_0, %structtype_rpy_string* %prefix_3, %structtype_rpy_string* %suffix_0) { +block0: + br i1 false, label %block67, label %block13 + +block13: ; preds = %block0 + ret %structtype_rpy_string* null + +block31: ; preds = %block67, %block44 + ret %structtype_rpy_string* null + +block42: ; preds = %block67, %block44 + %j_167.reg2mem.0 = phi i32 [ %v63822, %block44 ], [ 0, %block67 ] ; [#uses=1] + %v63822 = add i32 %j_167.reg2mem.0, -1 ; [#uses=3] + %v63823 = icmp slt i32 %v63822, 0 ; [#uses=1] + br i1 %v63823, label %block46, label %block43 + +block43: ; preds = %block42 + br label %block44 + +block44: ; preds = %block46, %block43 + %v6377959 = icmp sgt i32 %v63822, 0 ; [#uses=1] + br i1 %v6377959, label %block42, label %block31 + +block46: ; preds = %block42 + br label %block44 + +block67: ; preds = %block0 + br i1 false, label %block42, label %block31 +} From asl at math.spbu.ru Mon Dec 3 13:17:47 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 19:17:47 -0000 Subject: [llvm-commits] [llvm] r44541 - in /llvm/trunk/lib/AsmParser: llvmAsmParser.cpp.cvs llvmAsmParser.h.cvs Message-ID: <200712031917.lB3JHlkG021655@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 3 13:17:47 2007 New Revision: 44541 URL: http://llvm.org/viewvc/llvm-project?rev=44541&view=rev Log: Regenerate Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs llvm/trunk/lib/AsmParser/llvmAsmParser.h.cvs Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs?rev=44541&r1=44540&r2=44541&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs Mon Dec 3 13:17:47 2007 @@ -372,7 +372,7 @@ /* Copy the first part of user declarations. */ -#line 14 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 14 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -1324,7 +1324,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 945 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 945 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { llvm::Module *ModuleVal; llvm::Function *FunctionVal; @@ -1824,24 +1824,24 @@ 1223, 1224, 1227, 1228, 1233, 1234, 1235, 1236, 1237, 1238, 1241, 1242, 1249, 1250, 1256, 1257, 1265, 1273, 1274, 1279, 1280, 1281, 1286, 1299, 1299, 1299, 1299, 1299, 1299, 1299, - 1302, 1306, 1310, 1317, 1322, 1330, 1348, 1366, 1371, 1381, - 1391, 1395, 1405, 1412, 1421, 1428, 1433, 1438, 1445, 1446, - 1453, 1460, 1468, 1474, 1486, 1514, 1530, 1557, 1585, 1611, - 1631, 1657, 1677, 1689, 1696, 1762, 1772, 1782, 1788, 1798, - 1804, 1814, 1819, 1824, 1837, 1849, 1871, 1879, 1885, 1896, - 1901, 1906, 1912, 1918, 1927, 1931, 1939, 1939, 1942, 1942, - 1945, 1957, 1978, 1983, 1991, 1992, 1996, 1996, 2000, 2000, - 2003, 2006, 2030, 2041, 2041, 2052, 2051, 2061, 2060, 2071, - 2111, 2114, 2120, 2130, 2134, 2139, 2141, 2146, 2151, 2160, - 2170, 2181, 2185, 2194, 2203, 2208, 2338, 2338, 2340, 2349, - 2349, 2351, 2356, 2368, 2372, 2377, 2381, 2385, 2389, 2393, - 2397, 2401, 2405, 2409, 2434, 2438, 2448, 2452, 2456, 2461, - 2468, 2468, 2474, 2483, 2487, 2496, 2505, 2514, 2518, 2525, - 2529, 2533, 2538, 2548, 2567, 2576, 2660, 2664, 2671, 2682, - 2695, 2705, 2716, 2726, 2737, 2745, 2755, 2762, 2765, 2766, - 2773, 2777, 2782, 2798, 2815, 2829, 2843, 2855, 2863, 2870, - 2876, 2882, 2888, 2903, 2994, 2999, 3003, 3010, 3017, 3025, - 3032, 3040, 3048, 3062, 3079 + 1302, 1306, 1310, 1317, 1322, 1330, 1356, 1378, 1383, 1393, + 1403, 1407, 1417, 1424, 1433, 1440, 1445, 1450, 1457, 1458, + 1465, 1472, 1480, 1486, 1498, 1526, 1542, 1569, 1597, 1623, + 1643, 1669, 1689, 1701, 1708, 1774, 1784, 1794, 1800, 1810, + 1816, 1826, 1831, 1836, 1849, 1861, 1883, 1891, 1897, 1908, + 1913, 1918, 1924, 1930, 1939, 1943, 1951, 1951, 1954, 1954, + 1957, 1969, 1990, 1995, 2003, 2004, 2008, 2008, 2012, 2012, + 2015, 2018, 2042, 2053, 2053, 2064, 2063, 2073, 2072, 2083, + 2123, 2126, 2132, 2142, 2146, 2151, 2153, 2158, 2163, 2172, + 2182, 2193, 2197, 2206, 2215, 2220, 2350, 2350, 2352, 2361, + 2361, 2363, 2368, 2380, 2384, 2389, 2393, 2397, 2401, 2405, + 2409, 2413, 2417, 2421, 2446, 2450, 2460, 2464, 2468, 2473, + 2480, 2480, 2486, 2495, 2499, 2508, 2517, 2526, 2530, 2537, + 2541, 2545, 2550, 2560, 2579, 2588, 2672, 2676, 2683, 2694, + 2707, 2717, 2728, 2738, 2749, 2757, 2767, 2774, 2777, 2778, + 2785, 2789, 2794, 2810, 2827, 2841, 2855, 2867, 2875, 2882, + 2888, 2894, 2900, 2915, 3006, 3011, 3015, 3022, 3029, 3037, + 3044, 3052, 3060, 3074, 3091 }; #endif @@ -3415,142 +3415,142 @@ switch (yyn) { case 29: -#line 1111 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1111 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_EQ; ;} break; case 30: -#line 1111 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1111 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_NE; ;} break; case 31: -#line 1112 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1112 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SLT; ;} break; case 32: -#line 1112 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1112 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SGT; ;} break; case 33: -#line 1113 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1113 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SLE; ;} break; case 34: -#line 1113 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1113 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SGE; ;} break; case 35: -#line 1114 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1114 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_ULT; ;} break; case 36: -#line 1114 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1114 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_UGT; ;} break; case 37: -#line 1115 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1115 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_ULE; ;} break; case 38: -#line 1115 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1115 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_UGE; ;} break; case 39: -#line 1119 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1119 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OEQ; ;} break; case 40: -#line 1119 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1119 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ONE; ;} break; case 41: -#line 1120 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1120 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OLT; ;} break; case 42: -#line 1120 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1120 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OGT; ;} break; case 43: -#line 1121 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1121 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OLE; ;} break; case 44: -#line 1121 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1121 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OGE; ;} break; case 45: -#line 1122 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1122 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ORD; ;} break; case 46: -#line 1122 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1122 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UNO; ;} break; case 47: -#line 1123 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1123 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UEQ; ;} break; case 48: -#line 1123 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1123 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UNE; ;} break; case 49: -#line 1124 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1124 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ULT; ;} break; case 50: -#line 1124 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1124 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UGT; ;} break; case 51: -#line 1125 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1125 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ULE; ;} break; case 52: -#line 1125 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1125 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UGE; ;} break; case 53: -#line 1126 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1126 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_TRUE; ;} break; case 54: -#line 1127 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1127 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_FALSE; ;} break; case 65: -#line 1136 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1136 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; ;} break; case 66: -#line 1140 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1140 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[(1) - (2)].StrVal); CHECK_FOR_ERROR @@ -3558,7 +3558,7 @@ break; case 67: -#line 1144 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1144 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; CHECK_FOR_ERROR @@ -3566,7 +3566,7 @@ break; case 71: -#line 1152 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1152 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; CHECK_FOR_ERROR @@ -3574,7 +3574,7 @@ break; case 72: -#line 1157 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1157 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[(1) - (2)].StrVal); CHECK_FOR_ERROR @@ -3582,152 +3582,152 @@ break; case 73: -#line 1163 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1163 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; case 74: -#line 1164 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1164 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; case 75: -#line 1165 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1165 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} break; case 76: -#line 1166 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1166 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::AppendingLinkage; ;} break; case 77: -#line 1167 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1167 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} break; case 78: -#line 1171 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1171 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} break; case 79: -#line 1172 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1172 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} break; case 80: -#line 1173 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1173 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 81: -#line 1177 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1177 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::DefaultVisibility; ;} break; case 82: -#line 1178 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1178 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::DefaultVisibility; ;} break; case 83: -#line 1179 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1179 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::HiddenVisibility; ;} break; case 84: -#line 1180 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1180 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::ProtectedVisibility; ;} break; case 85: -#line 1184 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1184 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 86: -#line 1185 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1185 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} break; case 87: -#line 1186 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1186 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} break; case 88: -#line 1190 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1190 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 89: -#line 1191 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1191 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; case 90: -#line 1192 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1192 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} break; case 91: -#line 1193 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1193 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; case 92: -#line 1194 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1194 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} break; case 93: -#line 1198 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1198 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 94: -#line 1199 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1199 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; case 95: -#line 1200 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1200 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; case 96: -#line 1203 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1203 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::C; ;} break; case 97: -#line 1204 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1204 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::C; ;} break; case 98: -#line 1205 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1205 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::Fast; ;} break; case 99: -#line 1206 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1206 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::Cold; ;} break; case 100: -#line 1207 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1207 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::X86_StdCall; ;} break; case 101: -#line 1208 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1208 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::X86_FastCall; ;} break; case 102: -#line 1209 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1209 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((unsigned)(yyvsp[(2) - (2)].UInt64Val) != (yyvsp[(2) - (2)].UInt64Val)) GEN_ERROR("Calling conv too large"); @@ -3737,111 +3737,111 @@ break; case 103: -#line 1216 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1216 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ZExt; ;} break; case 104: -#line 1217 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1217 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ZExt; ;} break; case 105: -#line 1218 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1218 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::SExt; ;} break; case 106: -#line 1219 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1219 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::SExt; ;} break; case 107: -#line 1220 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1220 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::InReg; ;} break; case 108: -#line 1221 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1221 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::StructRet; ;} break; case 109: -#line 1222 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1222 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::NoAlias; ;} break; case 110: -#line 1223 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1223 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ByVal; ;} break; case 111: -#line 1224 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1224 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::Nest; ;} break; case 112: -#line 1227 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1227 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::None; ;} break; case 113: -#line 1228 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1228 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = (yyvsp[(1) - (2)].ParamAttrs) | (yyvsp[(2) - (2)].ParamAttrs); ;} break; case 114: -#line 1233 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1233 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::NoReturn; ;} break; case 115: -#line 1234 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1234 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::NoUnwind; ;} break; case 116: -#line 1235 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1235 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ZExt; ;} break; case 117: -#line 1236 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1236 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::SExt; ;} break; case 118: -#line 1237 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1237 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ReadNone; ;} break; case 119: -#line 1238 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1238 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ReadOnly; ;} break; case 120: -#line 1241 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1241 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::None; ;} break; case 121: -#line 1242 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1242 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = (yyvsp[(1) - (2)].ParamAttrs) | (yyvsp[(2) - (2)].ParamAttrs); ;} break; case 122: -#line 1249 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1249 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = 0; ;} break; case 123: -#line 1250 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1250 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = (yyvsp[(2) - (2)].UInt64Val); if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) @@ -3851,12 +3851,12 @@ break; case 124: -#line 1256 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1256 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = 0; ;} break; case 125: -#line 1257 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1257 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = (yyvsp[(3) - (3)].UInt64Val); if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) @@ -3866,7 +3866,7 @@ break; case 126: -#line 1265 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1265 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { for (unsigned i = 0, e = (yyvsp[(2) - (2)].StrVal)->length(); i != e; ++i) if ((*(yyvsp[(2) - (2)].StrVal))[i] == '"' || (*(yyvsp[(2) - (2)].StrVal))[i] == '\\') @@ -3877,27 +3877,27 @@ break; case 127: -#line 1273 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1273 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; ;} break; case 128: -#line 1274 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1274 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[(1) - (1)].StrVal); ;} break; case 129: -#line 1279 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1279 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" {;} break; case 130: -#line 1280 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1280 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" {;} break; case 131: -#line 1281 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1281 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV->setSection(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -3906,7 +3906,7 @@ break; case 132: -#line 1286 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1286 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(2) - (2)].UInt64Val) != 0 && !isPowerOf2_32((yyvsp[(2) - (2)].UInt64Val))) GEN_ERROR("Alignment must be a power of two"); @@ -3916,7 +3916,7 @@ break; case 140: -#line 1302 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1302 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder(OpaqueType::get()); CHECK_FOR_ERROR @@ -3924,7 +3924,7 @@ break; case 141: -#line 1306 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1306 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder((yyvsp[(1) - (1)].PrimType)); CHECK_FOR_ERROR @@ -3932,7 +3932,7 @@ break; case 142: -#line 1310 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1310 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Pointer type? if (*(yyvsp[(1) - (2)].TypeVal) == Type::LabelTy) GEN_ERROR("Cannot form a pointer to a basic block"); @@ -3943,7 +3943,7 @@ break; case 143: -#line 1317 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1317 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Named types are also simple types... const Type* tmp = getTypeVal((yyvsp[(1) - (1)].ValIDVal)); CHECK_FOR_ERROR @@ -3952,7 +3952,7 @@ break; case 144: -#line 1322 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1322 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Type UpReference if ((yyvsp[(2) - (2)].UInt64Val) > (uint64_t)~0U) GEN_ERROR("Value out of range"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder @@ -3964,20 +3964,28 @@ break; case 145: -#line 1330 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1330 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. + const Type* RetTy = *(yyvsp[(1) - (5)].TypeVal); + if (!(RetTy->isFirstClassType() || isa(RetTy))) + GEN_ERROR("LLVM Functions cannot return aggregates"); + std::vector Params; TypeWithAttrsList::iterator I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin(), E = (yyvsp[(3) - (5)].TypeWithAttrsList)->end(); for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); + if (!(Ty->isFirstClassType() || isa(Ty))) + GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } + CHECK_FOR_ERROR + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - FunctionType *FT = FunctionType::get(*(yyvsp[(1) - (5)].TypeVal), Params, isVarArg); + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete (yyvsp[(3) - (5)].TypeWithAttrsList); // Delete the argument list delete (yyvsp[(1) - (5)].TypeVal); // Delete the return type handle (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(FT)); @@ -3986,7 +3994,7 @@ break; case 146: -#line 1348 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1356 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -3994,8 +4002,12 @@ TypeWithAttrsList::iterator I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin(), E = (yyvsp[(3) - (5)].TypeWithAttrsList)->end(); for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); + if (!(Ty->isFirstClassType() || isa(Ty))) + GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } + CHECK_FOR_ERROR + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); @@ -4007,7 +4019,7 @@ break; case 147: -#line 1366 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1378 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Sized array type? (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(ArrayType::get(*(yyvsp[(4) - (5)].TypeVal), (unsigned)(yyvsp[(2) - (5)].UInt64Val)))); delete (yyvsp[(4) - (5)].TypeVal); @@ -4016,7 +4028,7 @@ break; case 148: -#line 1371 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1383 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Vector type? const llvm::Type* ElemTy = (yyvsp[(4) - (5)].TypeVal)->get(); if ((unsigned)(yyvsp[(2) - (5)].UInt64Val) != (yyvsp[(2) - (5)].UInt64Val)) @@ -4030,7 +4042,7 @@ break; case 149: -#line 1381 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1393 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Structure type? std::vector Elements; for (std::list::iterator I = (yyvsp[(2) - (3)].TypeList)->begin(), @@ -4044,7 +4056,7 @@ break; case 150: -#line 1391 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1403 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector())); CHECK_FOR_ERROR @@ -4052,7 +4064,7 @@ break; case 151: -#line 1395 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1407 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { std::vector Elements; for (std::list::iterator I = (yyvsp[(3) - (5)].TypeList)->begin(), @@ -4066,7 +4078,7 @@ break; case 152: -#line 1405 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1417 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector(), true)); CHECK_FOR_ERROR @@ -4074,7 +4086,7 @@ break; case 153: -#line 1412 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1424 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -4084,7 +4096,7 @@ break; case 154: -#line 1421 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1433 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (1)].TypeVal))->getDescription()); @@ -4095,14 +4107,14 @@ break; case 155: -#line 1428 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1440 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder(Type::VoidTy); ;} break; case 156: -#line 1433 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1445 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); (yyval.TypeWithAttrsList)->push_back((yyvsp[(1) - (1)].TypeWithAttrs)); @@ -4111,7 +4123,7 @@ break; case 157: -#line 1438 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1450 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ((yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList))->push_back((yyvsp[(3) - (3)].TypeWithAttrs)); CHECK_FOR_ERROR @@ -4119,7 +4131,7 @@ break; case 159: -#line 1446 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1458 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList); TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None; @@ -4130,7 +4142,7 @@ break; case 160: -#line 1453 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1465 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList; TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None; @@ -4141,7 +4153,7 @@ break; case 161: -#line 1460 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1472 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); CHECK_FOR_ERROR @@ -4149,7 +4161,7 @@ break; case 162: -#line 1468 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1480 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList) = new std::list(); (yyval.TypeList)->push_back(*(yyvsp[(1) - (1)].TypeVal)); @@ -4159,7 +4171,7 @@ break; case 163: -#line 1474 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1486 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ((yyval.TypeList)=(yyvsp[(1) - (3)].TypeList))->push_back(*(yyvsp[(3) - (3)].TypeVal)); delete (yyvsp[(3) - (3)].TypeVal); @@ -4168,7 +4180,7 @@ break; case 164: -#line 1486 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1498 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); @@ -4200,7 +4212,7 @@ break; case 165: -#line 1514 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1526 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4220,7 +4232,7 @@ break; case 166: -#line 1530 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1542 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4251,7 +4263,7 @@ break; case 167: -#line 1557 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1569 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); @@ -4283,7 +4295,7 @@ break; case 168: -#line 1585 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1597 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast((yyvsp[(1) - (4)].TypeVal)->get()); if (STy == 0) @@ -4313,7 +4325,7 @@ break; case 169: -#line 1611 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1623 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4337,7 +4349,7 @@ break; case 170: -#line 1631 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1643 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast((yyvsp[(1) - (6)].TypeVal)->get()); if (STy == 0) @@ -4367,7 +4379,7 @@ break; case 171: -#line 1657 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1669 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (5)].TypeVal))->getDescription()); @@ -4391,7 +4403,7 @@ break; case 172: -#line 1677 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1689 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4407,7 +4419,7 @@ break; case 173: -#line 1689 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1701 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4418,7 +4430,7 @@ break; case 174: -#line 1696 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1708 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4488,7 +4500,7 @@ break; case 175: -#line 1762 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1774 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4502,7 +4514,7 @@ break; case 176: -#line 1772 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1784 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4516,7 +4528,7 @@ break; case 177: -#line 1782 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1794 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantInt::isValueValidForType((yyvsp[(1) - (2)].PrimType), (yyvsp[(2) - (2)].SInt64Val))) GEN_ERROR("Constant value doesn't fit in type"); @@ -4526,7 +4538,7 @@ break; case 178: -#line 1788 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1800 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // arbitrary precision integer constants uint32_t BitWidth = cast((yyvsp[(1) - (2)].PrimType))->getBitWidth(); if ((yyvsp[(2) - (2)].APIntVal)->getBitWidth() > BitWidth) { @@ -4540,7 +4552,7 @@ break; case 179: -#line 1798 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1810 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantInt::isValueValidForType((yyvsp[(1) - (2)].PrimType), (yyvsp[(2) - (2)].UInt64Val))) GEN_ERROR("Constant value doesn't fit in type"); @@ -4550,7 +4562,7 @@ break; case 180: -#line 1804 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1816 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // arbitrary precision integer constants uint32_t BitWidth = cast((yyvsp[(1) - (2)].PrimType))->getBitWidth(); if ((yyvsp[(2) - (2)].APIntVal)->getBitWidth() > BitWidth) { @@ -4564,7 +4576,7 @@ break; case 181: -#line 1814 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1826 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Boolean constants assert(cast((yyvsp[(1) - (2)].PrimType))->getBitWidth() == 1 && "Not Bool?"); (yyval.ConstVal) = ConstantInt::getTrue(); @@ -4573,7 +4585,7 @@ break; case 182: -#line 1819 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1831 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Boolean constants assert(cast((yyvsp[(1) - (2)].PrimType))->getBitWidth() == 1 && "Not Bool?"); (yyval.ConstVal) = ConstantInt::getFalse(); @@ -4582,7 +4594,7 @@ break; case 183: -#line 1824 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1836 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Floating point constants if (!ConstantFP::isValueValidForType((yyvsp[(1) - (2)].PrimType), *(yyvsp[(2) - (2)].FPVal))) GEN_ERROR("Floating point constant invalid for type"); @@ -4597,7 +4609,7 @@ break; case 184: -#line 1837 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1849 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(5) - (6)].TypeVal))->getDescription()); @@ -4613,7 +4625,7 @@ break; case 185: -#line 1849 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1861 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!isa((yyvsp[(3) - (5)].ConstVal)->getType())) GEN_ERROR("GetElementPtr requires a pointer operand"); @@ -4639,7 +4651,7 @@ break; case 186: -#line 1871 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1883 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(3) - (8)].ConstVal)->getType() != Type::Int1Ty) GEN_ERROR("Select condition must be of boolean type"); @@ -4651,7 +4663,7 @@ break; case 187: -#line 1879 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1891 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(3) - (6)].ConstVal)->getType() != (yyvsp[(5) - (6)].ConstVal)->getType()) GEN_ERROR("Binary operator types must match"); @@ -4661,7 +4673,7 @@ break; case 188: -#line 1885 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1897 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(3) - (6)].ConstVal)->getType() != (yyvsp[(5) - (6)].ConstVal)->getType()) GEN_ERROR("Logical operator types must match"); @@ -4676,7 +4688,7 @@ break; case 189: -#line 1896 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1908 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) GEN_ERROR("icmp operand types must match"); @@ -4685,7 +4697,7 @@ break; case 190: -#line 1901 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1913 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) GEN_ERROR("fcmp operand types must match"); @@ -4694,7 +4706,7 @@ break; case 191: -#line 1906 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1918 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ExtractElementInst::isValidOperands((yyvsp[(3) - (6)].ConstVal), (yyvsp[(5) - (6)].ConstVal))) GEN_ERROR("Invalid extractelement operands"); @@ -4704,7 +4716,7 @@ break; case 192: -#line 1912 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1924 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!InsertElementInst::isValidOperands((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal))) GEN_ERROR("Invalid insertelement operands"); @@ -4714,7 +4726,7 @@ break; case 193: -#line 1918 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1930 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ShuffleVectorInst::isValidOperands((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal))) GEN_ERROR("Invalid shufflevector operands"); @@ -4724,7 +4736,7 @@ break; case 194: -#line 1927 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1939 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ((yyval.ConstVector) = (yyvsp[(1) - (3)].ConstVector))->push_back((yyvsp[(3) - (3)].ConstVal)); CHECK_FOR_ERROR @@ -4732,7 +4744,7 @@ break; case 195: -#line 1931 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1943 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ConstVector) = new std::vector(); (yyval.ConstVector)->push_back((yyvsp[(1) - (1)].ConstVal)); @@ -4741,27 +4753,27 @@ break; case 196: -#line 1939 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1951 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; ;} break; case 197: -#line 1939 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1951 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; ;} break; case 198: -#line 1942 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1954 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; ;} break; case 199: -#line 1942 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1954 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; ;} break; case 200: -#line 1945 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1957 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const Type* VTy = (yyvsp[(1) - (2)].TypeVal)->get(); Value *V = getVal(VTy, (yyvsp[(2) - (2)].ValIDVal)); @@ -4777,7 +4789,7 @@ break; case 201: -#line 1957 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1969 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { Constant *Val = (yyvsp[(3) - (6)].ConstVal); const Type *DestTy = (yyvsp[(5) - (6)].TypeVal)->get(); @@ -4793,7 +4805,7 @@ break; case 202: -#line 1978 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1990 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = ParserResult = CurModule.CurrentModule; CurModule.ModuleDone(); @@ -4802,7 +4814,7 @@ break; case 203: -#line 1983 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1995 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = ParserResult = CurModule.CurrentModule; CurModule.ModuleDone(); @@ -4811,12 +4823,12 @@ break; case 206: -#line 1996 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2008 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = false; ;} break; case 207: -#line 1996 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2008 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.FunctionDone(); CHECK_FOR_ERROR @@ -4824,26 +4836,26 @@ break; case 208: -#line 2000 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2012 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = true; ;} break; case 209: -#line 2000 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2012 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 210: -#line 2003 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2015 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 211: -#line 2006 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2018 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (3)].TypeVal))->getDescription()); @@ -4871,7 +4883,7 @@ break; case 212: -#line 2030 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2042 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ResolveTypeTo((yyvsp[(1) - (3)].StrVal), (yyvsp[(3) - (3)].PrimType)); @@ -4886,7 +4898,7 @@ break; case 213: -#line 2041 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2053 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { /* "Externally Visible" Linkage */ if ((yyvsp[(5) - (5)].ConstVal) == 0) @@ -4898,14 +4910,14 @@ break; case 214: -#line 2048 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2060 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ;} break; case 215: -#line 2052 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2064 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(6) - (6)].ConstVal) == 0) GEN_ERROR("Global value initializer is not a constant"); @@ -4915,14 +4927,14 @@ break; case 216: -#line 2057 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2069 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ;} break; case 217: -#line 2061 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2073 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(6) - (6)].TypeVal))->getDescription()); @@ -4933,7 +4945,7 @@ break; case 218: -#line 2067 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2079 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; CHECK_FOR_ERROR @@ -4941,7 +4953,7 @@ break; case 219: -#line 2071 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2083 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { std::string Name; if ((yyvsp[(1) - (5)].StrVal)) { @@ -4985,21 +4997,21 @@ break; case 220: -#line 2111 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2123 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 221: -#line 2114 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2126 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 222: -#line 2120 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2132 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); if (AsmSoFar.empty()) @@ -5012,7 +5024,7 @@ break; case 223: -#line 2130 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2142 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setTargetTriple(*(yyvsp[(3) - (3)].StrVal)); delete (yyvsp[(3) - (3)].StrVal); @@ -5020,7 +5032,7 @@ break; case 224: -#line 2134 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2146 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setDataLayout(*(yyvsp[(3) - (3)].StrVal)); delete (yyvsp[(3) - (3)].StrVal); @@ -5028,7 +5040,7 @@ break; case 226: -#line 2141 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2153 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(*(yyvsp[(3) - (3)].StrVal)); delete (yyvsp[(3) - (3)].StrVal); @@ -5037,7 +5049,7 @@ break; case 227: -#line 2146 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2158 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -5046,14 +5058,14 @@ break; case 228: -#line 2151 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2163 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 229: -#line 2160 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2172 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); @@ -5067,7 +5079,7 @@ break; case 230: -#line 2170 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2182 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -5081,7 +5093,7 @@ break; case 231: -#line 2181 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2193 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[(1) - (1)].ArgList); CHECK_FOR_ERROR @@ -5089,7 +5101,7 @@ break; case 232: -#line 2185 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2197 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[(1) - (3)].ArgList); struct ArgListEntry E; @@ -5102,7 +5114,7 @@ break; case 233: -#line 2194 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2206 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = new ArgListType; struct ArgListEntry E; @@ -5115,7 +5127,7 @@ break; case 234: -#line 2203 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2215 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = 0; CHECK_FOR_ERROR @@ -5123,7 +5135,7 @@ break; case 235: -#line 2209 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2221 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { std::string FunctionName(*(yyvsp[(3) - (9)].StrVal)); delete (yyvsp[(3) - (9)].StrVal); // Free strdup'd memory! @@ -5255,7 +5267,7 @@ break; case 238: -#line 2340 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2352 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = CurFun.CurrentFunction; @@ -5267,7 +5279,7 @@ break; case 241: -#line 2351 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2363 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); CHECK_FOR_ERROR @@ -5275,7 +5287,7 @@ break; case 242: -#line 2356 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2368 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.CurrentFunction->setLinkage((yyvsp[(1) - (3)].Linkage)); CurFun.CurrentFunction->setVisibility((yyvsp[(2) - (3)].Visibility)); @@ -5286,7 +5298,7 @@ break; case 243: -#line 2368 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2380 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR @@ -5294,7 +5306,7 @@ break; case 244: -#line 2372 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2384 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR @@ -5302,7 +5314,7 @@ break; case 245: -#line 2377 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2389 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // A reference to a direct constant (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].SInt64Val)); CHECK_FOR_ERROR @@ -5310,7 +5322,7 @@ break; case 246: -#line 2381 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2393 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].UInt64Val)); CHECK_FOR_ERROR @@ -5318,7 +5330,7 @@ break; case 247: -#line 2385 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2397 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Perhaps it's an FP constant? (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].FPVal)); CHECK_FOR_ERROR @@ -5326,7 +5338,7 @@ break; case 248: -#line 2389 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2401 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create(ConstantInt::getTrue()); CHECK_FOR_ERROR @@ -5334,7 +5346,7 @@ break; case 249: -#line 2393 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2405 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create(ConstantInt::getFalse()); CHECK_FOR_ERROR @@ -5342,7 +5354,7 @@ break; case 250: -#line 2397 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2409 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createNull(); CHECK_FOR_ERROR @@ -5350,7 +5362,7 @@ break; case 251: -#line 2401 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2413 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createUndef(); CHECK_FOR_ERROR @@ -5358,7 +5370,7 @@ break; case 252: -#line 2405 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2417 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // A vector zero constant. (yyval.ValIDVal) = ValID::createZeroInit(); CHECK_FOR_ERROR @@ -5366,7 +5378,7 @@ break; case 253: -#line 2409 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2421 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized packed vector const Type *ETy = (*(yyvsp[(2) - (3)].ConstVector))[0]->getType(); int NumElements = (yyvsp[(2) - (3)].ConstVector)->size(); @@ -5395,7 +5407,7 @@ break; case 254: -#line 2434 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2446 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].ConstVal)); CHECK_FOR_ERROR @@ -5403,7 +5415,7 @@ break; case 255: -#line 2438 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2450 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createInlineAsm(*(yyvsp[(3) - (5)].StrVal), *(yyvsp[(5) - (5)].StrVal), (yyvsp[(2) - (5)].BoolVal)); delete (yyvsp[(3) - (5)].StrVal); @@ -5413,7 +5425,7 @@ break; case 256: -#line 2448 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2460 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is it an integer reference...? (yyval.ValIDVal) = ValID::createLocalID((yyvsp[(1) - (1)].UIntVal)); CHECK_FOR_ERROR @@ -5421,7 +5433,7 @@ break; case 257: -#line 2452 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2464 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createGlobalID((yyvsp[(1) - (1)].UIntVal)); CHECK_FOR_ERROR @@ -5429,7 +5441,7 @@ break; case 258: -#line 2456 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2468 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? (yyval.ValIDVal) = ValID::createLocalName(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -5438,7 +5450,7 @@ break; case 259: -#line 2461 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2473 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? (yyval.ValIDVal) = ValID::createGlobalName(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -5447,7 +5459,7 @@ break; case 262: -#line 2474 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2486 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -5458,7 +5470,7 @@ break; case 263: -#line 2483 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2495 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); CHECK_FOR_ERROR @@ -5466,7 +5478,7 @@ break; case 264: -#line 2487 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2499 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Do not allow functions with 0 basic blocks (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); CHECK_FOR_ERROR @@ -5474,7 +5486,7 @@ break; case 265: -#line 2496 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2508 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { setValueName((yyvsp[(3) - (3)].TermInstVal), (yyvsp[(2) - (3)].StrVal)); CHECK_FOR_ERROR @@ -5486,7 +5498,7 @@ break; case 266: -#line 2505 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2517 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (CastInst *CI1 = dyn_cast((yyvsp[(2) - (2)].InstVal))) if (CastInst *CI2 = dyn_cast(CI1->getOperand(0))) @@ -5499,7 +5511,7 @@ break; case 267: -#line 2514 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2526 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Empty space between instruction lists (yyval.BasicBlockVal) = defineBBVal(ValID::createLocalID(CurFun.NextValNum)); CHECK_FOR_ERROR @@ -5507,7 +5519,7 @@ break; case 268: -#line 2518 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2530 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Labelled (named) basic block (yyval.BasicBlockVal) = defineBBVal(ValID::createLocalName(*(yyvsp[(1) - (1)].StrVal))); delete (yyvsp[(1) - (1)].StrVal); @@ -5517,7 +5529,7 @@ break; case 269: -#line 2525 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2537 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Return with a result... (yyval.TermInstVal) = new ReturnInst((yyvsp[(2) - (2)].ValueVal)); CHECK_FOR_ERROR @@ -5525,7 +5537,7 @@ break; case 270: -#line 2529 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2541 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Return with no result... (yyval.TermInstVal) = new ReturnInst(); CHECK_FOR_ERROR @@ -5533,7 +5545,7 @@ break; case 271: -#line 2533 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2545 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Unconditional Branch... BasicBlock* tmpBB = getBBVal((yyvsp[(3) - (3)].ValIDVal)); CHECK_FOR_ERROR @@ -5542,7 +5554,7 @@ break; case 272: -#line 2538 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2550 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { assert(cast((yyvsp[(2) - (9)].PrimType))->getBitWidth() == 1 && "Not Bool?"); BasicBlock* tmpBBA = getBBVal((yyvsp[(6) - (9)].ValIDVal)); @@ -5556,7 +5568,7 @@ break; case 273: -#line 2548 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2560 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { Value* tmpVal = getVal((yyvsp[(2) - (9)].PrimType), (yyvsp[(3) - (9)].ValIDVal)); CHECK_FOR_ERROR @@ -5579,7 +5591,7 @@ break; case 274: -#line 2567 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2579 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { Value* tmpVal = getVal((yyvsp[(2) - (8)].PrimType), (yyvsp[(3) - (8)].ValIDVal)); CHECK_FOR_ERROR @@ -5592,7 +5604,7 @@ break; case 275: -#line 2577 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2589 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Handle the short syntax @@ -5679,7 +5691,7 @@ break; case 276: -#line 2660 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2672 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TermInstVal) = new UnwindInst(); CHECK_FOR_ERROR @@ -5687,7 +5699,7 @@ break; case 277: -#line 2664 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2676 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TermInstVal) = new UnreachableInst(); CHECK_FOR_ERROR @@ -5695,7 +5707,7 @@ break; case 278: -#line 2671 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2683 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.JumpTable) = (yyvsp[(1) - (6)].JumpTable); Constant *V = cast(getExistingVal((yyvsp[(2) - (6)].PrimType), (yyvsp[(3) - (6)].ValIDVal))); @@ -5710,7 +5722,7 @@ break; case 279: -#line 2682 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2694 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.JumpTable) = new std::vector >(); Constant *V = cast(getExistingVal((yyvsp[(1) - (5)].PrimType), (yyvsp[(2) - (5)].ValIDVal))); @@ -5726,7 +5738,7 @@ break; case 280: -#line 2695 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2707 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is this definition named?? if so, assign the name... setValueName((yyvsp[(2) - (2)].InstVal), (yyvsp[(1) - (2)].StrVal)); @@ -5738,7 +5750,7 @@ break; case 281: -#line 2705 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2717 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Used for PHI nodes if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (6)].TypeVal))->getDescription()); @@ -5753,7 +5765,7 @@ break; case 282: -#line 2716 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2728 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.PHIList) = (yyvsp[(1) - (7)].PHIList); Value* tmpVal = getVal((yyvsp[(1) - (7)].PHIList)->front().first->getType(), (yyvsp[(4) - (7)].ValIDVal)); @@ -5765,7 +5777,7 @@ break; case 283: -#line 2726 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2738 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 if (!UpRefs.empty()) @@ -5780,7 +5792,7 @@ break; case 284: -#line 2737 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2749 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 // Labels are only valid in ASMs @@ -5792,7 +5804,7 @@ break; case 285: -#line 2745 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2757 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 if (!UpRefs.empty()) @@ -5806,7 +5818,7 @@ break; case 286: -#line 2755 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2767 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 (yyval.ParamList) = (yyvsp[(1) - (6)].ParamList); @@ -5817,17 +5829,17 @@ break; case 287: -#line 2762 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2774 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamList) = new ParamList(); ;} break; case 288: -#line 2765 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2777 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = new std::vector(); ;} break; case 289: -#line 2766 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2778 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = (yyvsp[(1) - (3)].ValueList); (yyval.ValueList)->push_back((yyvsp[(3) - (3)].ValueVal)); @@ -5836,7 +5848,7 @@ break; case 290: -#line 2773 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2785 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR @@ -5844,7 +5856,7 @@ break; case 291: -#line 2777 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2789 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR @@ -5852,7 +5864,7 @@ break; case 292: -#line 2782 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2794 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); @@ -5872,7 +5884,7 @@ break; case 293: -#line 2798 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2810 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); @@ -5893,7 +5905,7 @@ break; case 294: -#line 2815 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2827 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); @@ -5911,7 +5923,7 @@ break; case 295: -#line 2829 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2841 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); @@ -5929,7 +5941,7 @@ break; case 296: -#line 2843 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2855 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(4) - (4)].TypeVal))->getDescription()); @@ -5945,7 +5957,7 @@ break; case 297: -#line 2855 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2867 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(2) - (6)].ValueVal)->getType() != Type::Int1Ty) GEN_ERROR("select condition must be boolean"); @@ -5957,7 +5969,7 @@ break; case 298: -#line 2863 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2875 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(4) - (4)].TypeVal))->getDescription()); @@ -5968,7 +5980,7 @@ break; case 299: -#line 2870 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2882 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ExtractElementInst::isValidOperands((yyvsp[(2) - (4)].ValueVal), (yyvsp[(4) - (4)].ValueVal))) GEN_ERROR("Invalid extractelement operands"); @@ -5978,7 +5990,7 @@ break; case 300: -#line 2876 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2888 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!InsertElementInst::isValidOperands((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal))) GEN_ERROR("Invalid insertelement operands"); @@ -5988,7 +6000,7 @@ break; case 301: -#line 2882 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2894 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ShuffleVectorInst::isValidOperands((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal))) GEN_ERROR("Invalid shufflevector operands"); @@ -5998,7 +6010,7 @@ break; case 302: -#line 2888 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2900 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = (yyvsp[(2) - (2)].PHIList)->front().first->getType(); if (!Ty->isFirstClassType()) @@ -6017,7 +6029,7 @@ break; case 303: -#line 2904 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2916 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Handle the short syntax @@ -6111,7 +6123,7 @@ break; case 304: -#line 2994 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3006 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.InstVal) = (yyvsp[(1) - (1)].InstVal); CHECK_FOR_ERROR @@ -6119,7 +6131,7 @@ break; case 305: -#line 2999 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3011 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR @@ -6127,7 +6139,7 @@ break; case 306: -#line 3003 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3015 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR @@ -6135,7 +6147,7 @@ break; case 307: -#line 3010 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3022 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (3)].TypeVal))->getDescription()); @@ -6146,7 +6158,7 @@ break; case 308: -#line 3017 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3029 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (6)].TypeVal))->getDescription()); @@ -6158,7 +6170,7 @@ break; case 309: -#line 3025 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3037 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (3)].TypeVal))->getDescription()); @@ -6169,7 +6181,7 @@ break; case 310: -#line 3032 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3044 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (6)].TypeVal))->getDescription()); @@ -6181,7 +6193,7 @@ break; case 311: -#line 3040 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3052 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!isa((yyvsp[(2) - (2)].ValueVal)->getType())) GEN_ERROR("Trying to free nonpointer type " + @@ -6192,7 +6204,7 @@ break; case 312: -#line 3048 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3060 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); @@ -6210,7 +6222,7 @@ break; case 313: -#line 3062 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3074 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(5) - (7)].TypeVal))->getDescription()); @@ -6231,7 +6243,7 @@ break; case 314: -#line 3079 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3091 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (4)].TypeVal))->getDescription()); @@ -6251,7 +6263,7 @@ /* Line 1267 of yacc.c. */ -#line 6255 "llvmAsmParser.tab.c" +#line 6267 "llvmAsmParser.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -6465,7 +6477,7 @@ } -#line 3096 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 3108 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" // common code from the two 'RunVMAsmParser' functions Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.h.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.h.cvs?rev=44541&r1=44540&r2=44541&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.h.cvs (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.h.cvs Mon Dec 3 13:17:47 2007 @@ -338,7 +338,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 945 "/home/duncan/LLVM/llvm.top/llvm/lib/AsmParser/llvmAsmParser.y" +#line 945 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { llvm::Module *ModuleVal; llvm::Function *FunctionVal; From asl at math.spbu.ru Mon Dec 3 13:16:13 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 22:16:13 +0300 Subject: [llvm-commits] [llvm] r44539 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/Crash-2007-12-03.ll In-Reply-To: <200712031917.lB3JHLnZ021617.SS4408SS@zion.cs.uiuc.edu> References: <200712031917.lB3JHLnZ021617.SS4408SS@zion.cs.uiuc.edu> Message-ID: <1196709373.15652.0.camel@asl.dorms.spbu.ru> Hello Devang, > If ExitValue operand is also defined in Loop header then > insert new ExitValue after this operand definition. > > This fixes PR1828. Thanks alot! -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From criswell at uiuc.edu Mon Dec 3 13:34:25 2007 From: criswell at uiuc.edu (John Criswell) Date: Mon, 03 Dec 2007 19:34:25 -0000 Subject: [llvm-commits] [llvm] r44542 - /llvm/trunk/docs/WritingAnLLVMPass.html Message-ID: <200712031934.lB3JYPUm022250@zion.cs.uiuc.edu> Author: criswell Date: Mon Dec 3 13:34:25 2007 New Revision: 44542 URL: http://llvm.org/viewvc/llvm-project?rev=44542&view=rev Log: Fixed typo. Modified: llvm/trunk/docs/WritingAnLLVMPass.html Modified: llvm/trunk/docs/WritingAnLLVMPass.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=44542&r1=44541&r2=44542&view=diff ============================================================================== --- llvm/trunk/docs/WritingAnLLVMPass.html (original) +++ llvm/trunk/docs/WritingAnLLVMPass.html Mon Dec 3 13:34:25 2007 @@ -996,7 +996,7 @@

    -

    One of the main responsibilities of the PassManager is the make sure +

    One of the main responsibilities of the PassManager is to make sure that passes interact with each other correctly. Because PassManager tries to optimize the execution of passes it must know how the passes interact with each other and what dependencies exist between From sabre at nondot.org Mon Dec 3 13:43:19 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Dec 2007 19:43:19 -0000 Subject: [llvm-commits] [llvm] r44543 - /llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Message-ID: <200712031943.lB3JhJCO022666@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 3 13:43:18 2007 New Revision: 44543 URL: http://llvm.org/viewvc/llvm-project?rev=44543&view=rev Log: update file comment. Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp?rev=44543&r1=44542&r2=44543&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Mon Dec 3 13:43:18 2007 @@ -7,14 +7,17 @@ // //===----------------------------------------------------------------------===// // -// This file implements dead code elimination and basic block merging. -// Specifically: +// This file implements dead code elimination and basic block merging, along +// with a collection of other peephole control flow optimizations. For example: // // * Removes basic blocks with no predecessors. // * Merges a basic block into its predecessor if there is only one and the // predecessor only has one successor. // * Eliminates PHI nodes for basic blocks with a single predecessor. // * Eliminates a basic block that only contains an unconditional branch. +// * Changes invoke instructions to nounwind functions to be calls. +// * Change things like "if (x) if (y)" into "if (x&y)". +// * etc.. // //===----------------------------------------------------------------------===// From clattner at apple.com Mon Dec 3 13:50:23 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Dec 2007 11:50:23 -0800 Subject: [llvm-commits] PR889 final version In-Reply-To: References: Message-ID: On Dec 2, 2007, at 3:07 AM, pawel kunio wrote: > Hello, > Here comes the more or less final and complete version of patch for > PR889. The coding standard > enforced by Chris. I added the asserts as checks for Value-inherited > classes without destroyThis. > Should it be accepted, please submit as it seems, I havent got the > proper rights to do so. I'm getting a bunch of errors and warnings of this sort: llvm/Instructions.h:2206: warning: 'class llvm::FPToUIInst' has virtual functions but non-virtual destructor llvm/Instructions.h:2258: error: a class-key must be used when declaring a friend llvm/Instructions.h:2258: error: friend declaration does not name a class or function llvm/Instructions.h:2250: warning: 'class llvm::FPToSIInst' has virtual functions but non-virtual destructor llvm/Instructions.h:2302: error: a class-key must be used when declaring a friend llvm/Instructions.h:2302: error: friend declaration does not name a class or function llvm/Instructions.h:2294: warning: 'class llvm::IntToPtrInst' has virtual functions but non-virtual destruct To work around the first one, please mark value's dtor virtual temporarily. To fix the others, please use "friend class foo" instead of "friend foo". -Chris From baldrick at free.fr Mon Dec 3 14:06:50 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 03 Dec 2007 20:06:50 -0000 Subject: [llvm-commits] [llvm] r44544 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/Analysis/ lib/Analysis/IPA/ lib/CodeGen/SelectionDAG/ lib/Target/CBackend/ lib/Target/MSIL/ lib/Transforms/IPO/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ tools/bugpoint/ utils/TableGen/ Message-ID: <200712032006.lB3K6pjo023855@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 3 14:06:50 2007 New Revision: 44544 URL: http://llvm.org/viewvc/llvm-project?rev=44544&view=rev Log: Rather than having special rules like "intrinsics cannot throw exceptions", just mark intrinsics with the nounwind attribute. Likewise, mark intrinsics as readnone/readonly and get rid of special aliasing logic (which didn't use anything more than this anyway). Modified: llvm/trunk/include/llvm/Function.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Intrinsics.h llvm/trunk/include/llvm/Support/CallSite.h llvm/trunk/lib/Analysis/AliasAnalysis.cpp llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/lib/Analysis/IPA/CallGraph.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/CBackend/CBackend.cpp llvm/trunk/lib/Target/MSIL/MSILWriter.cpp llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp llvm/trunk/lib/Transforms/Scalar/LowerGC.cpp llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/VMCore/AutoUpgrade.cpp llvm/trunk/lib/VMCore/Function.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/Mangler.cpp llvm/trunk/tools/bugpoint/Miscompilation.cpp llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp llvm/trunk/utils/TableGen/IntrinsicEmitter.h Modified: llvm/trunk/include/llvm/Function.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Function.h?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/include/llvm/Function.h (original) +++ llvm/trunk/include/llvm/Function.h Mon Dec 3 14:06:50 2007 @@ -158,6 +158,16 @@ return ParamAttrs && ParamAttrs->paramHasAttr(i, attr); } + /// @brief Determine if the function does not access memory. + bool doesNotAccessMemory() const { + return paramHasAttr(0, ParamAttr::ReadNone); + } + + /// @brief Determine if the function does not access or only reads memory. + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); + } + /// @brief Determine if the function returns a structure. bool isStructReturn() const { return paramHasAttr(1, ParamAttr::StructRet); Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Mon Dec 3 14:06:50 2007 @@ -927,6 +927,21 @@ /// @brief Determine whether the call or the callee has the given attribute. bool paramHasAttr(uint16_t i, ParameterAttributes attr) const; + /// @brief Determine if the call does not access memory. + bool doesNotAccessMemory() const { + return paramHasAttr(0, ParamAttr::ReadNone); + } + + /// @brief Determine if the call does not access or only reads memory. + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); + } + + /// @brief Determine if the call cannot unwind. + bool isNoUnwind() const { + return paramHasAttr(0, ParamAttr::NoUnwind); + } + /// @brief Determine if the call returns a structure. bool isStructReturn() const { // Be friendly and also check the callee. @@ -1711,6 +1726,21 @@ /// @brief Determine whether the call or the callee has the given attribute. bool paramHasAttr(uint16_t i, ParameterAttributes attr) const; + /// @brief Determine if the call does not access memory. + bool doesNotAccessMemory() const { + return paramHasAttr(0, ParamAttr::ReadNone); + } + + /// @brief Determine if the call does not access or only reads memory. + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); + } + + /// @brief Determine if the call cannot unwind. + bool isNoUnwind() const { + return paramHasAttr(0, ParamAttr::NoUnwind); + } + /// @brief Determine if the call returns a structure. bool isStructReturn() const { // Be friendly and also check the callee. Modified: llvm/trunk/include/llvm/Intrinsics.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.h?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.h (original) +++ llvm/trunk/include/llvm/Intrinsics.h Mon Dec 3 14:06:50 2007 @@ -22,6 +22,7 @@ class FunctionType; class Function; class Module; +class ParamAttrsList; /// Intrinsic Namespace - This namespace contains an enum with a value for /// every intrinsic/builtin function known by LLVM. These enum values are @@ -46,6 +47,10 @@ /// const FunctionType *getType(ID id, const Type **Tys = 0, unsigned numTys = 0); + /// Intrinsic::getParamAttrs(ID) - Return the attributes for an intrinsic. + /// + const ParamAttrsList *getParamAttrs(ID id); + /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function /// declaration for an intrinsic, and return it. Function *getDeclaration(Module *M, ID id, const Type **Tys = 0, Modified: llvm/trunk/include/llvm/Support/CallSite.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CallSite.h?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CallSite.h (original) +++ llvm/trunk/include/llvm/Support/CallSite.h Mon Dec 3 14:06:50 2007 @@ -67,6 +67,12 @@ /// paramHasAttr - whether the call or the callee has the given attribute. bool paramHasAttr(uint16_t i, ParameterAttributes attr) const; + /// @brief Determine if the call does not access memory. + bool doesNotAccessMemory() const; + + /// @brief Determine if the call does not access or only reads memory. + bool onlyReadsMemory() const; + /// getType - Return the type of the instruction that generated this call site /// const Type *getType() const { return I->getType(); } Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Mon Dec 3 14:06:50 2007 @@ -116,13 +116,13 @@ AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(CallSite CS, std::vector *Info) { - if (CS.paramHasAttr(0, ParamAttr::ReadNone)) + if (CS.doesNotAccessMemory()) // Can't do better than this. return DoesNotAccessMemory; ModRefBehavior MRB = UnknownModRefBehavior; if (Function *F = CS.getCalledFunction()) MRB = getModRefBehavior(F, CS, Info); - if (MRB != DoesNotAccessMemory && CS.paramHasAttr(0, ParamAttr::ReadOnly)) + if (MRB != DoesNotAccessMemory && CS.onlyReadsMemory()) return OnlyReadsMemory; return MRB; } @@ -130,11 +130,11 @@ AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(Function *F, std::vector *Info) { - if (F->paramHasAttr(0, ParamAttr::ReadNone)) + if (F->doesNotAccessMemory()) // Can't do better than this. return DoesNotAccessMemory; ModRefBehavior MRB = getModRefBehavior(F, CallSite(), Info); - if (MRB != DoesNotAccessMemory && F->paramHasAttr(0, ParamAttr::ReadOnly)) + if (MRB != DoesNotAccessMemory && F->onlyReadsMemory()) return OnlyReadsMemory; return MRB; } Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Dec 3 14:06:50 2007 @@ -25,8 +25,6 @@ #include "llvm/Pass.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/GetElementPtrTypeIterator.h" @@ -116,9 +114,6 @@ /// global) or not. bool pointsToConstantMemory(const Value *P); - virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS, - std::vector *Info); - private: // CheckGEPInstructions - Check two GEP instructions with known // must-aliasing base pointers. This checks to see if the index expressions @@ -810,37 +805,5 @@ return MayAlias; } -static ManagedStatic NoMemoryIntrinsics; -static ManagedStatic OnlyReadsMemoryIntrinsics; - -AliasAnalysis::ModRefBehavior -BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS, - std::vector *Info) { - if (!F->isDeclaration()) return UnknownModRefBehavior; - - static bool Initialized = false; - if (!Initialized) { - NoMemoryIntrinsics->resize(Intrinsic::num_intrinsics); - OnlyReadsMemoryIntrinsics->resize(Intrinsic::num_intrinsics); -#define GET_MODREF_BEHAVIOR -#include "llvm/Intrinsics.gen" -#undef GET_MODREF_BEHAVIOR - - Initialized = true; - } - - // If this is an intrinsic, we can use lookup tables - if (unsigned id = F->getIntrinsicID()) { - if (NoMemoryIntrinsics->test(id)) - return DoesNotAccessMemory; - if (OnlyReadsMemoryIntrinsics->test(id)) - return OnlyReadsMemory; - - return UnknownModRefBehavior; - } - - return UnknownModRefBehavior; -} - // Make sure that anything that uses AliasAnalysis pulls in this file... DEFINING_FILE_FOR(BasicAliasAnalysis) Modified: llvm/trunk/lib/Analysis/IPA/CallGraph.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/CallGraph.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/CallGraph.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/CallGraph.cpp Mon Dec 3 14:06:50 2007 @@ -136,7 +136,7 @@ // If this function is not defined in this translation unit, it could call // anything. - if (F->isDeclaration() && !F->getIntrinsicID()) + if (F->isDeclaration() && !F->isIntrinsic()) Node->addCalledFunction(CallSite(), CallsExternalNode); // Loop over all of the users of the function... looking for callers... Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Dec 3 14:06:50 2007 @@ -2417,31 +2417,13 @@ I.isVolatile(), I.getAlignment())); } -/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot -/// access memory and has no other side effects at all. -static bool IntrinsicCannotAccessMemory(unsigned IntrinsicID) { -#define GET_NO_MEMORY_INTRINSICS -#include "llvm/Intrinsics.gen" -#undef GET_NO_MEMORY_INTRINSICS - return false; -} - -// IntrinsicOnlyReadsMemory - Return true if the specified intrinsic doesn't -// have any side-effects or if it only reads memory. -static bool IntrinsicOnlyReadsMemory(unsigned IntrinsicID) { -#define GET_SIDE_EFFECT_INFO -#include "llvm/Intrinsics.gen" -#undef GET_SIDE_EFFECT_INFO - return false; -} - /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC /// node. void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, unsigned Intrinsic) { - bool HasChain = !IntrinsicCannotAccessMemory(Intrinsic); - bool OnlyLoad = HasChain && IntrinsicOnlyReadsMemory(Intrinsic); - + bool HasChain = !I.doesNotAccessMemory(); + bool OnlyLoad = HasChain && I.onlyReadsMemory(); + // Build the operand list. SmallVector Ops; if (HasChain) { // If this intrinsic has side-effects, chainify it. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Mon Dec 3 14:06:50 2007 @@ -1551,7 +1551,7 @@ 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" && + if (!I->isIntrinsic() && I->getName() != "setjmp" && I->getName() != "longjmp" && I->getName() != "_setjmp") { if (I->hasExternalWeakLinkage()) Out << "extern "; Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original) +++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Mon Dec 3 14:06:50 2007 @@ -1586,7 +1586,7 @@ // Functions. for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) { // Skip intrisics - if (I->getIntrinsicID()) continue; + if (I->isIntrinsic()) continue; if (I->isDeclaration()) { const Function* F = I; std::string Name = getConvModopt(F->getCallingConv())+getValueName(F); Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Mon Dec 3 14:06:50 2007 @@ -284,7 +284,7 @@ Liveness RetValLiveness = F.getReturnType() == Type::VoidTy ? Live : Dead; if (!F.hasInternalLinkage() && - (!ShouldHackArguments() || F.getIntrinsicID())) + (!ShouldHackArguments() || F.isIntrinsic())) FunctionIntrinsicallyLive = true; else for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) { Modified: llvm/trunk/lib/Transforms/Scalar/LowerGC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LowerGC.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LowerGC.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LowerGC.cpp Mon Dec 3 14:06:50 2007 @@ -177,7 +177,7 @@ for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) if (CallInst *CI = dyn_cast(II++)) { if (!CI->getCalledFunction() || - !CI->getCalledFunction()->getIntrinsicID()) + !CI->getCalledFunction()->isIntrinsic()) NormalCalls.push_back(CI); // Remember all normal function calls. if (Function *F = CI->getCalledFunction()) Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Mon Dec 3 14:06:50 2007 @@ -135,7 +135,7 @@ // Turn invokes that call 'nounwind' functions into ordinary calls. if (InvokeInst *II = dyn_cast(BB->getTerminator())) - if (II->paramHasAttr(0, ParamAttr::NoUnwind)) { + if (II->isNoUnwind()) { ChangeToCall(II); Changed = true; } Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Dec 3 14:06:50 2007 @@ -69,13 +69,11 @@ if (!isa(I)) continue; CallInst *CI = cast(I); - // If this is an intrinsic function call or an inline asm, don't + // If this call cannot unwind or is an inline asm, don't // convert it to an invoke. - if ((CI->getCalledFunction() && - CI->getCalledFunction()->getIntrinsicID()) || - isa(CI->getCalledValue())) + if (CI->isNoUnwind() || isa(CI->getCalledValue())) continue; - + // Convert this function call into an invoke instruction. // First, split the basic block. BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc"); Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AutoUpgrade.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original) +++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Mon Dec 3 14:06:50 2007 @@ -20,7 +20,7 @@ using namespace llvm; -Function* llvm::UpgradeIntrinsicFunction(Function *F) { +static Function* UpgradeIntrinsicFunction1(Function *F) { assert(F && "Illegal to upgrade a non-existent Function."); // Get the Function's name. @@ -119,6 +119,17 @@ return 0; } +Function* llvm::UpgradeIntrinsicFunction(Function *F) { + Function *Upgraded = UpgradeIntrinsicFunction1(F); + + // Upgrade intrinsic attributes. This does not change the function. + if (Upgraded) + F = Upgraded; + if (unsigned id = F->getIntrinsicID(true)) + F->setParamAttrs(Intrinsic::getParamAttrs((Intrinsic::ID)id)); + return Upgraded; +} + // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the // upgraded intrinsic. All argument and return casting must be provided in // order to seamlessly integrate with existing context. Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Mon Dec 3 14:06:50 2007 @@ -18,6 +18,7 @@ #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "SymbolTableListTraitsImpl.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -435,12 +436,36 @@ return FunctionType::get(ResultTy, ArgTys, IsVarArg); } +const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { + static const ParamAttrsList *IntrinsicAttributes[Intrinsic::num_intrinsics]; + + if (IntrinsicAttributes[id]) + return IntrinsicAttributes[id]; + + ParamAttrsVector Attrs; + uint16_t Attr = ParamAttr::None; + +#define GET_INTRINSIC_ATTRIBUTES +#include "llvm/Intrinsics.gen" +#undef GET_INTRINSIC_ATTRIBUTES + + // Intrinsics cannot throw exceptions. + Attr |= ParamAttr::NoUnwind; + + Attrs.push_back(ParamAttrsWithIndex::get(0, Attr)); + IntrinsicAttributes[id] = ParamAttrsList::get(Attrs); + return IntrinsicAttributes[id]; +} + Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, unsigned numTys) { -// There can never be multiple globals with the same name of different types, -// because intrinsics must be a specific type. - return cast(M->getOrInsertFunction(getName(id, Tys, numTys), - getType(id, Tys, numTys))); + // There can never be multiple globals with the same name of different types, + // because intrinsics must be a specific type. + Function *F = + cast(M->getOrInsertFunction(getName(id, Tys, numTys), + getType(id, Tys, numTys))); + F->setParamAttrs(getParamAttrs(id)); + return F; } Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Mon Dec 3 14:06:50 2007 @@ -13,8 +13,8 @@ #include "llvm/Type.h" #include "llvm/Instructions.h" -#include "llvm/IntrinsicInst.h" #include "llvm/Function.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -197,31 +197,18 @@ return true; } -// IntrinsicOnlyReadsMemory - Return true if the specified intrinsic doesn't -// have any side-effects or if it only reads memory. -static bool IntrinsicOnlyReadsMemory(unsigned IntrinsicID) { -#define GET_SIDE_EFFECT_INFO -#include "llvm/Intrinsics.gen" -#undef GET_SIDE_EFFECT_INFO - return false; -} - /// mayWriteToMemory - Return true if this instruction may modify memory. /// bool Instruction::mayWriteToMemory() const { switch (getOpcode()) { default: return false; case Instruction::Free: - case Instruction::Store: case Instruction::Invoke: + case Instruction::Store: case Instruction::VAArg: return true; case Instruction::Call: - if (const IntrinsicInst *II = dyn_cast(this)) { - // If the intrinsic doesn't write memory, it is safe. - return !IntrinsicOnlyReadsMemory(II->getIntrinsicID()); - } - return true; + return !cast(this)->onlyReadsMemory(); case Instruction::Load: return cast(this)->isVolatile(); } Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Dec 3 14:06:50 2007 @@ -53,7 +53,18 @@ else return cast(I)->paramHasAttr(i, attr); } - +bool CallSite::doesNotAccessMemory() const { + if (CallInst *CI = dyn_cast(I)) + return CI->doesNotAccessMemory(); + else + return cast(I)->doesNotAccessMemory(); +} +bool CallSite::onlyReadsMemory() const { + if (CallInst *CI = dyn_cast(I)) + return CI->onlyReadsMemory(); + else + return cast(I)->onlyReadsMemory(); +} Modified: llvm/trunk/lib/VMCore/Mangler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Mangler.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Mangler.cpp (original) +++ llvm/trunk/lib/VMCore/Mangler.cpp Mon Dec 3 14:06:50 2007 @@ -135,7 +135,7 @@ // Name mangling occurs as follows: // - If V is an intrinsic function, do not change name at all // - Otherwise, mangling occurs if global collides with existing name. - if (isa(GV) && cast(GV)->getIntrinsicID()) { + if (isa(GV) && cast(GV)->isIntrinsic()) { Name = GV->getName(); // Is an intrinsic function } else if (!GV->hasName()) { // Must mangle the global into a unique ID. Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Mon Dec 3 14:06:50 2007 @@ -685,7 +685,7 @@ // Use the function we just added to get addresses of functions we need. for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc && - F->getIntrinsicID() == 0 /* ignore intrinsics */) { + !F->isIntrinsic() /* ignore intrinsics */) { Function *TestFn = Test->getFunction(F->getName()); // Don't forward functions which are external in the test module too. Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Mon Dec 3 14:06:50 2007 @@ -42,14 +42,8 @@ // Emit the intrinsic declaration generator. EmitGenerator(Ints, OS); - // Emit mod/ref info for each function. - EmitModRefInfo(Ints, OS); - - // Emit table of non-memory accessing intrinsics. - EmitNoMemoryInfo(Ints, OS); - - // Emit side effect info for each intrinsic. - EmitSideEffectInfo(Ints, OS); + // Emit the intrinsic parameter attributes. + EmitAttributes(Ints, OS); // Emit a list of intrinsics with corresponding GCC builtins. EmitGCCBuiltinList(Ints, OS); @@ -297,30 +291,11 @@ 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 << " NoMemoryIntrinsics->set(Intrinsic::" << Ints[i].EnumName << ");\n"; - break; - case CodeGenIntrinsic::ReadArgMem: - case CodeGenIntrinsic::ReadMem: - OS << " OnlyReadsMemoryIntrinsics->set(Intrinsic::" << Ints[i].EnumName << ");\n"; - break; - } - } - OS << "#endif\n\n"; -} - void IntrinsicEmitter:: -EmitNoMemoryInfo(const std::vector &Ints, std::ostream &OS) { - OS << "// SelectionDAGIsel code.\n"; - OS << "#ifdef GET_NO_MEMORY_INTRINSICS\n"; - OS << " switch (IntrinsicID) {\n"; +EmitAttributes(const std::vector &Ints, std::ostream &OS) { + OS << "// Add parameter attributes that are not common to all intrinsics.\n"; + OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; + OS << " switch (id) {\n"; OS << " default: break;\n"; for (unsigned i = 0, e = Ints.size(); i != e; ++i) { switch (Ints[i].ModRef) { @@ -330,28 +305,19 @@ break; } } - OS << " return true; // These intrinsics do not reference memory.\n"; - OS << " }\n"; - OS << "#endif\n\n"; -} - -void IntrinsicEmitter:: -EmitSideEffectInfo(const std::vector &Ints, std::ostream &OS){ - OS << "// Return true if doesn't access or only reads memory.\n"; - OS << "#ifdef GET_SIDE_EFFECT_INFO\n"; - OS << " switch (IntrinsicID) {\n"; - OS << " default: break;\n"; + OS << " Attr |= ParamAttr::ReadNone; // These do not access memory.\n"; + OS << " 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 << " Attr |= ParamAttr::ReadOnly; // These do not write memory.\n"; + OS << " break;\n"; OS << " }\n"; OS << "#endif\n\n"; } Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.h?rev=44544&r1=44543&r2=44544&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/IntrinsicEmitter.h (original) +++ llvm/trunk/utils/TableGen/IntrinsicEmitter.h Mon Dec 3 14:06:50 2007 @@ -37,12 +37,8 @@ std::ostream &OS); void EmitGenerator(const std::vector &Ints, std::ostream &OS); - void EmitModRefInfo(const std::vector &Ints, + void EmitAttributes(const std::vector &Ints, std::ostream &OS); - void EmitNoMemoryInfo(const std::vector &Ints, - std::ostream &OS); - void EmitSideEffectInfo(const std::vector &Ints, - std::ostream &OS); void EmitGCCBuiltinList(const std::vector &Ints, std::ostream &OS); void EmitIntrinsicToGCCBuiltinMap(const std::vector &Ints, From asl at math.spbu.ru Mon Dec 3 15:00:45 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 21:00:45 -0000 Subject: [llvm-commits] [llvm] r44545 - /llvm/trunk/lib/AsmParser/llvmAsmParser.y Message-ID: <200712032100.lB3L0j6h026375@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 3 15:00:45 2007 New Revision: 44545 URL: http://llvm.org/viewvc/llvm-project?rev=44545&view=rev Log: Fix fallout from my last patch: don't reject varargs functions :) Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=44545&r1=44544&r2=44545&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Mon Dec 3 15:00:45 2007 @@ -1331,22 +1331,26 @@ // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. const Type* RetTy = *$1; - if (!(RetTy->isFirstClassType() || isa(RetTy))) + if (!(RetTy->isFirstClassType() || RetTy == Type::VoidTy || + isa(RetTy))) GEN_ERROR("LLVM Functions cannot return aggregates"); std::vector Params; TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); - if (!(Ty->isFirstClassType() || isa(Ty))) - GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } - CHECK_FOR_ERROR bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete $3; // Delete the argument list delete $1; // Delete the return type handle @@ -1360,15 +1364,18 @@ TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); - if (!(Ty->isFirstClassType() || isa(Ty))) - GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } - CHECK_FOR_ERROR bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + FunctionType *FT = FunctionType::get($1, Params, isVarArg); delete $3; // Delete the argument list $$ = new PATypeHolder(HandleUpRefs(FT)); From asl at math.spbu.ru Mon Dec 3 15:01:30 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 03 Dec 2007 21:01:30 -0000 Subject: [llvm-commits] [llvm] r44546 - in /llvm/trunk/lib/AsmParser: llvmAsmParser.cpp.cvs llvmAsmParser.y.cvs Message-ID: <200712032101.lB3L1U7o026447@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 3 15:01:29 2007 New Revision: 44546 URL: http://llvm.org/viewvc/llvm-project?rev=44546&view=rev Log: Regenerate Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs?rev=44546&r1=44545&r2=44546&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs Mon Dec 3 15:01:29 2007 @@ -1824,24 +1824,24 @@ 1223, 1224, 1227, 1228, 1233, 1234, 1235, 1236, 1237, 1238, 1241, 1242, 1249, 1250, 1256, 1257, 1265, 1273, 1274, 1279, 1280, 1281, 1286, 1299, 1299, 1299, 1299, 1299, 1299, 1299, - 1302, 1306, 1310, 1317, 1322, 1330, 1356, 1378, 1383, 1393, - 1403, 1407, 1417, 1424, 1433, 1440, 1445, 1450, 1457, 1458, - 1465, 1472, 1480, 1486, 1498, 1526, 1542, 1569, 1597, 1623, - 1643, 1669, 1689, 1701, 1708, 1774, 1784, 1794, 1800, 1810, - 1816, 1826, 1831, 1836, 1849, 1861, 1883, 1891, 1897, 1908, - 1913, 1918, 1924, 1930, 1939, 1943, 1951, 1951, 1954, 1954, - 1957, 1969, 1990, 1995, 2003, 2004, 2008, 2008, 2012, 2012, - 2015, 2018, 2042, 2053, 2053, 2064, 2063, 2073, 2072, 2083, - 2123, 2126, 2132, 2142, 2146, 2151, 2153, 2158, 2163, 2172, - 2182, 2193, 2197, 2206, 2215, 2220, 2350, 2350, 2352, 2361, - 2361, 2363, 2368, 2380, 2384, 2389, 2393, 2397, 2401, 2405, - 2409, 2413, 2417, 2421, 2446, 2450, 2460, 2464, 2468, 2473, - 2480, 2480, 2486, 2495, 2499, 2508, 2517, 2526, 2530, 2537, - 2541, 2545, 2550, 2560, 2579, 2588, 2672, 2676, 2683, 2694, - 2707, 2717, 2728, 2738, 2749, 2757, 2767, 2774, 2777, 2778, - 2785, 2789, 2794, 2810, 2827, 2841, 2855, 2867, 2875, 2882, - 2888, 2894, 2900, 2915, 3006, 3011, 3015, 3022, 3029, 3037, - 3044, 3052, 3060, 3074, 3091 + 1302, 1306, 1310, 1317, 1322, 1330, 1360, 1385, 1390, 1400, + 1410, 1414, 1424, 1431, 1440, 1447, 1452, 1457, 1464, 1465, + 1472, 1479, 1487, 1493, 1505, 1533, 1549, 1576, 1604, 1630, + 1650, 1676, 1696, 1708, 1715, 1781, 1791, 1801, 1807, 1817, + 1823, 1833, 1838, 1843, 1856, 1868, 1890, 1898, 1904, 1915, + 1920, 1925, 1931, 1937, 1946, 1950, 1958, 1958, 1961, 1961, + 1964, 1976, 1997, 2002, 2010, 2011, 2015, 2015, 2019, 2019, + 2022, 2025, 2049, 2060, 2060, 2071, 2070, 2080, 2079, 2090, + 2130, 2133, 2139, 2149, 2153, 2158, 2160, 2165, 2170, 2179, + 2189, 2200, 2204, 2213, 2222, 2227, 2357, 2357, 2359, 2368, + 2368, 2370, 2375, 2387, 2391, 2396, 2400, 2404, 2408, 2412, + 2416, 2420, 2424, 2428, 2453, 2457, 2467, 2471, 2475, 2480, + 2487, 2487, 2493, 2502, 2506, 2515, 2524, 2533, 2537, 2544, + 2548, 2552, 2557, 2567, 2586, 2595, 2679, 2683, 2690, 2701, + 2714, 2724, 2735, 2745, 2756, 2764, 2774, 2781, 2784, 2785, + 2792, 2796, 2801, 2817, 2834, 2848, 2862, 2874, 2882, 2889, + 2895, 2901, 2907, 2922, 3013, 3018, 3022, 3029, 3036, 3044, + 3051, 3059, 3067, 3081, 3098 }; #endif @@ -3969,22 +3969,26 @@ // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. const Type* RetTy = *(yyvsp[(1) - (5)].TypeVal); - if (!(RetTy->isFirstClassType() || isa(RetTy))) + if (!(RetTy->isFirstClassType() || RetTy == Type::VoidTy || + isa(RetTy))) GEN_ERROR("LLVM Functions cannot return aggregates"); - + std::vector Params; TypeWithAttrsList::iterator I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin(), E = (yyvsp[(3) - (5)].TypeWithAttrsList)->end(); for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); - if (!(Ty->isFirstClassType() || isa(Ty))) - GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } - CHECK_FOR_ERROR - + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete (yyvsp[(3) - (5)].TypeWithAttrsList); // Delete the argument list delete (yyvsp[(1) - (5)].TypeVal); // Delete the return type handle @@ -3994,7 +3998,7 @@ break; case 146: -#line 1356 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1360 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -4002,15 +4006,18 @@ TypeWithAttrsList::iterator I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin(), E = (yyvsp[(3) - (5)].TypeWithAttrsList)->end(); for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); - if (!(Ty->isFirstClassType() || isa(Ty))) - GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } - CHECK_FOR_ERROR - + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + FunctionType *FT = FunctionType::get((yyvsp[(1) - (5)].PrimType), Params, isVarArg); delete (yyvsp[(3) - (5)].TypeWithAttrsList); // Delete the argument list (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(FT)); @@ -4019,7 +4026,7 @@ break; case 147: -#line 1378 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1385 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Sized array type? (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(ArrayType::get(*(yyvsp[(4) - (5)].TypeVal), (unsigned)(yyvsp[(2) - (5)].UInt64Val)))); delete (yyvsp[(4) - (5)].TypeVal); @@ -4028,7 +4035,7 @@ break; case 148: -#line 1383 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1390 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Vector type? const llvm::Type* ElemTy = (yyvsp[(4) - (5)].TypeVal)->get(); if ((unsigned)(yyvsp[(2) - (5)].UInt64Val) != (yyvsp[(2) - (5)].UInt64Val)) @@ -4042,7 +4049,7 @@ break; case 149: -#line 1393 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1400 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Structure type? std::vector Elements; for (std::list::iterator I = (yyvsp[(2) - (3)].TypeList)->begin(), @@ -4056,7 +4063,7 @@ break; case 150: -#line 1403 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1410 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector())); CHECK_FOR_ERROR @@ -4064,7 +4071,7 @@ break; case 151: -#line 1407 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1414 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { std::vector Elements; for (std::list::iterator I = (yyvsp[(3) - (5)].TypeList)->begin(), @@ -4078,7 +4085,7 @@ break; case 152: -#line 1417 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1424 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector(), true)); CHECK_FOR_ERROR @@ -4086,7 +4093,7 @@ break; case 153: -#line 1424 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1431 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -4096,7 +4103,7 @@ break; case 154: -#line 1433 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1440 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (1)].TypeVal))->getDescription()); @@ -4107,14 +4114,14 @@ break; case 155: -#line 1440 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1447 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder(Type::VoidTy); ;} break; case 156: -#line 1445 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1452 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); (yyval.TypeWithAttrsList)->push_back((yyvsp[(1) - (1)].TypeWithAttrs)); @@ -4123,7 +4130,7 @@ break; case 157: -#line 1450 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1457 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ((yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList))->push_back((yyvsp[(3) - (3)].TypeWithAttrs)); CHECK_FOR_ERROR @@ -4131,7 +4138,7 @@ break; case 159: -#line 1458 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1465 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList); TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None; @@ -4142,7 +4149,7 @@ break; case 160: -#line 1465 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1472 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList; TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None; @@ -4153,7 +4160,7 @@ break; case 161: -#line 1472 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1479 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); CHECK_FOR_ERROR @@ -4161,7 +4168,7 @@ break; case 162: -#line 1480 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1487 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList) = new std::list(); (yyval.TypeList)->push_back(*(yyvsp[(1) - (1)].TypeVal)); @@ -4171,7 +4178,7 @@ break; case 163: -#line 1486 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1493 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ((yyval.TypeList)=(yyvsp[(1) - (3)].TypeList))->push_back(*(yyvsp[(3) - (3)].TypeVal)); delete (yyvsp[(3) - (3)].TypeVal); @@ -4180,7 +4187,7 @@ break; case 164: -#line 1498 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1505 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); @@ -4212,7 +4219,7 @@ break; case 165: -#line 1526 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1533 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4232,7 +4239,7 @@ break; case 166: -#line 1542 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1549 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4263,7 +4270,7 @@ break; case 167: -#line 1569 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1576 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); @@ -4295,7 +4302,7 @@ break; case 168: -#line 1597 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1604 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast((yyvsp[(1) - (4)].TypeVal)->get()); if (STy == 0) @@ -4325,7 +4332,7 @@ break; case 169: -#line 1623 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1630 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4349,7 +4356,7 @@ break; case 170: -#line 1643 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1650 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast((yyvsp[(1) - (6)].TypeVal)->get()); if (STy == 0) @@ -4379,7 +4386,7 @@ break; case 171: -#line 1669 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1676 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (5)].TypeVal))->getDescription()); @@ -4403,7 +4410,7 @@ break; case 172: -#line 1689 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1696 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4419,7 +4426,7 @@ break; case 173: -#line 1701 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1708 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4430,7 +4437,7 @@ break; case 174: -#line 1708 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1715 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4500,7 +4507,7 @@ break; case 175: -#line 1774 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1781 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4514,7 +4521,7 @@ break; case 176: -#line 1784 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1791 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -4528,7 +4535,7 @@ break; case 177: -#line 1794 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1801 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantInt::isValueValidForType((yyvsp[(1) - (2)].PrimType), (yyvsp[(2) - (2)].SInt64Val))) GEN_ERROR("Constant value doesn't fit in type"); @@ -4538,7 +4545,7 @@ break; case 178: -#line 1800 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1807 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // arbitrary precision integer constants uint32_t BitWidth = cast((yyvsp[(1) - (2)].PrimType))->getBitWidth(); if ((yyvsp[(2) - (2)].APIntVal)->getBitWidth() > BitWidth) { @@ -4552,7 +4559,7 @@ break; case 179: -#line 1810 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1817 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantInt::isValueValidForType((yyvsp[(1) - (2)].PrimType), (yyvsp[(2) - (2)].UInt64Val))) GEN_ERROR("Constant value doesn't fit in type"); @@ -4562,7 +4569,7 @@ break; case 180: -#line 1816 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1823 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // arbitrary precision integer constants uint32_t BitWidth = cast((yyvsp[(1) - (2)].PrimType))->getBitWidth(); if ((yyvsp[(2) - (2)].APIntVal)->getBitWidth() > BitWidth) { @@ -4576,7 +4583,7 @@ break; case 181: -#line 1826 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1833 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Boolean constants assert(cast((yyvsp[(1) - (2)].PrimType))->getBitWidth() == 1 && "Not Bool?"); (yyval.ConstVal) = ConstantInt::getTrue(); @@ -4585,7 +4592,7 @@ break; case 182: -#line 1831 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1838 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Boolean constants assert(cast((yyvsp[(1) - (2)].PrimType))->getBitWidth() == 1 && "Not Bool?"); (yyval.ConstVal) = ConstantInt::getFalse(); @@ -4594,7 +4601,7 @@ break; case 183: -#line 1836 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1843 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Floating point constants if (!ConstantFP::isValueValidForType((yyvsp[(1) - (2)].PrimType), *(yyvsp[(2) - (2)].FPVal))) GEN_ERROR("Floating point constant invalid for type"); @@ -4609,7 +4616,7 @@ break; case 184: -#line 1849 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1856 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(5) - (6)].TypeVal))->getDescription()); @@ -4625,7 +4632,7 @@ break; case 185: -#line 1861 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1868 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!isa((yyvsp[(3) - (5)].ConstVal)->getType())) GEN_ERROR("GetElementPtr requires a pointer operand"); @@ -4651,7 +4658,7 @@ break; case 186: -#line 1883 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1890 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(3) - (8)].ConstVal)->getType() != Type::Int1Ty) GEN_ERROR("Select condition must be of boolean type"); @@ -4663,7 +4670,7 @@ break; case 187: -#line 1891 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1898 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(3) - (6)].ConstVal)->getType() != (yyvsp[(5) - (6)].ConstVal)->getType()) GEN_ERROR("Binary operator types must match"); @@ -4673,7 +4680,7 @@ break; case 188: -#line 1897 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1904 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(3) - (6)].ConstVal)->getType() != (yyvsp[(5) - (6)].ConstVal)->getType()) GEN_ERROR("Logical operator types must match"); @@ -4688,7 +4695,7 @@ break; case 189: -#line 1908 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1915 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) GEN_ERROR("icmp operand types must match"); @@ -4697,7 +4704,7 @@ break; case 190: -#line 1913 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1920 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) GEN_ERROR("fcmp operand types must match"); @@ -4706,7 +4713,7 @@ break; case 191: -#line 1918 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1925 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ExtractElementInst::isValidOperands((yyvsp[(3) - (6)].ConstVal), (yyvsp[(5) - (6)].ConstVal))) GEN_ERROR("Invalid extractelement operands"); @@ -4716,7 +4723,7 @@ break; case 192: -#line 1924 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1931 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!InsertElementInst::isValidOperands((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal))) GEN_ERROR("Invalid insertelement operands"); @@ -4726,7 +4733,7 @@ break; case 193: -#line 1930 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1937 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ShuffleVectorInst::isValidOperands((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal))) GEN_ERROR("Invalid shufflevector operands"); @@ -4736,7 +4743,7 @@ break; case 194: -#line 1939 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1946 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ((yyval.ConstVector) = (yyvsp[(1) - (3)].ConstVector))->push_back((yyvsp[(3) - (3)].ConstVal)); CHECK_FOR_ERROR @@ -4744,7 +4751,7 @@ break; case 195: -#line 1943 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1950 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ConstVector) = new std::vector(); (yyval.ConstVector)->push_back((yyvsp[(1) - (1)].ConstVal)); @@ -4753,27 +4760,27 @@ break; case 196: -#line 1951 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1958 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; ;} break; case 197: -#line 1951 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1958 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; ;} break; case 198: -#line 1954 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1961 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; ;} break; case 199: -#line 1954 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1961 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; ;} break; case 200: -#line 1957 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1964 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const Type* VTy = (yyvsp[(1) - (2)].TypeVal)->get(); Value *V = getVal(VTy, (yyvsp[(2) - (2)].ValIDVal)); @@ -4789,7 +4796,7 @@ break; case 201: -#line 1969 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1976 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { Constant *Val = (yyvsp[(3) - (6)].ConstVal); const Type *DestTy = (yyvsp[(5) - (6)].TypeVal)->get(); @@ -4805,7 +4812,7 @@ break; case 202: -#line 1990 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1997 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = ParserResult = CurModule.CurrentModule; CurModule.ModuleDone(); @@ -4814,7 +4821,7 @@ break; case 203: -#line 1995 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2002 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = ParserResult = CurModule.CurrentModule; CurModule.ModuleDone(); @@ -4823,12 +4830,12 @@ break; case 206: -#line 2008 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2015 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = false; ;} break; case 207: -#line 2008 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2015 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.FunctionDone(); CHECK_FOR_ERROR @@ -4836,26 +4843,26 @@ break; case 208: -#line 2012 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2019 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = true; ;} break; case 209: -#line 2012 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2019 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 210: -#line 2015 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2022 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 211: -#line 2018 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2025 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (3)].TypeVal))->getDescription()); @@ -4883,7 +4890,7 @@ break; case 212: -#line 2042 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2049 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { ResolveTypeTo((yyvsp[(1) - (3)].StrVal), (yyvsp[(3) - (3)].PrimType)); @@ -4898,7 +4905,7 @@ break; case 213: -#line 2053 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2060 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { /* "Externally Visible" Linkage */ if ((yyvsp[(5) - (5)].ConstVal) == 0) @@ -4910,14 +4917,14 @@ break; case 214: -#line 2060 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2067 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ;} break; case 215: -#line 2064 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2071 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(6) - (6)].ConstVal) == 0) GEN_ERROR("Global value initializer is not a constant"); @@ -4927,14 +4934,14 @@ break; case 216: -#line 2069 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2076 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ;} break; case 217: -#line 2073 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2080 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(6) - (6)].TypeVal))->getDescription()); @@ -4945,7 +4952,7 @@ break; case 218: -#line 2079 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2086 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; CHECK_FOR_ERROR @@ -4953,7 +4960,7 @@ break; case 219: -#line 2083 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2090 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { std::string Name; if ((yyvsp[(1) - (5)].StrVal)) { @@ -4997,21 +5004,21 @@ break; case 220: -#line 2123 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2130 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 221: -#line 2126 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2133 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 222: -#line 2132 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2139 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); if (AsmSoFar.empty()) @@ -5024,7 +5031,7 @@ break; case 223: -#line 2142 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2149 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setTargetTriple(*(yyvsp[(3) - (3)].StrVal)); delete (yyvsp[(3) - (3)].StrVal); @@ -5032,7 +5039,7 @@ break; case 224: -#line 2146 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2153 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setDataLayout(*(yyvsp[(3) - (3)].StrVal)); delete (yyvsp[(3) - (3)].StrVal); @@ -5040,7 +5047,7 @@ break; case 226: -#line 2153 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2160 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(*(yyvsp[(3) - (3)].StrVal)); delete (yyvsp[(3) - (3)].StrVal); @@ -5049,7 +5056,7 @@ break; case 227: -#line 2158 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2165 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -5058,14 +5065,14 @@ break; case 228: -#line 2163 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2170 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; case 229: -#line 2172 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2179 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); @@ -5079,7 +5086,7 @@ break; case 230: -#line 2182 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2189 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -5093,7 +5100,7 @@ break; case 231: -#line 2193 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2200 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[(1) - (1)].ArgList); CHECK_FOR_ERROR @@ -5101,7 +5108,7 @@ break; case 232: -#line 2197 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2204 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[(1) - (3)].ArgList); struct ArgListEntry E; @@ -5114,7 +5121,7 @@ break; case 233: -#line 2206 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2213 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = new ArgListType; struct ArgListEntry E; @@ -5127,7 +5134,7 @@ break; case 234: -#line 2215 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2222 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = 0; CHECK_FOR_ERROR @@ -5135,7 +5142,7 @@ break; case 235: -#line 2221 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2228 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { std::string FunctionName(*(yyvsp[(3) - (9)].StrVal)); delete (yyvsp[(3) - (9)].StrVal); // Free strdup'd memory! @@ -5267,7 +5274,7 @@ break; case 238: -#line 2352 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2359 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = CurFun.CurrentFunction; @@ -5279,7 +5286,7 @@ break; case 241: -#line 2363 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2370 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); CHECK_FOR_ERROR @@ -5287,7 +5294,7 @@ break; case 242: -#line 2368 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2375 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { CurFun.CurrentFunction->setLinkage((yyvsp[(1) - (3)].Linkage)); CurFun.CurrentFunction->setVisibility((yyvsp[(2) - (3)].Visibility)); @@ -5298,7 +5305,7 @@ break; case 243: -#line 2380 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2387 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR @@ -5306,7 +5313,7 @@ break; case 244: -#line 2384 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2391 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR @@ -5314,7 +5321,7 @@ break; case 245: -#line 2389 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2396 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // A reference to a direct constant (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].SInt64Val)); CHECK_FOR_ERROR @@ -5322,7 +5329,7 @@ break; case 246: -#line 2393 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2400 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].UInt64Val)); CHECK_FOR_ERROR @@ -5330,7 +5337,7 @@ break; case 247: -#line 2397 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2404 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Perhaps it's an FP constant? (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].FPVal)); CHECK_FOR_ERROR @@ -5338,7 +5345,7 @@ break; case 248: -#line 2401 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2408 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create(ConstantInt::getTrue()); CHECK_FOR_ERROR @@ -5346,7 +5353,7 @@ break; case 249: -#line 2405 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2412 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create(ConstantInt::getFalse()); CHECK_FOR_ERROR @@ -5354,7 +5361,7 @@ break; case 250: -#line 2409 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2416 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createNull(); CHECK_FOR_ERROR @@ -5362,7 +5369,7 @@ break; case 251: -#line 2413 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2420 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createUndef(); CHECK_FOR_ERROR @@ -5370,7 +5377,7 @@ break; case 252: -#line 2417 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2424 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // A vector zero constant. (yyval.ValIDVal) = ValID::createZeroInit(); CHECK_FOR_ERROR @@ -5378,7 +5385,7 @@ break; case 253: -#line 2421 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2428 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized packed vector const Type *ETy = (*(yyvsp[(2) - (3)].ConstVector))[0]->getType(); int NumElements = (yyvsp[(2) - (3)].ConstVector)->size(); @@ -5407,7 +5414,7 @@ break; case 254: -#line 2446 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2453 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].ConstVal)); CHECK_FOR_ERROR @@ -5415,7 +5422,7 @@ break; case 255: -#line 2450 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2457 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createInlineAsm(*(yyvsp[(3) - (5)].StrVal), *(yyvsp[(5) - (5)].StrVal), (yyvsp[(2) - (5)].BoolVal)); delete (yyvsp[(3) - (5)].StrVal); @@ -5425,7 +5432,7 @@ break; case 256: -#line 2460 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2467 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is it an integer reference...? (yyval.ValIDVal) = ValID::createLocalID((yyvsp[(1) - (1)].UIntVal)); CHECK_FOR_ERROR @@ -5433,7 +5440,7 @@ break; case 257: -#line 2464 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2471 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createGlobalID((yyvsp[(1) - (1)].UIntVal)); CHECK_FOR_ERROR @@ -5441,7 +5448,7 @@ break; case 258: -#line 2468 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2475 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? (yyval.ValIDVal) = ValID::createLocalName(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -5450,7 +5457,7 @@ break; case 259: -#line 2473 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2480 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? (yyval.ValIDVal) = ValID::createGlobalName(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -5459,7 +5466,7 @@ break; case 262: -#line 2486 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2493 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); @@ -5470,7 +5477,7 @@ break; case 263: -#line 2495 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2502 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); CHECK_FOR_ERROR @@ -5478,7 +5485,7 @@ break; case 264: -#line 2499 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2506 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Do not allow functions with 0 basic blocks (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); CHECK_FOR_ERROR @@ -5486,7 +5493,7 @@ break; case 265: -#line 2508 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2515 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { setValueName((yyvsp[(3) - (3)].TermInstVal), (yyvsp[(2) - (3)].StrVal)); CHECK_FOR_ERROR @@ -5498,7 +5505,7 @@ break; case 266: -#line 2517 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2524 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (CastInst *CI1 = dyn_cast((yyvsp[(2) - (2)].InstVal))) if (CastInst *CI2 = dyn_cast(CI1->getOperand(0))) @@ -5511,7 +5518,7 @@ break; case 267: -#line 2526 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2533 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Empty space between instruction lists (yyval.BasicBlockVal) = defineBBVal(ValID::createLocalID(CurFun.NextValNum)); CHECK_FOR_ERROR @@ -5519,7 +5526,7 @@ break; case 268: -#line 2530 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2537 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Labelled (named) basic block (yyval.BasicBlockVal) = defineBBVal(ValID::createLocalName(*(yyvsp[(1) - (1)].StrVal))); delete (yyvsp[(1) - (1)].StrVal); @@ -5529,7 +5536,7 @@ break; case 269: -#line 2537 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2544 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Return with a result... (yyval.TermInstVal) = new ReturnInst((yyvsp[(2) - (2)].ValueVal)); CHECK_FOR_ERROR @@ -5537,7 +5544,7 @@ break; case 270: -#line 2541 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2548 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Return with no result... (yyval.TermInstVal) = new ReturnInst(); CHECK_FOR_ERROR @@ -5545,7 +5552,7 @@ break; case 271: -#line 2545 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2552 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Unconditional Branch... BasicBlock* tmpBB = getBBVal((yyvsp[(3) - (3)].ValIDVal)); CHECK_FOR_ERROR @@ -5554,7 +5561,7 @@ break; case 272: -#line 2550 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2557 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { assert(cast((yyvsp[(2) - (9)].PrimType))->getBitWidth() == 1 && "Not Bool?"); BasicBlock* tmpBBA = getBBVal((yyvsp[(6) - (9)].ValIDVal)); @@ -5568,7 +5575,7 @@ break; case 273: -#line 2560 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2567 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { Value* tmpVal = getVal((yyvsp[(2) - (9)].PrimType), (yyvsp[(3) - (9)].ValIDVal)); CHECK_FOR_ERROR @@ -5591,7 +5598,7 @@ break; case 274: -#line 2579 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2586 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { Value* tmpVal = getVal((yyvsp[(2) - (8)].PrimType), (yyvsp[(3) - (8)].ValIDVal)); CHECK_FOR_ERROR @@ -5604,7 +5611,7 @@ break; case 275: -#line 2589 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2596 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Handle the short syntax @@ -5691,7 +5698,7 @@ break; case 276: -#line 2672 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2679 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TermInstVal) = new UnwindInst(); CHECK_FOR_ERROR @@ -5699,7 +5706,7 @@ break; case 277: -#line 2676 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2683 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.TermInstVal) = new UnreachableInst(); CHECK_FOR_ERROR @@ -5707,7 +5714,7 @@ break; case 278: -#line 2683 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2690 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.JumpTable) = (yyvsp[(1) - (6)].JumpTable); Constant *V = cast(getExistingVal((yyvsp[(2) - (6)].PrimType), (yyvsp[(3) - (6)].ValIDVal))); @@ -5722,7 +5729,7 @@ break; case 279: -#line 2694 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2701 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.JumpTable) = new std::vector >(); Constant *V = cast(getExistingVal((yyvsp[(1) - (5)].PrimType), (yyvsp[(2) - (5)].ValIDVal))); @@ -5738,7 +5745,7 @@ break; case 280: -#line 2707 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2714 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Is this definition named?? if so, assign the name... setValueName((yyvsp[(2) - (2)].InstVal), (yyvsp[(1) - (2)].StrVal)); @@ -5750,7 +5757,7 @@ break; case 281: -#line 2717 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2724 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Used for PHI nodes if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (6)].TypeVal))->getDescription()); @@ -5765,7 +5772,7 @@ break; case 282: -#line 2728 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2735 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.PHIList) = (yyvsp[(1) - (7)].PHIList); Value* tmpVal = getVal((yyvsp[(1) - (7)].PHIList)->front().first->getType(), (yyvsp[(4) - (7)].ValIDVal)); @@ -5777,7 +5784,7 @@ break; case 283: -#line 2738 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2745 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 if (!UpRefs.empty()) @@ -5792,7 +5799,7 @@ break; case 284: -#line 2749 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2756 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 // Labels are only valid in ASMs @@ -5804,7 +5811,7 @@ break; case 285: -#line 2757 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2764 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 if (!UpRefs.empty()) @@ -5818,7 +5825,7 @@ break; case 286: -#line 2767 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2774 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0 (yyval.ParamList) = (yyvsp[(1) - (6)].ParamList); @@ -5829,17 +5836,17 @@ break; case 287: -#line 2774 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2781 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamList) = new ParamList(); ;} break; case 288: -#line 2777 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2784 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = new std::vector(); ;} break; case 289: -#line 2778 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2785 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = (yyvsp[(1) - (3)].ValueList); (yyval.ValueList)->push_back((yyvsp[(3) - (3)].ValueVal)); @@ -5848,7 +5855,7 @@ break; case 290: -#line 2785 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2792 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR @@ -5856,7 +5863,7 @@ break; case 291: -#line 2789 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2796 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR @@ -5864,7 +5871,7 @@ break; case 292: -#line 2794 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2801 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); @@ -5884,7 +5891,7 @@ break; case 293: -#line 2810 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2817 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); @@ -5905,7 +5912,7 @@ break; case 294: -#line 2827 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2834 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); @@ -5923,7 +5930,7 @@ break; case 295: -#line 2841 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2848 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); @@ -5941,7 +5948,7 @@ break; case 296: -#line 2855 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2862 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(4) - (4)].TypeVal))->getDescription()); @@ -5957,7 +5964,7 @@ break; case 297: -#line 2867 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2874 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(2) - (6)].ValueVal)->getType() != Type::Int1Ty) GEN_ERROR("select condition must be boolean"); @@ -5969,7 +5976,7 @@ break; case 298: -#line 2875 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2882 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(4) - (4)].TypeVal))->getDescription()); @@ -5980,7 +5987,7 @@ break; case 299: -#line 2882 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2889 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ExtractElementInst::isValidOperands((yyvsp[(2) - (4)].ValueVal), (yyvsp[(4) - (4)].ValueVal))) GEN_ERROR("Invalid extractelement operands"); @@ -5990,7 +5997,7 @@ break; case 300: -#line 2888 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2895 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!InsertElementInst::isValidOperands((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal))) GEN_ERROR("Invalid insertelement operands"); @@ -6000,7 +6007,7 @@ break; case 301: -#line 2894 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2901 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!ShuffleVectorInst::isValidOperands((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal))) GEN_ERROR("Invalid shufflevector operands"); @@ -6010,7 +6017,7 @@ break; case 302: -#line 2900 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2907 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = (yyvsp[(2) - (2)].PHIList)->front().first->getType(); if (!Ty->isFirstClassType()) @@ -6029,7 +6036,7 @@ break; case 303: -#line 2916 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 2923 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { // Handle the short syntax @@ -6123,7 +6130,7 @@ break; case 304: -#line 3006 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3013 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.InstVal) = (yyvsp[(1) - (1)].InstVal); CHECK_FOR_ERROR @@ -6131,7 +6138,7 @@ break; case 305: -#line 3011 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3018 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR @@ -6139,7 +6146,7 @@ break; case 306: -#line 3015 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3022 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR @@ -6147,7 +6154,7 @@ break; case 307: -#line 3022 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3029 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (3)].TypeVal))->getDescription()); @@ -6158,7 +6165,7 @@ break; case 308: -#line 3029 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3036 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (6)].TypeVal))->getDescription()); @@ -6170,7 +6177,7 @@ break; case 309: -#line 3037 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3044 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (3)].TypeVal))->getDescription()); @@ -6181,7 +6188,7 @@ break; case 310: -#line 3044 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3051 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (6)].TypeVal))->getDescription()); @@ -6193,7 +6200,7 @@ break; case 311: -#line 3052 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3059 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!isa((yyvsp[(2) - (2)].ValueVal)->getType())) GEN_ERROR("Trying to free nonpointer type " + @@ -6204,7 +6211,7 @@ break; case 312: -#line 3060 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3067 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); @@ -6222,7 +6229,7 @@ break; case 313: -#line 3074 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3081 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(5) - (7)].TypeVal))->getDescription()); @@ -6243,7 +6250,7 @@ break; case 314: -#line 3091 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3098 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (4)].TypeVal))->getDescription()); @@ -6263,7 +6270,7 @@ /* Line 1267 of yacc.c. */ -#line 6267 "llvmAsmParser.tab.c" +#line 6274 "llvmAsmParser.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -6477,7 +6484,7 @@ } -#line 3108 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 3115 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" // common code from the two 'RunVMAsmParser' functions Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs?rev=44546&r1=44545&r2=44546&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs Mon Dec 3 15:01:29 2007 @@ -1331,22 +1331,26 @@ // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. const Type* RetTy = *$1; - if (!(RetTy->isFirstClassType() || isa(RetTy))) + if (!(RetTy->isFirstClassType() || RetTy == Type::VoidTy || + isa(RetTy))) GEN_ERROR("LLVM Functions cannot return aggregates"); std::vector Params; TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for (; I != E; ++I ) { const Type *Ty = I->Ty->get(); - if (!(Ty->isFirstClassType() || isa(Ty))) - GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } - CHECK_FOR_ERROR bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); delete $3; // Delete the argument list delete $1; // Delete the return type handle @@ -1360,15 +1364,18 @@ TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); for ( ; I != E; ++I ) { const Type* Ty = I->Ty->get(); - if (!(Ty->isFirstClassType() || isa(Ty))) - GEN_ERROR("Function arguments must be value types!"); Params.push_back(Ty); } - CHECK_FOR_ERROR bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); + for (unsigned i = 0; i != Params.size(); ++i) + if (!(Params[i]->isFirstClassType() || isa(Params[i]))) + GEN_ERROR("Function arguments must be value types!"); + + CHECK_FOR_ERROR + FunctionType *FT = FunctionType::get($1, Params, isVarArg); delete $3; // Delete the argument list $$ = new PATypeHolder(HandleUpRefs(FT)); From gordonhenriksen at mac.com Mon Dec 3 15:15:53 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 03 Dec 2007 21:15:53 -0000 Subject: [llvm-commits] [llvm] r44547 - /llvm/trunk/bindings/ocaml/Makefile.ocaml Message-ID: <200712032115.lB3LFrqM027180@zion.cs.uiuc.edu> Author: gordon Date: Mon Dec 3 15:15:53 2007 New Revision: 44547 URL: http://llvm.org/viewvc/llvm-project?rev=44547&view=rev Log: Track dependencies when creating symlinks to LLVM libraries next to the ocaml bindings. This is required on Windows where 'ln -sf' actually creates a copy. Thanks to Alain Frisch for noticing this. Modified: llvm/trunk/bindings/ocaml/Makefile.ocaml Modified: llvm/trunk/bindings/ocaml/Makefile.ocaml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/Makefile.ocaml?rev=44547&r1=44546&r2=44547&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/Makefile.ocaml (original) +++ llvm/trunk/bindings/ocaml/Makefile.ocaml Mon Dec 3 15:15:53 2007 @@ -70,11 +70,13 @@ OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa) OutputsCMI := $(ObjectsCMI:$(ObjDir)/%.cmi=$(OcamlDir)/%.cmi) OutputsCMX := $(ObjectsCMX:$(ObjDir)/%.cmx=$(OcamlDir)/%.cmx) +OutputLibs := $(UsedLibNames:%=$(OcamlDir)/%) # Installation targets DestA := $(PROJ_libocamldir)/lib$(LIBRARYNAME).a DestCMA := $(PROJ_libocamldir)/$(LIBRARYNAME).cma DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa +DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%) ##===- Dependencies -------------------------------------------------------===## @@ -123,6 +125,30 @@ -$(Verb) $(RM) -f $(DestA) +##===- Deposit dependent libraries adjacent to Ocaml libs -----------------===## + +all-local:: build-deplibs +clean-local:: clean-deplibs +install-local:: install-deplibs +uninstall-local:: uninstall-deplibs + +build-deplibs: $(OutputLibs) + +$(OcamlDir)/%.a: $(LibDir)/%.a + $(Verb) ln -sf $< $@ + +clean-deplibs: + $(Verb) rm -f $(OutputLibs) + +install-deplibs: + $(Verb) for i in $(DestLibs:$(PROJ_libocamldir)/%=%); do \ + ln -sf "$(PROJ_libdir)/$$i" "$(PROJ_libocamldir)/$$i"; \ + done + +uninstall-deplibs: + $(Verb) rm -f $(DestLibs) + + ##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===## all-local:: build-cmis @@ -178,9 +204,6 @@ $(LibraryCMA): $(ObjectsCMO) $(OcamlDir)/.dir $(Echo) "Archiving $(notdir $@) for $(BuildMode) build" $(Verb) $(Archive.CMA) $@ $(ObjectsCMO) - $(Verb) for i in $(UsedLibNames); do \ - ln -sf "$(LibDir)/$$i" "$(OcamlDir)/$$i"; \ - done $(ObjDir)/%.cmo: $(ObjDir)/%.ml $(Echo) "Compiling $(notdir $<) for $(BuildMode) build" @@ -193,16 +216,10 @@ $(Echo) "Installing $(BuildMode) $(DestCMA)" $(Verb) $(MKDIR) $(PROJ_libocamldir) $(Verb) $(DataInstall) $(OutputCMA) "$(DestCMA)" - $(Verb) for i in $(UsedLibNames); do \ - ln -sf "$(PROJ_libdir)/$$i" "$(PROJ_libocamldir)/$$i"; \ - done uninstall-cma:: $(Echo) "Uninstalling $(DestCMA)" -$(Verb) $(RM) -f $(DestCMA) - $(Verb) for i in $(UsedLibNames); do \ - $(RM) -f "$(PROJ_libocamldir)/$$i"; \ - done ##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===## From evan.cheng at apple.com Mon Dec 3 15:31:55 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 03 Dec 2007 21:31:55 -0000 Subject: [llvm-commits] [llvm] r44549 - /llvm/trunk/lib/CodeGen/VirtRegMap.cpp Message-ID: <200712032131.lB3LVtkm027931@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 3 15:31:55 2007 New Revision: 44549 URL: http://llvm.org/viewvc/llvm-project?rev=44549&view=rev Log: Bug fixes. Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44549&r1=44548&r2=44549&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Mon Dec 3 15:31:55 2007 @@ -276,7 +276,7 @@ SmallSet &ReMatDefs, BitVector &RegKills, std::vector &KillOps, - VirtRegMap &VRM, bool StoreMaybeDead); + VirtRegMap &VRM); void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM); }; } @@ -860,7 +860,7 @@ SmallSet &ReMatDefs, BitVector &RegKills, std::vector &KillOps, - VirtRegMap &VRM, bool StoreMaybeDead) { + VirtRegMap &VRM) { MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); DOUT << "Store:\t" << *next(MII); @@ -896,15 +896,14 @@ } } - MachineInstr *NewStore = next(MII); - LastStore = StoreMaybeDead ? NewStore : NULL; + LastStore = next(MII); // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. Spills.ModifyStackSlotOrReMat(StackSlot); Spills.ClobberPhysReg(PhysReg); - Spills.addAvailable(StackSlot, NewStore, PhysReg); + Spills.addAvailable(StackSlot, LastStore, PhysReg); ++NumStores; } @@ -987,8 +986,9 @@ int StackSlot = VRM.getStackSlot(VirtReg); MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; SpillRegToStackSlot(MBB, MII, i, Phys, StackSlot, RC, LastStore, - Spills, ReMatDefs, RegKills, KillOps, VRM, false); + Spills, ReMatDefs, RegKills, KillOps, VRM); } + NextMII = next(MII); } /// ReusedOperands - Keep track of operand reuse in case we need to undo @@ -1447,7 +1447,8 @@ if (!MO.isDead()) { MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, LastStore, - Spills, ReMatDefs, RegKills, KillOps, VRM, true); + Spills, ReMatDefs, RegKills, KillOps, VRM); + NextMII = next(MII); // Check to see if this is a noop copy. If so, eliminate the // instruction before considering the dest reg to be changed. From pawel.kunio at gmail.com Mon Dec 3 16:59:29 2007 From: pawel.kunio at gmail.com (pawel kunio) Date: Mon, 3 Dec 2007 23:59:29 +0100 Subject: [llvm-commits] Re: Re: PR889 final version Message-ID: > llvm/Instructions.h:2206: warning: 'class llvm::FPToUIInst' has virtual functions but non-virtual destructor > llvm/Instructions.h:2258: error: a class-key must be used when declaring a friend > llvm/Instructions.h:2258: error: friend declaration does not name a class or function Whoah, pretty strange I get neither of those. I'm using compiler from vs 2008 beta2 'orcas'. What compiler should I use to be more in sync with the one used by You for verification? btw, I had a deeper look into the Value class hierarchy and it seems that to remove all vtables there will be a need to flatten Instruction hierarchy with regard to the clone virtual method as well as Constant (destroyConstant,isNullValue,replaceUsesOfWithOnConstant methods) and GlobalValue (isDeclaration method). Those as well as print and dump methods will probably be blocking the Value destructor from being de-virtualized. Anyway, please find the patch attached with the Value destructor virtualized temporarily and with added 'class' clause to friend Value declarations. Best regards, Pawel -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm PR889-try4.patch Type: application/octet-stream Size: 58519 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071203/6881c081/attachment.obj From scottm at aero.org Mon Dec 3 17:09:50 2007 From: scottm at aero.org (Scott Michel) Date: Mon, 03 Dec 2007 23:09:50 -0000 Subject: [llvm-commits] [llvm] r44557 - /llvm/trunk/lib/Target/CellSPU/README.txt Message-ID: <200712032309.lB3N9oec032053@zion.cs.uiuc.edu> Author: pingbak Date: Mon Dec 3 17:09:49 2007 New Revision: 44557 URL: http://llvm.org/viewvc/llvm-project?rev=44557&view=rev Log: First commit to CellSPU. More to follow Modified: llvm/trunk/lib/Target/CellSPU/README.txt Modified: llvm/trunk/lib/Target/CellSPU/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/README.txt?rev=44557&r1=44556&r2=44557&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/README.txt (original) +++ llvm/trunk/lib/Target/CellSPU/README.txt Mon Dec 3 17:09:49 2007 @@ -1,10 +1,41 @@ //===- README.txt - Notes for improving CellSPU-specific code gen ---------===// +This code was contributed by a team from the Computer Systems Research +Department in The Aerospace Corporation: + +- Scott Michel (head bottle washer and much of the non-floating point + instructions) +- Mark Thomas (floating point instructions) +- Michael AuYeung (intrinsics) +- Chandler Carruth (LLVM expertise) + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR +OTHERWISE. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE FOR DAMAGES +OF ANY KIND OR NATURE WHETHER BASED IN CONTRACT, TORT, OR OTHERWISE ARISING +OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE INCLUDING, WITHOUT +LIMITATION, DAMAGES RESULTING FROM LOST OR CONTAMINATED DATA, LOST PROFITS OR +REVENUE, COMPUTER MALFUNCTION, OR FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, +OR PUNITIVE DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR +SUCH DAMAGES ARE FORESEEABLE. + +--------------------------------------------------------------------------- +--WARNING--: The CellSPU work is work-in-progress and "alpha" quality code. +--------------------------------------------------------------------------- + TODO: -* Check in the actual code. +* Finish branch instructions, branch prediction -===-------------------------------------------------------------------------=== + These instructions were started, but only insofar as to get llvm-gcc-4.2's + crtbegin.ll working (which doesn't.) -Note: The CellSPU work is work-in-progress and "alpha" quality code. No code -has been officially checked into the llvm repo, but this will happen Real Soon, -Real Soon Now. +* Double floating point support + + This was started. "What's missing?" to be filled in. + +* Intrinsics + + Lots of progress. "What's missing/incomplete?" to be filled in. + +===-------------------------------------------------------------------------=== From scottm at aero.org Mon Dec 3 17:12:49 2007 From: scottm at aero.org (Scott Michel) Date: Mon, 03 Dec 2007 23:12:49 -0000 Subject: [llvm-commits] [llvm] r44558 - /llvm/trunk/lib/Target/CellSPU/Makefile Message-ID: <200712032312.lB3NCncO032203@zion.cs.uiuc.edu> Author: pingbak Date: Mon Dec 3 17:12:49 2007 New Revision: 44558 URL: http://llvm.org/viewvc/llvm-project?rev=44558&view=rev Log: Makefile fragment for CellSPU. Added: llvm/trunk/lib/Target/CellSPU/Makefile Added: llvm/trunk/lib/Target/CellSPU/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/Makefile?rev=44558&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/Makefile (added) +++ llvm/trunk/lib/Target/CellSPU/Makefile Mon Dec 3 17:12:49 2007 @@ -0,0 +1,20 @@ +##===- lib/Target/CellSPU/Makefile -------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by a team from the Computer Systems Research +# Department at The Aerospace Corporation. +# +# See README.txt for details. +##===----------------------------------------------------------------------===## +LEVEL = ../../.. +LIBRARYNAME = LLVMCellSPU +TARGET = SPU + +BUILT_SOURCES = SPUGenInstrNames.inc SPUGenRegisterNames.inc \ + SPUGenAsmWriter.inc SPUGenCodeEmitter.inc \ + SPUGenRegisterInfo.h.inc SPUGenRegisterInfo.inc \ + SPUGenInstrInfo.inc SPUGenDAGISel.inc \ + SPUGenSubtarget.inc SPUGenCallingConv.inc + +include $(LEVEL)/Makefile.common From scottm at aero.org Mon Dec 3 17:14:43 2007 From: scottm at aero.org (Scott Michel) Date: Mon, 03 Dec 2007 23:14:43 -0000 Subject: [llvm-commits] [llvm] r44559 - in /llvm/trunk/lib/Target/CellSPU: SPU.h SPU.td Message-ID: <200712032314.lB3NEh0Q032277@zion.cs.uiuc.edu> Author: pingbak Date: Mon Dec 3 17:14:43 2007 New Revision: 44559 URL: http://llvm.org/viewvc/llvm-project?rev=44559&view=rev Log: More CellSPU files... more to follow. Added: llvm/trunk/lib/Target/CellSPU/SPU.h llvm/trunk/lib/Target/CellSPU/SPU.td Added: llvm/trunk/lib/Target/CellSPU/SPU.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPU.h?rev=44559&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPU.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPU.h Mon Dec 3 17:14:43 2007 @@ -0,0 +1,64 @@ +//===-- SPU.h - Top-level interface for Cell SPU Target ----------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in the LLVM +// Cell SPU back-end. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_IBMCELLSPU_H +#define LLVM_TARGET_IBMCELLSPU_H + +#include + +namespace llvm { + class SPUTargetMachine; + class FunctionPass; + + FunctionPass *createSPUISelDag(SPUTargetMachine &TM); + FunctionPass *createSPUAsmPrinterPass(std::ostream &o, SPUTargetMachine &tm); + + /* Utility functions/predicates/etc used all over the place: */ + //! Predicate test for a signed 10-bit value + /*! + \param Value The input value to be tested + + This predicate tests for a signed 10-bit value, returning the 10-bit value + as a short if true. + */ + inline bool isS10Constant(short Value) { + int SExtValue = ((int) Value << (32 - 10)) >> (32 - 10); + return ((Value > 0 && Value <= (1 << 9) - 1) + || (Value < 0 && (short) SExtValue == Value)); + } + + inline bool isS10Constant(int Value) { + return (Value >= -(1 << 9) && Value <= (1 << 9) - 1); + } + + inline bool isS10Constant(uint32_t Value) { + return (Value <= ((1 << 9) - 1)); + } + + inline bool isS10Constant(int64_t Value) { + return (Value >= -(1 << 9) && Value <= (1 << 9) - 1); + } + + inline bool isS10Constant(uint64_t Value) { + return (Value <= ((1 << 9) - 1)); + } +} + +// Defines symbolic names for the SPU instructions. +// +#include "SPUGenInstrNames.inc" + +#endif /* LLVM_TARGET_IBMCELLSPU_H */ Added: llvm/trunk/lib/Target/CellSPU/SPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPU.td?rev=44559&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPU.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPU.td Mon Dec 3 17:14:43 2007 @@ -0,0 +1,61 @@ +//===- SPU.td - Describe the STI Cell SPU Target Machine ----*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +//===----------------------------------------------------------------------===// +// +// This is the top level entry point for the STI Cell SPU target machine. +// +//===----------------------------------------------------------------------===// + +// Get the target-independent interfaces which we are implementing. +// +include "../Target.td" + +//===----------------------------------------------------------------------===// +// Register File Description +//===----------------------------------------------------------------------===// + +include "SPURegisterInfo.td" + +//===----------------------------------------------------------------------===// +// Instruction formats, instructions +//===----------------------------------------------------------------------===// + +include "SPUNodes.td" +include "SPUOperands.td" +include "SPUSchedule.td" +include "SPUInstrFormats.td" +include "SPUInstrInfo.td" + +//===----------------------------------------------------------------------===// +// Subtarget features: +//===----------------------------------------------------------------------===// + +def DefaultProc: SubtargetFeature<"", "ProcDirective", "SPU::DEFAULT_PROC", "">; +def LargeMemFeature: + SubtargetFeature<"large_mem","UseLargeMem", "true", + "Use large (>256) LSA memory addressing [default = false]">; + +def SPURev0 : Processor<"v0", SPUItineraries, [DefaultProc]>; + +//===----------------------------------------------------------------------===// +// Calling convention: +//===----------------------------------------------------------------------===// + +include "SPUCallingConv.td" + +// Target: + +def SPUInstrInfo : InstrInfo { + let isLittleEndianEncoding = 1; +} + +def SPU : Target { + let InstructionSet = SPUInstrInfo; +} From sabre at nondot.org Mon Dec 3 17:57:32 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 03 Dec 2007 23:57:32 -0000 Subject: [llvm-commits] [test-suite] r44562 - in /test-suite/trunk: TEST.beta-compare.Makefile TEST.beta-compare.report Message-ID: <200712032357.lB3NvWuS001498@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 3 17:57:31 2007 New Revision: 44562 URL: http://llvm.org/viewvc/llvm-project?rev=44562&view=rev Log: Add a new beta-compare report, for comparing static measurements of llc output. At this point, it compares code size. For example, running this on ppc on olden currently prints: $ make TEST=beta-compare report Name: | #Insts Beta LLC/BETA | bh/bh | 1968 1875 1.050 | em3d/em3d | 651 631 1.032 | mst/mst | 444 416 1.067 | power/power | 1012 994 1.018 | tsp/tsp | 860 777 1.107 | bisort/bisort | 764 712 1.073 | health/health | 855 806 1.061 | perimeter/perimeter | 1308 1129 1.159 | treeadd/treeadd | 247 233 1.060 | voronoi/voronoi | 2539 2420 1.049 | Looks like llc-beta is good right now :) Added: test-suite/trunk/TEST.beta-compare.Makefile test-suite/trunk/TEST.beta-compare.report Added: test-suite/trunk/TEST.beta-compare.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.beta-compare.Makefile?rev=44562&view=auto ============================================================================== --- test-suite/trunk/TEST.beta-compare.Makefile (added) +++ test-suite/trunk/TEST.beta-compare.Makefile Mon Dec 3 17:57:31 2007 @@ -0,0 +1,38 @@ +##===- TEST.beta-compare.Makefile -----------------------------------*- Makefile -*-===## +# +# This test runs llc and llc-beta and generates numbers to compare their static +# values produced by -stats. +# +##===----------------------------------------------------------------------===## + +LLC_OPTS = $(LLCFLAGS) -f -o=/dev/null -stats -time-passes +CURDIR := $(shell cd .; pwd) +PROGDIR := $(PROJ_SRC_ROOT) +RELDIR := $(subst $(PROGDIR),,$(CURDIR)) + +$(PROGRAMS_TO_TEST:%=Output/%.$(TEST).llc-info.txt): \ +Output/%.$(TEST).llc-info.txt: Output/%.llvm.bc $(LLC) + - $(LLC) $(LLC_OPTS) $< -info-output-file=$@ + +$(PROGRAMS_TO_TEST:%=Output/%.$(TEST).llc-beta-info.txt): \ +Output/%.$(TEST).llc-beta-info.txt: Output/%.llvm.bc $(LLC) + - $(LLC) $(LLC_OPTS) $(LLCBETAOPTION) $< -info-output-file=$@ + + +$(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ +Output/%.$(TEST).report.txt: Output/%.$(TEST).llc-info.txt Output/%.$(TEST).llc-beta-info.txt + - at printf "LLC: " > $@ + -grep 'Number of machine instrs printed' Output/$*.$(TEST).llc-info.txt >> $@ + - at printf "LLCBETA: " >> $@ + -grep 'Number of machine instrs printed' Output/$*.$(TEST).llc-beta-info.txt >> $@ + +$(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ +test.$(TEST).%: Output/%.$(TEST).report.txt + @echo "---------------------------------------------------------------" + @echo ">>> ========= '$(RELDIR)/$*' Program" + @echo "---------------------------------------------------------------" + @cat $< + +# Define REPORT_DEPENDENCIES so that the report is regenerated if llc changes +# +REPORT_DEPENDENCIES := $(LLC) Added: test-suite/trunk/TEST.beta-compare.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.beta-compare.report?rev=44562&view=auto ============================================================================== --- test-suite/trunk/TEST.beta-compare.report (added) +++ test-suite/trunk/TEST.beta-compare.report Mon Dec 3 17:57:31 2007 @@ -0,0 +1,32 @@ +##=== TEST.beta-compare.report - Compare llc vs llcbeta -*- perl -*-===## +# +# This file defines a report to be generated for the beta-compare test. +# +##===----------------------------------------------------------------------===## + +# Sort by name +$SortCol = 1; +$TrimRepeatedPrefix = 1; + +sub SizeRatio { + my ($Cols, $Col) = @_; + my $LLC = $Cols->[$Col-2]; + my $BETA = $Cols->[$Col-1]; + return "n/a" if ($LLC eq "*" or $BETA eq "*"); + return sprintf("%2.3f", $LLC/$BETA); +} + + +# These are the columns for the report. The first entry is the header for the +# column, the second is the regex to use to match the value. Empty list create +# seperators, and closures may be put in for custom processing. +( +# Name + ["Name:" , '\'([^\']+)\' Program'], + [], +# Code Size + ["#Insts", 'LLC: ([0-9]+).*Number of machine instrs printed'], + ["Beta", 'LLCBETA: ([0-9]+).*Number of machine instrs printed'], + ["LLC/BETA" , \&SizeRatio], + [] + ); From evan.cheng at apple.com Mon Dec 3 18:32:23 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 04 Dec 2007 00:32:23 -0000 Subject: [llvm-commits] [llvm] r44565 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200712040032.lB40WNuC002793@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 3 18:32:23 2007 New Revision: 44565 URL: http://llvm.org/viewvc/llvm-project?rev=44565&view=rev Log: Discard split intervals made empty due to folding. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44565&r1=44564&r2=44565&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Dec 3 18:32:23 2007 @@ -1234,6 +1234,7 @@ for (unsigned i = 0, e = spills.size(); i != e; ++i) { int index = spills[i].index; unsigned VReg = spills[i].vreg; + LiveInterval &nI = getOrCreateInterval(VReg); bool isReMat = vrm.isReMaterialized(VReg); MachineInstr *MI = getInstructionFromIndex(index); bool CanFold = false; @@ -1269,6 +1270,7 @@ if (FoundUse > 0) // Also folded uses, do not issue a load. eraseRestoreInfo(Id, index, VReg, RestoreMBBs, RestoreIdxes); + nI.removeRange(getDefIndex(index), getStoreIndex(index)); } } @@ -1288,6 +1290,7 @@ if (index == -1) continue; unsigned VReg = restores[i].vreg; + LiveInterval &nI = getOrCreateInterval(VReg); MachineInstr *MI = getInstructionFromIndex(index); bool CanFold = false; Ops.clear(); @@ -1326,15 +1329,23 @@ } // If folding is not possible / failed, then tell the spiller to issue a // load / rematerialization for us. - if (!Folded) + if (Folded) + nI.removeRange(getLoadIndex(index), getUseIndex(index)+1); + else vrm.addRestorePoint(VReg, MI); } Id = RestoreMBBs.find_next(Id); } - // Finalize spill weights. - for (unsigned i = 0, e = NewLIs.size(); i != e; ++i) - NewLIs[i]->weight /= NewLIs[i]->getSize(); + // Finalize spill weights and filter out dead intervals. + std::vector RetNewLIs; + for (unsigned i = 0, e = NewLIs.size(); i != e; ++i) { + LiveInterval *LI = NewLIs[i]; + if (!LI->empty()) { + LI->weight /= LI->getSize(); + RetNewLIs.push_back(LI); + } + } - return NewLIs; + return RetNewLIs; } From clattner at apple.com Mon Dec 3 23:50:45 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 3 Dec 2007 21:50:45 -0800 Subject: [llvm-commits] [llvm] r44559 - in /llvm/trunk/lib/Target/CellSPU: SPU.h SPU.td In-Reply-To: <200712032314.lB3NEh0Q032277@zion.cs.uiuc.edu> References: <200712032314.lB3NEh0Q032277@zion.cs.uiuc.edu> Message-ID: On Dec 3, 2007, at 3:14 PM, Scott Michel wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=44559&view=rev > Log: > More CellSPU files... more to follow. Very nice Scott! > +//===-- SPU.h - Top-level interface for Cell SPU Target ---------- > *- C++ -*-==// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file was developed by a team from the Computer Systems > Research > +// Department at The Aerospace Corporation. > +// > +// See README.txt for details. Please use the standard LLVM header blurb. Specifically, please use: // This file was developed by XXX and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. where you can replace XXX with whatever you want, for example: // This file was developed by the Computer Systems Research Department at The // Aerospace Corporation and is distributed under the University of Illinois Open // Source License. See LICENSE.TXT for details. or something shorter :) the code looks great so far! -Chris From sabre at nondot.org Tue Dec 4 01:29:52 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 04 Dec 2007 07:29:52 -0000 Subject: [llvm-commits] [llvm] r44569 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200712040729.lB47Tq2l018626@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 4 01:29:51 2007 New Revision: 44569 URL: http://llvm.org/viewvc/llvm-project?rev=44569&view=rev Log: start providing framework for scalarizing vectors. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44569&r1=44568&r2=44569&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Tue Dec 4 01:29:51 2007 @@ -85,14 +85,18 @@ return DAG.getConstant(Val, TLI.getPointerTy()); } - /// PromotedNodes - For nodes that are below legal width, and that have more - /// than one use, this map indicates what promoted value to use. + /// PromotedNodes - For nodes that are below legal width, this map indicates + /// what promoted value to use. DenseMap PromotedNodes; /// ExpandedNodes - For nodes that need to be expanded this map indicates /// which operands are the expanded version of the input. DenseMap > ExpandedNodes; + /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the + /// scalar value of type 'ty' to use. + DenseMap ScalarizedNodes; + /// ReplacedNodes - For nodes that have been replaced with another, /// indicates the replacement node to use. DenseMap ReplacedNodes; @@ -139,6 +143,14 @@ void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi); + SDOperand GetScalarizedOp(SDOperand Op) { + SDOperand &ScalarOp = ScalarizedNodes[Op]; + RemapNode(ScalarOp); + assert(ScalarOp.Val && "Operand wasn't scalarized?"); + return ScalarOp; + } + void SetScalarizedOp(SDOperand Op, SDOperand Result); + // Common routines. SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); SDOperand HandleMemIntrinsic(SDNode *N); @@ -219,6 +231,11 @@ void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, ISD::CondCode &CCCode); + + // Operand Vector Scalarization <1 x ty> -> ty. + bool ScalarizeOperand(SDNode *N, unsigned OpNo); + SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); + }; } // end anonymous namespace @@ -279,12 +296,26 @@ unsigned NumOperands = N->getNumOperands(); bool NeedsRevisit = false; for (i = 0; i != NumOperands; ++i) { - LegalizeAction Action = getTypeAction(N->getOperand(i).getValueType()); + MVT::ValueType OpVT = N->getOperand(i).getValueType(); + LegalizeAction Action = getTypeAction(OpVT); if (Action == Promote) { NeedsRevisit = PromoteOperand(N, i); break; } else if (Action == Expand) { - NeedsRevisit = ExpandOperand(N, i); + // Expand can mean 1) split integer in half 2) scalarize single-element + // vector 3) split vector in half. + if (!MVT::isVector(OpVT)) { + NeedsRevisit = ExpandOperand(N, i); + } else { + unsigned NumElts = MVT::getVectorNumElements(OpVT); + if (NumElts == 1) { + // Scalarize the single-element vector. + NeedsRevisit = ScalarizeOperand(N, i); + } else { + // Split the vector in half. + assert(0 && "Vector splitting not implemented"); + } + } break; } else { assert(Action == Legal && "Unknown action!"); @@ -487,6 +518,16 @@ OpEntry = Result; } +void DAGTypeLegalizer::SetScalarizedOp(SDOperand Op, SDOperand Result) { + if (Result.Val->getNodeId() == NewNode) + MarkNewNodes(Result.Val); + + SDOperand &OpEntry = ScalarizedNodes[Op]; + assert(OpEntry.Val == 0 && "Node is already scalarized!"); + OpEntry = Result; +} + + void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { std::pair &Entry = ExpandedNodes[Op]; @@ -2197,6 +2238,67 @@ } } +//===----------------------------------------------------------------------===// +// Operand Vector Scalarization <1 x ty> -> ty. +//===----------------------------------------------------------------------===// + +bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { + DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG); + cerr << "\n"); + SDOperand Res(0, 0); + + // FIXME: Should we support custom lowering for scalarization? +#if 0 + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, 0), DAG); +#endif + + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "ScalarizeOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to scalarize this operator's operand!"); + abort(); + + case ISD::EXTRACT_VECTOR_ELT: + Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N, OpNo); + break; + } + } + + // If the result is null, the sub-method took care of registering results etc. + if (!Res.Val) return false; + + // If the result is N, the sub-method updated N in place. Check to see if any + // operands are new, and if so, mark them. + if (Res.Val == N) { + // Mark N as new and remark N and its operands. This allows us to correctly + // revisit N if it needs another step of promotion and allows us to visit + // any new operands to N. + N->setNodeId(NewNode); + MarkNewNodes(N); + return true; + } + + assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + "Invalid operand expansion"); + + ReplaceValueWith(SDOperand(N, 0), Res); + return false; +} + +/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be +/// scalarized, it must be <1 x ty>, just return the operand, ignoring the +/// index. +SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, + unsigned OpNo) { + return GetScalarizedOp(N->getOperand(0)); +} + //===----------------------------------------------------------------------===// // Entry Point From sabre at nondot.org Tue Dec 4 01:48:46 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 04 Dec 2007 07:48:46 -0000 Subject: [llvm-commits] [llvm] r44570 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200712040748.lB47mk15019283@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 4 01:48:46 2007 New Revision: 44570 URL: http://llvm.org/viewvc/llvm-project?rev=44570&view=rev Log: Implement framework for scalarizing node results. This is sufficient to codegen this: define float @test_extract_elt(<1 x float> * %P) { %p = load <1 x float>* %P %R = extractelement <1 x float> %p, i32 0 ret float %R } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44570&r1=44569&r2=44570&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Tue Dec 4 01:48:46 2007 @@ -202,6 +202,11 @@ SDOperand &Lo, SDOperand &Hi); bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi); + // Result Vector Scalarization: <1 x ty> -> ty. + void ScalarizeResult(SDNode *N, unsigned OpNo); + SDOperand ScalarizeRes_UNDEF(SDNode *N); + SDOperand ScalarizeRes_LOAD(LoadSDNode *N); + // Operand Promotion. bool PromoteOperand(SDNode *N, unsigned OperandNo); SDOperand PromoteOperand_ANY_EXTEND(SDNode *N); @@ -232,7 +237,7 @@ void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, ISD::CondCode &CCCode); - // Operand Vector Scalarization <1 x ty> -> ty. + // Operand Vector Scalarization: <1 x ty> -> ty. bool ScalarizeOperand(SDNode *N, unsigned OpNo); SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); @@ -278,12 +283,20 @@ unsigned i = 0; unsigned NumResults = N->getNumValues(); do { - LegalizeAction Action = getTypeAction(N->getValueType(i)); + MVT::ValueType ResultVT = N->getValueType(i); + LegalizeAction Action = getTypeAction(ResultVT); if (Action == Promote) { PromoteResult(N, i); goto NodeDone; } else if (Action == Expand) { - ExpandResult(N, i); + // Expand can mean 1) split integer in half 2) scalarize single-element + // vector 3) split vector in half. + if (!MVT::isVector(ResultVT)) + ExpandResult(N, i); + else if (MVT::getVectorNumElements(ResultVT) == 1) + ScalarizeResult(N, i); // Scalarize the single-element vector. + else // Split the vector in half. + assert(0 && "Vector splitting not implemented"); goto NodeDone; } else { assert(Action == Legal && "Unknown action!"); @@ -306,15 +319,12 @@ // vector 3) split vector in half. if (!MVT::isVector(OpVT)) { NeedsRevisit = ExpandOperand(N, i); + } else if (MVT::getVectorNumElements(OpVT) == 1) { + // Scalarize the single-element vector. + NeedsRevisit = ScalarizeOperand(N, i); } else { - unsigned NumElts = MVT::getVectorNumElements(OpVT); - if (NumElts == 1) { - // Scalarize the single-element vector. - NeedsRevisit = ScalarizeOperand(N, i); - } else { - // Split the vector in half. - assert(0 && "Vector splitting not implemented"); - } + // Split the vector in half. + assert(0 && "Vector splitting not implemented"); } break; } else { @@ -1584,6 +1594,65 @@ return true; } +//===----------------------------------------------------------------------===// +// Result Vector Scalarization: <1 x ty> -> ty. +//===----------------------------------------------------------------------===// + + +void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { + DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); + cerr << "\n"); + SDOperand R = SDOperand(); + + // FIXME: Custom lowering for scalarization? +#if 0 + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } +#endif + + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "ScalarizeResult #" << ResNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to expand the result of this operator!"); + abort(); + + case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; + case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; + } + + // If R is null, the sub-method took care of registering the resul. + if (R.Val) + SetScalarizedOp(SDOperand(N, ResNo), R); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) { + return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(N->getValueType(0))); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { + SDOperand Result = DAG.getLoad(MVT::getVectorElementType(N->getValueType(0)), + N->getChain(), N->getBasePtr(), + N->getSrcValue(), N->getSrcValueOffset(), + N->isVolatile(), N->getAlignment()); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Result.getValue(1)); + return Result; +} + //===----------------------------------------------------------------------===// // Operand Promotion From evan.cheng at apple.com Tue Dec 4 13:19:46 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 04 Dec 2007 19:19:46 -0000 Subject: [llvm-commits] [llvm] r44575 - /llvm/trunk/lib/CodeGen/VirtRegMap.cpp Message-ID: <200712041919.lB4JJlH5023710@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 4 13:19:45 2007 New Revision: 44575 URL: http://llvm.org/viewvc/llvm-project?rev=44575&view=rev Log: Spiller unfold optimization bug: do not clobber a reusable stack slot value unless it can be modified. Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44575&r1=44574&r2=44575&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Tue Dec 4 13:19:45 2007 @@ -271,7 +271,7 @@ MachineBasicBlock::iterator &MII, int Idx, unsigned PhysReg, int StackSlot, const TargetRegisterClass *RC, - MachineInstr *&LastStore, + bool isAvailable, MachineInstr *&LastStore, AvailableSpills &Spills, SmallSet &ReMatDefs, BitVector &RegKills, @@ -357,7 +357,7 @@ "Value not available!"); return SpillSlotsOrReMatsAvailable.find(SlotOrReMat)->second & 1; } - + /// disallowClobberPhysReg - Unset the CanClobber bit of the specified /// stackslot register. The register is still available but is no longer /// allowed to be modifed. @@ -855,7 +855,7 @@ MachineBasicBlock::iterator &MII, int Idx, unsigned PhysReg, int StackSlot, const TargetRegisterClass *RC, - MachineInstr *&LastStore, + bool isAvailable, MachineInstr *&LastStore, AvailableSpills &Spills, SmallSet &ReMatDefs, BitVector &RegKills, @@ -903,7 +903,7 @@ // in PhysReg. Spills.ModifyStackSlotOrReMat(StackSlot); Spills.ClobberPhysReg(PhysReg); - Spills.addAvailable(StackSlot, LastStore, PhysReg); + Spills.addAvailable(StackSlot, LastStore, PhysReg, isAvailable); ++NumStores; } @@ -984,9 +984,9 @@ const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); - MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; - SpillRegToStackSlot(MBB, MII, i, Phys, StackSlot, RC, LastStore, - Spills, ReMatDefs, RegKills, KillOps, VRM); + MRI->storeRegToStackSlot(MBB, next(MII), Phys, StackSlot, RC); + DOUT << "Store:\t" << *next(MII); + VRM.virtFolded(VirtReg, next(MII), VirtRegMap::isMod); } NextMII = next(MII); } @@ -1303,7 +1303,12 @@ if (MR & VirtRegMap::isModRef) { unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS); SmallVector NewMIs; + // We can reuse this physreg as long as we are allowed to clobber + // the value and there isn't an earlier def that has already clobbered the + // physreg. if (PhysReg && + Spills.canClobberPhysReg(SS) && + !ReusedOperands.isClobbered(PhysReg) && DeadStore->findRegisterUseOperandIdx(PhysReg, true) != -1 && MRI->unfoldMemoryOperand(MF, &MI, PhysReg, false, true, NewMIs)) { MBB.insert(MII, NewMIs[0]); @@ -1446,8 +1451,8 @@ if (!MO.isDead()) { MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; - SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, LastStore, - Spills, ReMatDefs, RegKills, KillOps, VRM); + SpillRegToStackSlot(MBB, MII, -1, PhysReg, StackSlot, RC, true, + LastStore, Spills, ReMatDefs, RegKills, KillOps, VRM); NextMII = next(MII); // Check to see if this is a noop copy. If so, eliminate the @@ -1467,9 +1472,10 @@ } } ProcessNextInst: - if (!Erased && !BackTracked) + if (!Erased && !BackTracked) { for (MachineBasicBlock::iterator II = MI; II != NextMII; ++II) UpdateKills(*II, RegKills, KillOps); + } MII = NextMII; } } From evan.cheng at apple.com Tue Dec 4 14:11:22 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 04 Dec 2007 20:11:22 -0000 Subject: [llvm-commits] [test-suite] r44579 - /test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile Message-ID: <200712042011.lB4KBM8d025847@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 4 14:11:21 2007 New Revision: 44579 URL: http://llvm.org/viewvc/llvm-project?rev=44579&view=rev Log: Fix makefile so it doesn't report false positive. Modified: test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile Modified: test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile?rev=44579&r1=44578&r2=44579&view=diff ============================================================================== --- test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile (original) +++ test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile Tue Dec 4 14:11:21 2007 @@ -12,7 +12,7 @@ RUN_OPTIONS = `head -n 1 $(REF_IN_DIR)control` ifeq ($(RUN_TYPE),test) - STDOUT_FILENAME := input.compressed.out + STDOUT_FILENAME := input.program.out else STDOUT_FILENAME := input.combined.out endif From clattner at apple.com Tue Dec 4 14:59:23 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 4 Dec 2007 12:59:23 -0800 Subject: [llvm-commits] [test-suite] r44579 - /test-suite/trunk/External/SPEC/CINT2006/401.bzip2/Makefile In-Reply-To: <200712042011.lB4KBM8d025847@zion.cs.uiuc.edu> References: <200712042011.lB4KBM8d025847@zion.cs.uiuc.edu> Message-ID: <385AF175-B76A-44E8-9995-4C828CF73F19@apple.com> On Dec 4, 2007, at 12:11 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Dec 4 14:11:21 2007 > New Revision: 44579 > > URL: http://llvm.org/viewvc/llvm-project?rev=44579&view=rev > Log: > Fix makefile so it doesn't report false positive. woot! It's the simple things that can make people happy huh? :) -Chris From scottm at aero.org Tue Dec 4 16:23:37 2007 From: scottm at aero.org (Scott Michel) Date: Tue, 04 Dec 2007 22:23:37 -0000 Subject: [llvm-commits] [llvm] r44582 - in /llvm/trunk/lib/Target/CellSPU: SPUAsmPrinter.cpp SPUCallingConv.td SPUFrameInfo.cpp SPUFrameInfo.h SPUHazardRecognizers.cpp SPUHazardRecognizers.h SPUISelDAGToDAG.cpp SPUISelLowering.cpp SPUISelLowering.h SPUInstrBuilder.h SPUInstrFormats.td Message-ID: <200712042223.lB4MNceR031778@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 16:23:35 2007 New Revision: 44582 URL: http://llvm.org/viewvc/llvm-project?rev=44582&view=rev Log: More of the Cell SPU code drop from "Team Aerospace". Added: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td Added: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp Tue Dec 4 16:23:35 2007 @@ -0,0 +1,654 @@ +//===-- SPUAsmPrinter.cpp - Print machine instrs to Cell SPU assembly -------=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to Cell SPU assembly language. This printer +// is the output mechanism used by `llc'. +// +// Documentation at http://developer.apple.com/documentation/DeveloperTools/ +// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asmprinter" +#include "SPU.h" +#include "SPUTargetMachine.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" +#include +using namespace llvm; + +namespace { + STATISTIC(EmittedInsts, "Number of machine instrs printed"); + + const std::string bss_section(".bss"); + + struct VISIBILITY_HIDDEN SPUAsmPrinter : public AsmPrinter { + std::set FnStubs, GVStubs; + + SPUAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T) : + AsmPrinter(O, TM, T) + { + } + + virtual const char *getPassName() const { + return "STI CBEA SPU Assembly Printer"; + } + + SPUTargetMachine &getTM() { + return static_cast(TM); + } + + /// printInstruction - This method is automatically generated by tablegen + /// from the instruction set description. This method returns true if the + /// machine instruction was sufficiently described to print it, otherwise it + /// returns false. + bool printInstruction(const MachineInstr *MI); + + void printMachineInstruction(const MachineInstr *MI); + void printOp(const MachineOperand &MO); + + /// printRegister - Print register according to target requirements. + /// + void printRegister(const MachineOperand &MO, bool R0AsZero) { + unsigned RegNo = MO.getReg(); + assert(MRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); + O << TM.getRegisterInfo()->get(RegNo).Name; + } + + void printOperand(const MachineInstr *MI, unsigned OpNo) { + const MachineOperand &MO = MI->getOperand(OpNo); + if (MO.isRegister()) { + assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); + O << TM.getRegisterInfo()->get(MO.getReg()).Name; + } else if (MO.isImmediate()) { + O << MO.getImmedValue(); + } else { + printOp(MO); + } + } + + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode); + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode); + + + void + printS7ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + int value = MI->getOperand(OpNo).getImmedValue(); + value = (value << (32 - 7)) >> (32 - 7); + + assert((value >= -(1 << 8) && value <= (1 << 7) - 1) + && "Invalid s7 argument"); + O << value; + } + + void + printU7ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + unsigned int value = MI->getOperand(OpNo).getImmedValue(); + assert(value < (1 << 8) && "Invalid u7 argument"); + O << value; + } + + void + printMemRegImmS7(const MachineInstr *MI, unsigned OpNo) + { + char value = MI->getOperand(OpNo).getImmedValue(); + O << (int) value; + O << "("; + printOperand(MI, OpNo+1); + O << ")"; + } + + void + printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + O << (short) MI->getOperand(OpNo).getImmedValue(); + } + + void + printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + O << (unsigned short)MI->getOperand(OpNo).getImmedValue(); + } + + void + printU32ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + O << (unsigned)MI->getOperand(OpNo).getImmedValue(); + } + + void + printMemRegReg(const MachineInstr *MI, unsigned OpNo) { + // When used as the base register, r0 reads constant zero rather than + // the value contained in the register. For this reason, the darwin + // assembler requires that we print r0 as 0 (no r) when used as the base. + const MachineOperand &MO = MI->getOperand(OpNo); + O << TM.getRegisterInfo()->get(MO.getReg()).Name; + O << ", "; + printOperand(MI, OpNo+1); + } + + void + printU18ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + unsigned int value = MI->getOperand(OpNo).getImmedValue(); + assert(value <= (1 << 19) - 1 && "Invalid u18 argument"); + O << value; + } + + void + printS10ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + short value = (short) (((int) MI->getOperand(OpNo).getImmedValue() << 16) + >> 16); + assert((value >= -(1 << 9) && value <= (1 << 9) - 1) + && "Invalid s10 argument"); + O << value; + } + + void + printU10ImmOperand(const MachineInstr *MI, unsigned OpNo) + { + short value = (short) (((int) MI->getOperand(OpNo).getImmedValue() << 16) + >> 16); + assert((value <= (1 << 10) - 1) && "Invalid u10 argument"); + O << value; + } + + void + printMemRegImmS10(const MachineInstr *MI, unsigned OpNo) + { + const MachineOperand &MO = MI->getOperand(OpNo); + assert(MO.isImmediate() + && "printMemRegImmS10 first operand is not immedate"); + printS10ImmOperand(MI, OpNo); + O << "("; + printOperand(MI, OpNo+1); + O << ")"; + } + + void + printAddr256K(const MachineInstr *MI, unsigned OpNo) + { + /* Note: operand 1 is an offset or symbol name. Operand 2 is + ignored. */ + if (MI->getOperand(OpNo).isImmediate()) { + printS16ImmOperand(MI, OpNo); + } else { + printOp(MI->getOperand(OpNo)); + } + } + + void printCallOperand(const MachineInstr *MI, unsigned OpNo) { + printOp(MI->getOperand(OpNo)); + } + + void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo) { + printOp(MI->getOperand(OpNo)); + O << "-."; + } + + void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { + if (MI->getOperand(OpNo).isImmediate()) { + printS16ImmOperand(MI, OpNo); + } else { + printOp(MI->getOperand(OpNo)); + O << "@h"; + } + } + + void printSymbolLo(const MachineInstr *MI, unsigned OpNo) { + if (MI->getOperand(OpNo).isImmediate()) { + printS16ImmOperand(MI, OpNo); + } else { + printOp(MI->getOperand(OpNo)); + O << "@l"; + } + } + + /// Print local store address + void printSymbolLSA(const MachineInstr *MI, unsigned OpNo) { + printOp(MI->getOperand(OpNo)); + } + + void printROTHNeg7Imm(const MachineInstr *MI, unsigned OpNo) { + if (MI->getOperand(OpNo).isImmediate()) { + int value = (int) MI->getOperand(OpNo).getImmedValue(); + assert((value >= 0 && value < 16) + && "Invalid negated immediate rotate 7-bit argument"); + O << -value; + } else { + assert(0 && "Invalid/non-immediate rotate amount in printRotateNeg7Imm"); + } + } + + void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo) { + if (MI->getOperand(OpNo).isImmediate()) { + int value = (int) MI->getOperand(OpNo).getImmedValue(); + assert((value >= 0 && value < 32) + && "Invalid negated immediate rotate 7-bit argument"); + O << -value; + } else { + assert(0 && "Invalid/non-immediate rotate amount in printRotateNeg7Imm"); + } + } + + virtual bool runOnMachineFunction(MachineFunction &F) = 0; + virtual bool doFinalization(Module &M) = 0; + }; + + /// LinuxAsmPrinter - SPU assembly printer, customized for Linux + struct VISIBILITY_HIDDEN LinuxAsmPrinter : public SPUAsmPrinter { + + DwarfWriter DW; + + LinuxAsmPrinter(std::ostream &O, SPUTargetMachine &TM, + const TargetAsmInfo *T) : + SPUAsmPrinter(O, TM, T), + DW(O, this, T) + { } + + virtual const char *getPassName() const { + return "STI CBEA SPU Assembly Printer"; + } + + bool runOnMachineFunction(MachineFunction &F); + bool doInitialization(Module &M); + bool doFinalization(Module &M); + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + SPUAsmPrinter::getAnalysisUsage(AU); + } + + /// getSectionForFunction - Return the section that we should emit the + /// specified function body into. + virtual std::string getSectionForFunction(const Function &F) const; + }; +} // end of anonymous namespace + +// Include the auto-generated portion of the assembly writer +#include "SPUGenAsmWriter.inc" + +void SPUAsmPrinter::printOp(const MachineOperand &MO) { + switch (MO.getType()) { + case MachineOperand::MO_Immediate: + cerr << "printOp() does not handle immediate values\n"; + abort(); + return; + + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMachineBasicBlock()); + return; + case MachineOperand::MO_JumpTableIndex: + O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + << '_' << MO.getJumpTableIndex(); + // FIXME: PIC relocation model + return; + case MachineOperand::MO_ConstantPoolIndex: + O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() + << '_' << MO.getConstantPoolIndex(); + return; + case MachineOperand::MO_ExternalSymbol: + // Computing the address of an external symbol, not calling it. + if (TM.getRelocationModel() != Reloc::Static) { + std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); + GVStubs.insert(Name); + O << "L" << Name << "$non_lazy_ptr"; + return; + } + O << TAI->getGlobalPrefix() << MO.getSymbolName(); + return; + case MachineOperand::MO_GlobalAddress: { + // Computing the address of a global symbol, not calling it. + GlobalValue *GV = MO.getGlobal(); + std::string Name = Mang->getValueName(GV); + + // External or weakly linked global variables need non-lazily-resolved + // stubs + if (TM.getRelocationModel() != Reloc::Static) { + if (((GV->isDeclaration() || GV->hasWeakLinkage() || + GV->hasLinkOnceLinkage()))) { + GVStubs.insert(Name); + O << "L" << Name << "$non_lazy_ptr"; + return; + } + } + O << Name; + + if (GV->hasExternalWeakLinkage()) + ExtWeakSymbols.insert(GV); + return; + } + + default: + O << ""; + return; + } +} + +/// PrintAsmOperand - Print out an operand for an inline asm expression. +/// +bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) { + if (ExtraCode[1] != 0) return true; // Unknown modifier. + + switch (ExtraCode[0]) { + default: return true; // Unknown modifier. + case 'L': // Write second word of DImode reference. + // Verify that this operand has two consecutive registers. + if (!MI->getOperand(OpNo).isRegister() || + OpNo+1 == MI->getNumOperands() || + !MI->getOperand(OpNo+1).isRegister()) + return true; + ++OpNo; // Return the high-part. + break; + } + } + + printOperand(MI, OpNo); + return false; +} + +bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + printMemRegReg(MI, OpNo); + return false; +} + +/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax +/// to the current output stream. +/// +void SPUAsmPrinter::printMachineInstruction(const MachineInstr *MI) { + ++EmittedInsts; + printInstruction(MI); +} + + + +std::string LinuxAsmPrinter::getSectionForFunction(const Function &F) const { + switch (F.getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::ExternalLinkage: + case Function::InternalLinkage: return TAI->getTextSection(); + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + return ""; // Print nothing for the time being... + } +} + +/// runOnMachineFunction - This uses the printMachineInstruction() +/// method to print assembly for each instruction. +/// +bool +LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) +{ + DW.SetModuleInfo(&getAnalysis()); + + SetupMachineFunction(MF); + O << "\n\n"; + + // Print out constants referenced by the function + EmitConstantPool(MF.getConstantPool()); + + // Print out labels for the function. + const Function *F = MF.getFunction(); + + SwitchToTextSection(getSectionForFunction(*F).c_str(), F); + EmitAlignment(3, F); + + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: // Symbols default to internal. + break; + case Function::ExternalLinkage: + O << "\t.global\t" << CurrentFnName << "\n" + << "\t.type\t" << CurrentFnName << ", @function\n"; + break; + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + O << "\t.global\t" << CurrentFnName << "\n"; + O << "\t.weak_definition\t" << CurrentFnName << "\n"; + break; + } + O << CurrentFnName << ":\n"; + + // Emit pre-function debug information. + DW.BeginFunction(&MF); + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + if (I != MF.begin()) { + printBasicBlockLabel(I, true); + O << '\n'; + } + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + O << "\t"; + printMachineInstruction(II); + } + } + + O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n"; + + // Print out jump tables referenced by the function. + EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + + // Emit post-function debug information. + DW.EndFunction(); + + // We didn't modify anything. + return false; +} + + +bool LinuxAsmPrinter::doInitialization(Module &M) { + bool Result = AsmPrinter::doInitialization(M); + SwitchToTextSection(TAI->getTextSection()); + // Emit initial debug information. + DW.BeginModule(&M); + return Result; +} + +bool LinuxAsmPrinter::doFinalization(Module &M) { + 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) { + 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 (EmitSpecialLLVMGlobal(I)) + continue; + + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD->getTypeStoreSize(C->getType()); + unsigned Align = TD->getPreferredAlignmentLog(I); + + if (C->isNullValue() && /* FIXME: Verify correct */ + (I->hasInternalLinkage() || I->hasWeakLinkage() || + I->hasLinkOnceLinkage() || + (I->hasExternalLinkage() && !I->hasSection()))) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + if (I->hasExternalLinkage()) { + // External linkage globals -> .bss section + // FIXME: Want to set the global variable's section so that + // SwitchToDataSection emits the ".section" directive + SwitchToDataSection("\t.section\t.bss", I); + O << "\t.global\t" << name << '\n'; + O << "\t.align\t" << Align << '\n'; + O << "\t.type\t" << name << ", @object\n"; + O << "\t.size\t" << name << ", " << Size << '\n'; + O << name << ":\n"; + O << "\t.zero\t" << Size; + } else if (I->hasInternalLinkage()) { + SwitchToDataSection("\t.data", I); + O << TAI->getLCOMMDirective() << name << "," << Size << "," << Align; + } else { + SwitchToDataSection("\t.data", I); + O << ".comm " << name << "," << Size; + } + O << "\t\t# '" << I->getName() << "'\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: + O << "\t.global " << name << '\n' + << "\t.weak_definition " << name << '\n'; + SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.global " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + if (I->isConstant()) { + const ConstantArray *CVA = dyn_cast(C); + if (TAI->getCStringSection() && CVA && CVA->isCString()) { + SwitchToDataSection(TAI->getCStringSection(), I); + break; + } + } + + SwitchToDataSection("\t.data", I); + break; + default: + cerr << "Unknown linkage type!"; + abort(); + } + + EmitAlignment(Align, I); + O << name << ":\t\t\t\t# '" << I->getName() << "'\n"; + + // If the initializer is a extern weak symbol, remember to emit the weak + // reference! + if (const GlobalValue *GV = dyn_cast(C)) + if (GV->hasExternalWeakLinkage()) + ExtWeakSymbols.insert(GV); + + EmitGlobalConstant(C); + O << '\n'; + } + } + + // Output stubs for dynamically-linked functions + if (TM.getRelocationModel() == Reloc::PIC_) { + for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); + i != e; ++i) { + SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," + "pure_instructions,32"); + EmitAlignment(4); + O << "L" << *i << "$stub:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\tmflr r0\n"; + O << "\tbcl 20,31,L0$" << *i << "\n"; + O << "L0$" << *i << ":\n"; + O << "\tmflr r11\n"; + O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n"; + O << "\tmtlr r0\n"; + O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; + O << "\tmtctr r12\n"; + O << "\tbctr\n"; + SwitchToDataSection(".lazy_symbol_pointer"); + O << "L" << *i << "$lazy_ptr:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.long dyld_stub_binding_helper\n"; + } + } else { + for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); + i != e; ++i) { + SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," + "pure_instructions,16"); + EmitAlignment(4); + O << "L" << *i << "$stub:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n"; + O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; + O << "\tmtctr r12\n"; + O << "\tbctr\n"; + SwitchToDataSection(".lazy_symbol_pointer"); + O << "L" << *i << "$lazy_ptr:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.long dyld_stub_binding_helper\n"; + } + } + + O << "\n"; + + // Output stubs for external and common global variables. + if (GVStubs.begin() != GVStubs.end()) { + SwitchToDataSection(".non_lazy_symbol_pointer"); + for (std::set::iterator I = GVStubs.begin(), + E = GVStubs.end(); I != E; ++I) { + O << "L" << *I << "$non_lazy_ptr:\n"; + O << "\t.indirect_symbol " << *I << "\n"; + O << "\t.long\t0\n"; + } + } + + // Emit initial debug information. + DW.EndModule(); + + // Emit ident information + O << "\t.ident\t\"(llvm 1.9+) STI CBEA Cell SPU backend\"\n"; + + return AsmPrinter::doFinalization(M); +} + + + +/// createSPUCodePrinterPass - Returns a pass that prints the Cell SPU +/// assembly code for a MachineFunction to the given output stream, in a format +/// that the Linux SPU assembler can deal with. +/// +FunctionPass *llvm::createSPUAsmPrinterPass(std::ostream &o, + SPUTargetMachine &tm) { + return new LinuxAsmPrinter(o, tm, tm.getTargetAsmInfo()); +} + Added: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Tue Dec 4 16:23:35 2007 @@ -0,0 +1,62 @@ +//===- SPUCallingConv.td - Calling Conventions for CellSPU ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This describes the calling conventions for the STI Cell SPU architecture. +// +//===----------------------------------------------------------------------===// + +/// CCIfSubtarget - Match if the current subtarget has a feature F. +class CCIfSubtarget + : CCIf().", F), A>; + +//===----------------------------------------------------------------------===// +// Return Value Calling Convention +//===----------------------------------------------------------------------===// + +// Return-value convention for Cell SPU: Everything can be passed back via $3: +def RetCC_SPU : CallingConv<[ + CCIfType<[i32], CCAssignToReg<[R3]>>, + CCIfType<[i64], CCAssignToReg<[R3]>>, + CCIfType<[f32, f64], CCAssignToReg<[R3]>>, + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>> +]>; + + +//===----------------------------------------------------------------------===// +// CellSPU Argument Calling Conventions +// FIXME +//===----------------------------------------------------------------------===// +/* +def CC_SPU : CallingConv<[ + // The first 8 integer arguments are passed in integer registers. + CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>, + CCIfType<[i64], CCAssignToReg<[X3, X4, X5, X6, X7, X8, X9, X10]>>, + + // SPU can pass back arguments in all + CCIfType<[f32, f64], CCIfSubtarget<"isMachoABI()", + CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8,F9,F10,F11,F12,F13]>>>, + // Other sub-targets pass FP values in F1-10. + CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8, F9,F10]>>, + + // The first 12 Vector arguments are passed in altivec registers. + CCIfType<[v16i8, v8i16, v4i32, v4f32], + CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9, V10,V11,V12,V13]>> + */ +/* + // Integer/FP values get stored in stack slots that are 8 bytes in size and + // 8-byte aligned if there are no more registers to hold them. + CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>, + + // Vectors get 16-byte stack slots that are 16-byte aligned. + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], + CCAssignToStack<16, 16>>*/ +]>; + */ Added: llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp Tue Dec 4 16:23:35 2007 @@ -0,0 +1,32 @@ +//===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// Top-level implementation for the Cell SPU target. +// +//===----------------------------------------------------------------------===// + +#include "SPU.h" +#include "SPUFrameInfo.h" +#include "SPURegisterNames.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// SPUFrameInfo: +//===----------------------------------------------------------------------===// + +SPUFrameInfo::SPUFrameInfo(const TargetMachine &tm): + TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), + TM(tm) +{ + LR[0].first = SPU::R0; + LR[0].second = 16; +} Added: llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h Tue Dec 4 16:23:35 2007 @@ -0,0 +1,77 @@ +//===-- SPUFrameInfo.h - Top-level interface for Cell SPU Target -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains CellSPU frame information that doesn't fit anywhere else +// cleanly... +// +//===----------------------------------------------------------------------===// + +#if !defined(SPUFRAMEINFO_H) + +#include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "SPURegisterInfo.h" + +namespace llvm { + class SPUFrameInfo: public TargetFrameInfo { + const TargetMachine &TM; + std::pair LR[1]; + + public: + SPUFrameInfo(const TargetMachine &tm); + + //! Return a function's saved spill slots + /*! + For CellSPU, a function's saved spill slots is just the link register. + */ + const std::pair * + getCalleeSaveSpillSlots(unsigned &NumEntries) const; + + //! Stack slot size (16 bytes) + static const int stackSlotSize() { + return 16; + } + //! Maximum frame offset representable by a signed 10-bit integer + /*! + This is the maximum frame offset that can be expressed as a 10-bit + integer, used in D-form addresses. + */ + static const int maxFrameOffset() { + return ((1 << 9) - 1) * stackSlotSize(); + } + //! Minimum frame offset representable by a signed 10-bit integer + static const int minFrameOffset() { + return -(1 << 9) * stackSlotSize(); + } + //! Minimum frame size (enough to spill LR + SP) + static const int minStackSize() { + return (2 * stackSlotSize()); + } + //! Frame size required to spill all registers plus frame info + static const int fullSpillSize() { + return (SPURegisterInfo::getNumArgRegs() * stackSlotSize()); + } + //! Number of instructions required to overcome hint-for-branch latency + /*! + HBR (hint-for-branch) instructions can be inserted when, for example, + we know that a given function is going to be called, such as printf(), + in the control flow graph. HBRs are only inserted if a sufficient number + of instructions occurs between the HBR and the target. Currently, HBRs + take 6 cycles, ergo, the magic number 6. + */ + static const int branchHintPenalty() { + return 6; + } + }; +} + +#define SPUFRAMEINFO_H 1 +#endif Added: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp Tue Dec 4 16:23:35 2007 @@ -0,0 +1,137 @@ +//===-- SPUHazardRecognizers.cpp - Cell Hazard Recognizer Impls -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements hazard recognizers for scheduling on Cell SPU +// processors. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sched" + +#include "SPUHazardRecognizers.h" +#include "SPU.h" +#include "SPUInstrInfo.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Cell SPU hazard recognizer +// +// This is the pipeline hazard recognizer for the Cell SPU processor. It does +// very little right now. +//===----------------------------------------------------------------------===// + +SPUHazardRecognizer::SPUHazardRecognizer(const TargetInstrInfo &tii) : + TII(tii), + EvenOdd(0) +{ +} + +/// Return the pipeline hazard type encountered or generated by this +/// instruction. Currently returns NoHazard. +/// +/// \return NoHazard +HazardRecognizer::HazardType +SPUHazardRecognizer::getHazardType(SDNode *Node) +{ + // Initial thoughts on how to do this, but this code cannot work unless the + // function's prolog and epilog code are also being scheduled so that we can + // accurately determine which pipeline is being scheduled. +#if 0 + HazardRecognizer::HazardType retval = NoHazard; + bool mustBeOdd = false; + + switch (Node->getOpcode()) { + case SPU::LQDv16i8: + case SPU::LQDv8i16: + case SPU::LQDv4i32: + case SPU::LQDv4f32: + case SPU::LQDv2f64: + case SPU::LQDr128: + case SPU::LQDr64: + case SPU::LQDr32: + case SPU::LQDr16: + case SPU::LQAv16i8: + case SPU::LQAv8i16: + case SPU::LQAv4i32: + case SPU::LQAv4f32: + case SPU::LQAv2f64: + case SPU::LQAr128: + case SPU::LQAr64: + case SPU::LQAr32: + case SPU::LQXv4i32: + case SPU::LQXr128: + case SPU::LQXr64: + case SPU::LQXr32: + case SPU::LQXr16: + case SPU::STQDv16i8: + case SPU::STQDv8i16: + case SPU::STQDv4i32: + case SPU::STQDv4f32: + case SPU::STQDv2f64: + case SPU::STQDr128: + case SPU::STQDr64: + case SPU::STQDr32: + case SPU::STQDr16: + case SPU::STQDr8: + case SPU::STQAv16i8: + case SPU::STQAv8i16: + case SPU::STQAv4i32: + case SPU::STQAv4f32: + case SPU::STQAv2f64: + case SPU::STQAr128: + case SPU::STQAr64: + case SPU::STQAr32: + case SPU::STQAr16: + case SPU::STQAr8: + case SPU::STQXv16i8: + case SPU::STQXv8i16: + case SPU::STQXv4i32: + case SPU::STQXv4f32: + case SPU::STQXv2f64: + case SPU::STQXr128: + case SPU::STQXr64: + case SPU::STQXr32: + case SPU::STQXr16: + case SPU::STQXr8: + case SPU::RET: + mustBeOdd = true; + break; + default: + // Assume that this instruction can be on the even pipe + break; + } + + if (mustBeOdd && !EvenOdd) + retval = Hazard; + + DOUT << "SPUHazardRecognizer EvenOdd " << EvenOdd << " Hazard " << retval << "\n"; + EvenOdd ^= 1; + return retval; +#else + return NoHazard; +#endif +} + +void SPUHazardRecognizer::EmitInstruction(SDNode *Node) +{ +} + +void SPUHazardRecognizer::AdvanceCycle() +{ + DOUT << "SPUHazardRecognizer::AdvanceCycle\n"; +} + +void SPUHazardRecognizer::EmitNoop() +{ + AdvanceCycle(); +} Added: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Tue Dec 4 16:23:35 2007 @@ -0,0 +1,43 @@ +//===-- SPUHazardRecognizers.h - Cell SPU Hazard Recognizer -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines hazard recognizers for scheduling on the Cell SPU +// processor. +// +//===----------------------------------------------------------------------===// + +#ifndef SPUHAZRECS_H +#define SPUHAZRECS_H + +#include "llvm/CodeGen/ScheduleDAG.h" +#include "SPUInstrInfo.h" + +namespace llvm { + +/// SPUHazardRecognizer +class SPUHazardRecognizer : public HazardRecognizer +{ +private: + const TargetInstrInfo &TII; + int EvenOdd; + +public: + SPUHazardRecognizer(const TargetInstrInfo &TII); + virtual HazardType getHazardType(SDNode *Node); + virtual void EmitInstruction(SDNode *Node); + virtual void AdvanceCycle(); + virtual void EmitNoop(); +}; + +} // end namespace llvm + +#endif + Added: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Tue Dec 4 16:23:35 2007 @@ -0,0 +1,615 @@ +//===-- SPUISelDAGToDAG.cpp - CellSPU -pattern matching inst selector -----===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a pattern matching instruction selector for the Cell SPU, +// converting from a legalized dag to a SPU-target dag. +// +//===----------------------------------------------------------------------===// + +#include "SPU.h" +#include "SPUTargetMachine.h" +#include "SPUISelLowering.h" +#include "SPUHazardRecognizers.h" +#include "SPUFrameInfo.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/SSARegMap.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Constants.h" +#include "llvm/GlobalValue.h" +#include "llvm/Intrinsics.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/Compiler.h" +#include +#include +#include + +using namespace llvm; + +namespace { + //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates + bool + isI64IntS10Immediate(ConstantSDNode *CN) + { + return isS10Constant(CN->getValue()); + } + + //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates + bool + isI32IntS10Immediate(ConstantSDNode *CN) + { + return isS10Constant((int) CN->getValue()); + } + +#if 0 + //! SDNode predicate for sign-extended, 10-bit immediate values + bool + isI32IntS10Immediate(SDNode *N) + { + return (N->getOpcode() == ISD::Constant + && isI32IntS10Immediate(cast(N))); + } +#endif + + //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values + bool + isI16IntS10Immediate(ConstantSDNode *CN) + { + return isS10Constant((short) CN->getValue()); + } + + //! SDNode predicate for i16 sign-extended, 10-bit immediate values + bool + isI16IntS10Immediate(SDNode *N) + { + return (N->getOpcode() == ISD::Constant + && isI16IntS10Immediate(cast(N))); + } + + //! ConstantSDNode predicate for signed 16-bit values + /*! + \arg CN The constant SelectionDAG node holding the value + \arg Imm The returned 16-bit value, if returning true + + This predicate tests the value in \a CN to see whether it can be + represented as a 16-bit, sign-extended quantity. Returns true if + this is the case. + */ + bool + isIntS16Immediate(ConstantSDNode *CN, short &Imm) + { + MVT::ValueType vt = CN->getValueType(0); + Imm = (short) CN->getValue(); + if (vt >= MVT::i1 && vt <= MVT::i16) { + return true; + } else if (vt == MVT::i32) { + int32_t i_val = (int32_t) CN->getValue(); + short s_val = (short) i_val; + return i_val == s_val; + } else { + int64_t i_val = (int64_t) CN->getValue(); + short s_val = (short) i_val; + return i_val == s_val; + } + + return false; + } + + //! SDNode predicate for signed 16-bit values. + bool + isIntS16Immediate(SDNode *N, short &Imm) + { + return (N->getOpcode() == ISD::Constant + && isIntS16Immediate(cast(N), Imm)); + } + + //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. + static bool + isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) + { + MVT::ValueType vt = FPN->getValueType(0); + if (vt == MVT::f32) { + const APFloat &apf = FPN->getValueAPF(); + float fval = apf.convertToFloat(); + int val = *((int *) &fval); + int sval = (int) ((val << 16) >> 16); + Imm = (short) val; + return val == sval; + } + + return false; + } + + //===------------------------------------------------------------------===// + //! MVT::ValueType to useful stuff structure: + + struct valtype_map_s { + MVT::ValueType VT; + unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) + int prefslot_byte; /// Byte offset of the "preferred" slot + unsigned brcc_eq_ins; /// br_cc equal instruction + unsigned brcc_neq_ins; /// br_cc not equal instruction + }; + + const valtype_map_s valtype_map[] = { + { MVT::i1, 0, 3, 0, 0 }, + { MVT::i8, 0, 3, 0, 0 }, + { MVT::i16, SPU::ORHIr16, 2, SPU::BRHZ, SPU::BRHNZ }, + { MVT::i32, SPU::ORIr32, 0, SPU::BRZ, SPU::BRNZ }, + { MVT::i64, SPU::ORIr64, 0, 0, 0 }, + { MVT::f32, SPU::ORIf32, 0, 0, 0 }, + { MVT::f64, SPU::ORIf64, 0, 0, 0 } + }; + + const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); + + const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) + { + const valtype_map_s *retval = 0; + for (size_t i = 0; i < n_valtype_map; ++i) { + if (valtype_map[i].VT == VT) { + retval = valtype_map + i; + break; + } + } + + +#ifndef NDEBUG + if (retval == 0) { + cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " + << MVT::getValueTypeString(VT) + << "\n"; + abort(); + } +#endif + + return retval; + } +} + +//===--------------------------------------------------------------------===// +/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine +/// instructions for SelectionDAG operations. +/// +class SPUDAGToDAGISel : + public SelectionDAGISel +{ + SPUTargetMachine &TM; + SPUTargetLowering &SPUtli; + unsigned GlobalBaseReg; + +public: + SPUDAGToDAGISel(SPUTargetMachine &tm) : + SelectionDAGISel(*tm.getTargetLowering()), + TM(tm), + SPUtli(*tm.getTargetLowering()) + {} + + virtual bool runOnFunction(Function &Fn) { + // Make sure we re-emit a set of the global base reg if necessary + GlobalBaseReg = 0; + SelectionDAGISel::runOnFunction(Fn); + return true; + } + + /// getI32Imm - Return a target constant with the specified value, of type + /// i32. + inline SDOperand getI32Imm(uint32_t Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i32); + } + + /// getI64Imm - Return a target constant with the specified value, of type + /// i64. + inline SDOperand getI64Imm(uint64_t Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i64); + } + + /// getSmallIPtrImm - Return a target constant of pointer type. + inline SDOperand getSmallIPtrImm(unsigned Imm) { + return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); + } + + /// Select - Convert the specified operand from a target-independent to a + /// target-specific node if it hasn't already been changed. + SDNode *Select(SDOperand Op); + + /// Return true if the address N is a RI7 format address [r+imm] + bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp, + SDOperand &Base); + + //! Returns true if the address N is an A-form (local store) address + bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Index); + + //! D-form address predicate + bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Index); + + //! Address predicate if N can be expressed as an indexed [r+r] operation. + bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Index); + + /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for + /// inline asm expressions. + virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op, + char ConstraintCode, + std::vector &OutOps, + SelectionDAG &DAG) { + SDOperand Op0, Op1; + switch (ConstraintCode) { + default: return true; + case 'm': // memory + if (!SelectDFormAddr(Op, Op, Op0, Op1) + && !SelectAFormAddr(Op, Op, Op0, Op1)) + SelectXFormAddr(Op, Op, Op0, Op1); + break; + case 'o': // offsetable + if (!SelectDFormAddr(Op, Op, Op0, Op1) + && !SelectAFormAddr(Op, Op, Op0, Op1)) { + Op0 = Op; + AddToISelQueue(Op0); // r+0. + Op1 = getSmallIPtrImm(0); + } + break; + case 'v': // not offsetable +#if 1 + assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); +#else + SelectAddrIdxOnly(Op, Op, Op0, Op1); +#endif + break; + } + + OutOps.push_back(Op0); + OutOps.push_back(Op1); + return false; + } + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + + virtual const char *getPassName() const { + return "Cell SPU DAG->DAG Pattern Instruction Selection"; + } + + /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for + /// this target when scheduling the DAG. + virtual HazardRecognizer *CreateTargetHazardRecognizer() { + const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo(); + assert(II && "No InstrInfo?"); + return new SPUHazardRecognizer(*II); + } + + // Include the pieces autogenerated from the target description. +#include "SPUGenDAGISel.inc" +}; + +/// InstructionSelectBasicBlock - This callback is invoked by +/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. +void +SPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) +{ + DEBUG(BB->dump()); + + // Select target instructions for the DAG. + DAG.setRoot(SelectRoot(DAG.getRoot())); + DAG.RemoveDeadNodes(); + + // Emit machine code to BB. + ScheduleAndEmitDAG(DAG); +} + +bool +SPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp, + SDOperand &Base) { + unsigned Opc = N.getOpcode(); + unsigned VT = N.getValueType(); + MVT::ValueType PtrVT = SPUtli.getPointerTy(); + ConstantSDNode *CN = 0; + int Imm; + + if (Opc == ISD::ADD) { + SDOperand Op0 = N.getOperand(0); + SDOperand Op1 = N.getOperand(1); + if (Op1.getOpcode() == ISD::Constant || + Op1.getOpcode() == ISD::TargetConstant) { + CN = cast(Op1); + Imm = int(CN->getValue()); + if (Imm <= 0xff) { + Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); + Base = Op0; + return true; + } + } + } else if (Opc == ISD::GlobalAddress + || Opc == ISD::TargetGlobalAddress + || Opc == ISD::Register) { + // Plain old local store address: + Disp = CurDAG->getTargetConstant(0, VT); + Base = N; + return true; + } else if (Opc == SPUISD::DFormAddr) { + // D-Form address: This is pretty straightforward, naturally... + CN = cast(N.getOperand(1)); + assert(CN != 0 && "SelectDFormAddr/SPUISD::DForm2Addr expecting constant"); + Imm = unsigned(CN->getValue()); + if (Imm < 0xff) { + Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT); + Base = N.getOperand(0); + return true; + } + } + + return false; +} + +/*! + \arg Op The ISD instructio operand + \arg N The address to be tested + \arg Base The base address + \arg Index The base address index + */ +bool +SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Index) { + // These match the addr256k operand type: + MVT::ValueType PtrVT = SPUtli.getPointerTy(); + MVT::ValueType OffsVT = MVT::i16; + + switch (N.getOpcode()) { + case ISD::Constant: + case ISD::TargetConstant: { + // Loading from a constant address. + ConstantSDNode *CN = dyn_cast(N); + int Imm = (int)CN->getValue(); + if (Imm < 0x3ffff && (Imm & 0x3) == 0) { + Base = CurDAG->getTargetConstant(Imm, PtrVT); + // Note that this operand will be ignored by the assembly printer... + Index = CurDAG->getTargetConstant(0, OffsVT); + return true; + } + } + case ISD::ConstantPool: + case ISD::TargetConstantPool: { + // The constant pool address is N. Base is a dummy that will be ignored by + // the assembly printer. + Base = N; + Index = CurDAG->getTargetConstant(0, OffsVT); + return true; + } + + case ISD::GlobalAddress: + case ISD::TargetGlobalAddress: { + // The global address is N. Base is a dummy that is ignored by the + // assembly printer. + Base = N; + Index = CurDAG->getTargetConstant(0, OffsVT); + return true; + } + } + + return false; +} + +/*! + \arg Op The ISD instruction (ignored) + \arg N The address to be tested + \arg Base Base address register/pointer + \arg Index Base address index + + Examine the input address by a base register plus a signed 10-bit + displacement, [r+I10] (D-form address). + + \return true if \a N is a D-form address with \a Base and \a Index set + to non-empty SDOperand instances. +*/ +bool +SPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Index) { + unsigned Opc = N.getOpcode(); + unsigned PtrTy = SPUtli.getPointerTy(); + + if (Opc == ISD::Register) { + Base = N; + Index = CurDAG->getTargetConstant(0, PtrTy); + return true; + } else if (Opc == ISD::FrameIndex) { + // Stack frame index must be less than 512 (divided by 16): + FrameIndexSDNode *FI = dyn_cast(N); + DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " + << FI->getIndex() << "\n"); + if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { + Base = CurDAG->getTargetConstant(0, PtrTy); + Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); + return true; + } + } else if (Opc == ISD::ADD) { + // Generated by getelementptr + const SDOperand Op0 = N.getOperand(0); // Frame index/base + const SDOperand Op1 = N.getOperand(1); // Offset within base + ConstantSDNode *CN = dyn_cast(Op1); + + // Not a constant? + if (CN == 0) + return false; + + int32_t offset = (int32_t) CN->getSignExtended(); + unsigned Opc0 = Op0.getOpcode(); + + if ((offset & 0xf) != 0) { + cerr << "SelectDFormAddr: unaligned offset = " << offset << "\n"; + abort(); + /*NOTREACHED*/ + } + + if (Opc0 == ISD::FrameIndex) { + FrameIndexSDNode *FI = dyn_cast(Op0); + DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset + << " frame index = " << FI->getIndex() << "\n"); + + if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { + Base = CurDAG->getTargetConstant(offset, PtrTy); + Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); + return true; + } + } else if (offset > SPUFrameInfo::minFrameOffset() + && offset < SPUFrameInfo::maxFrameOffset()) { + Base = CurDAG->getTargetConstant(offset, PtrTy); + if (Opc0 == ISD::GlobalAddress) { + // Convert global address to target global address + GlobalAddressSDNode *GV = dyn_cast(Op0); + Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy); + return true; + } else { + // Otherwise, just take operand 0 + Index = Op0; + return true; + } + } + } else if (Opc == SPUISD::DFormAddr) { + // D-Form address: This is pretty straightforward, naturally... + ConstantSDNode *CN = cast(N.getOperand(1)); + assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant"); + Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); + Index = N.getOperand(0); + return true; + } + + return false; +} + +/*! + \arg Op The ISD instruction operand + \arg N The address operand + \arg Base The base pointer operand + \arg Index The offset/index operand + + If the address \a N can be expressed as a [r + s10imm] address, returns false. + Otherwise, creates two operands, Base and Index that will become the [r+r] + address. +*/ +bool +SPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Index) { + if (SelectAFormAddr(Op, N, Base, Index) + || SelectDFormAddr(Op, N, Base, Index)) + return false; + + unsigned Opc = N.getOpcode(); + + if (Opc == ISD::ADD) { + SDOperand N1 = N.getOperand(0); + SDOperand N2 = N.getOperand(1); + unsigned N1Opc = N1.getOpcode(); + unsigned N2Opc = N2.getOpcode(); + + if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo) + || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)) { + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; + } else { + cerr << "SelectXFormAddr: Unhandled ADD operands:\n"; + N1.Val->dump(); + cerr << "\n"; + N2.Val->dump(); + cerr << "\n"; + abort(); + /*UNREACHED*/ + } + } else if (N.getNumOperands() == 2) { + SDOperand N1 = N.getOperand(0); + SDOperand N2 = N.getOperand(1); + unsigned N1Opc = N1.getOpcode(); + unsigned N2Opc = N2.getOpcode(); + + if ((N1Opc == ISD::CopyToReg || N1Opc == ISD::Register) + && (N2Opc == ISD::CopyToReg || N2Opc == ISD::Register)) { + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; + /*UNREACHED*/ + } else { + cerr << "SelectXFormAddr: 2-operand unhandled operand:\n"; + N.Val->dump(); + cerr << "\n"; + abort(); + /*UNREACHED*/ + } + } else { + cerr << "SelectXFormAddr: Unhandled operand type:\n"; + N.Val->dump(); + cerr << "\n"; + abort(); + /*UNREACHED*/ + } + + return false; +} + +//! Convert the operand from a target-independent to a target-specific node +/*! + */ +SDNode * +SPUDAGToDAGISel::Select(SDOperand Op) { + SDNode *N = Op.Val; + unsigned Opc = N->getOpcode(); + + if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) { + return NULL; // Already selected. + } else if (Opc == ISD::FrameIndex) { + // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm. + int FI = cast(N)->getIndex(); + SDOperand TFI = CurDAG->getTargetFrameIndex(FI, SPUtli.getPointerTy()); + + DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 TFI, 0\n"); + return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI, + CurDAG->getTargetConstant(0, MVT::i32)); + } else if (Opc == SPUISD::LDRESULT) { + // Custom select instructions for LDRESULT + unsigned VT = N->getValueType(0); + SDOperand Arg = N->getOperand(0); + SDOperand Chain = N->getOperand(1); + SDOperand Zero = CurDAG->getTargetConstant(0, VT); + SDNode *Result; + const valtype_map_s *vtm = getValueTypeMapEntry(VT); + + if (vtm->ldresult_ins == 0) { + cerr << "LDRESULT for unsupported type: " + << MVT::getValueTypeString(VT) + << "\n"; + abort(); + } else + Opc = vtm->ldresult_ins; + + AddToISelQueue(Arg); + AddToISelQueue(Zero); + AddToISelQueue(Chain); + Result = CurDAG->SelectNodeTo(N, Opc, VT, MVT::Other, Arg, Zero, Chain); + Chain = SDOperand(Result, 1); + return Result; + } + + return SelectCode(Op); +} + +/// createPPCISelDag - This pass converts a legalized DAG into a +/// SPU-specific DAG, ready for instruction scheduling. +/// +FunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { + return new SPUDAGToDAGISel(TM); +} Added: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Tue Dec 4 16:23:35 2007 @@ -0,0 +1,2673 @@ +//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the SPUTargetLowering class. +// +//===----------------------------------------------------------------------===// + +#include "SPURegisterNames.h" +#include "SPUISelLowering.h" +#include "SPUTargetMachine.h" +#include "llvm/ADT/VectorExtras.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SSARegMap.h" +#include "llvm/Constants.h" +#include "llvm/Function.h" +#include "llvm/Intrinsics.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Target/TargetOptions.h" + +#include + +using namespace llvm; + +// Used in getTargetNodeName() below +namespace { + std::map node_names; + + //! MVT::ValueType mapping to useful data for Cell SPU + struct valtype_map_s { + const MVT::ValueType valtype; + const int prefslot_byte; + }; + + const valtype_map_s valtype_map[] = { + { MVT::i1, 3 }, + { MVT::i8, 3 }, + { MVT::i16, 2 }, + { MVT::i32, 0 }, + { MVT::f32, 0 }, + { MVT::i64, 0 }, + { MVT::f64, 0 }, + { MVT::i128, 0 } + }; + + const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); + + const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) { + const valtype_map_s *retval = 0; + + for (size_t i = 0; i < n_valtype_map; ++i) { + if (valtype_map[i].valtype == VT) { + retval = valtype_map + i; + break; + } + } + +#ifndef NDEBUG + if (retval == 0) { + cerr << "getValueTypeMapEntry returns NULL for " + << MVT::getValueTypeString(VT) + << "\n"; + abort(); + } +#endif + + return retval; + } + + //! Predicate that returns true if operand is a memory target + /*! + \arg Op Operand to test + \return true if the operand is a memory target (i.e., global + address, external symbol, constant pool) or an existing D-Form + address. + */ + bool isMemoryOperand(const SDOperand &Op) + { + const unsigned Opc = Op.getOpcode(); + return (Opc == ISD::GlobalAddress + || Opc == ISD::GlobalTLSAddress + || Opc == ISD::FrameIndex + || Opc == ISD::JumpTable + || Opc == ISD::ConstantPool + || Opc == ISD::ExternalSymbol + || Opc == ISD::TargetGlobalAddress + || Opc == ISD::TargetGlobalTLSAddress + || Opc == ISD::TargetFrameIndex + || Opc == ISD::TargetJumpTable + || Opc == ISD::TargetConstantPool + || Opc == ISD::TargetExternalSymbol + || Opc == SPUISD::DFormAddr); + } +} + +SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) + : TargetLowering(TM), + SPUTM(TM) +{ + // Fold away setcc operations if possible. + setPow2DivIsCheap(); + + // Use _setjmp/_longjmp instead of setjmp/longjmp. + setUseUnderscoreSetJmp(true); + setUseUnderscoreLongJmp(true); + + // Set up the SPU's register classes: + // NOTE: i8 register class is not registered because we cannot determine when + // we need to zero or sign extend for custom-lowered loads and stores. + addRegisterClass(MVT::i16, SPU::R16CRegisterClass); + addRegisterClass(MVT::i32, SPU::R32CRegisterClass); + addRegisterClass(MVT::i64, SPU::R64CRegisterClass); + addRegisterClass(MVT::f32, SPU::R32FPRegisterClass); + addRegisterClass(MVT::f64, SPU::R64FPRegisterClass); + addRegisterClass(MVT::i128, SPU::GPRCRegisterClass); + + // SPU has no sign or zero extended loads for i1, i8, i16: + setLoadXAction(ISD::EXTLOAD, MVT::i1, Custom); + setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote); + setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote); + setStoreXAction(MVT::i1, Custom); + + setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom); + setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom); + setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom); + setStoreXAction(MVT::i8, Custom); + + setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom); + setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom); + setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom); + + // SPU constant load actions are custom lowered: + setOperationAction(ISD::Constant, MVT::i64, Custom); + setOperationAction(ISD::ConstantFP, MVT::f32, Custom); + setOperationAction(ISD::ConstantFP, MVT::f64, Custom); + + // SPU's loads and stores have to be custom lowered: + for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128; + ++sctype) { + setOperationAction(ISD::LOAD, sctype, Custom); + setOperationAction(ISD::STORE, sctype, Custom); + } + + // SPU supports BRCOND, although DAGCombine will convert BRCONDs + // into BR_CCs. BR_CC instructions are custom selected in + // SPUDAGToDAGISel. + setOperationAction(ISD::BRCOND, MVT::Other, Legal); + + // Expand the jumptable branches + setOperationAction(ISD::BR_JT, MVT::Other, Expand); + setOperationAction(ISD::BR_CC, MVT::Other, Expand); + setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); + + // SPU has no intrinsics for these particular operations: + setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); + setOperationAction(ISD::MEMSET, MVT::Other, Expand); + setOperationAction(ISD::MEMCPY, MVT::Other, Expand); + + // PowerPC has no SREM/UREM instructions + setOperationAction(ISD::SREM, MVT::i32, Expand); + setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::SREM, MVT::i64, Expand); + setOperationAction(ISD::UREM, MVT::i64, Expand); + + // We don't support sin/cos/sqrt/fmod + setOperationAction(ISD::FSIN , MVT::f64, Expand); + setOperationAction(ISD::FCOS , MVT::f64, Expand); + setOperationAction(ISD::FREM , MVT::f64, Expand); + setOperationAction(ISD::FSIN , MVT::f32, Expand); + setOperationAction(ISD::FCOS , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); + + // If we're enabling GP optimizations, use hardware square root + setOperationAction(ISD::FSQRT, MVT::f64, Expand); + setOperationAction(ISD::FSQRT, MVT::f32, Expand); + + setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); + setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); + + // SPU can do rotate right and left, so legalize it... but customize for i8 + // because instructions don't exist. + setOperationAction(ISD::ROTR, MVT::i32, Legal); + setOperationAction(ISD::ROTR, MVT::i16, Legal); + setOperationAction(ISD::ROTR, MVT::i8, Custom); + setOperationAction(ISD::ROTL, MVT::i32, Legal); + setOperationAction(ISD::ROTL, MVT::i16, Legal); + setOperationAction(ISD::ROTL, MVT::i8, Custom); + // SPU has no native version of shift left/right for i8 + setOperationAction(ISD::SHL, MVT::i8, Custom); + setOperationAction(ISD::SRL, MVT::i8, Custom); + setOperationAction(ISD::SRA, MVT::i8, Custom); + + // Custom lower i32 multiplications + setOperationAction(ISD::MUL, MVT::i32, Custom); + + // Need to custom handle (some) common i8 math ops + setOperationAction(ISD::SUB, MVT::i8, Custom); + setOperationAction(ISD::MUL, MVT::i8, Custom); + + // SPU does not have BSWAP. It does have i32 support CTLZ. + // CTPOP has to be custom lowered. + setOperationAction(ISD::BSWAP, MVT::i32, Expand); + setOperationAction(ISD::BSWAP, MVT::i64, Expand); + + setOperationAction(ISD::CTPOP, MVT::i8, Custom); + setOperationAction(ISD::CTPOP, MVT::i16, Custom); + setOperationAction(ISD::CTPOP, MVT::i32, Custom); + setOperationAction(ISD::CTPOP, MVT::i64, Custom); + + setOperationAction(ISD::CTTZ , MVT::i32, Expand); + setOperationAction(ISD::CTTZ , MVT::i64, Expand); + + setOperationAction(ISD::CTLZ , MVT::i32, Legal); + + // SPU does not have select or setcc + setOperationAction(ISD::SELECT, MVT::i1, Expand); + setOperationAction(ISD::SELECT, MVT::i8, Expand); + setOperationAction(ISD::SELECT, MVT::i16, Expand); + setOperationAction(ISD::SELECT, MVT::i32, Expand); + setOperationAction(ISD::SELECT, MVT::i64, Expand); + setOperationAction(ISD::SELECT, MVT::f32, Expand); + setOperationAction(ISD::SELECT, MVT::f64, Expand); + + setOperationAction(ISD::SETCC, MVT::i1, Expand); + setOperationAction(ISD::SETCC, MVT::i8, Expand); + setOperationAction(ISD::SETCC, MVT::i16, Expand); + setOperationAction(ISD::SETCC, MVT::i32, Expand); + setOperationAction(ISD::SETCC, MVT::i64, Expand); + setOperationAction(ISD::SETCC, MVT::f32, Expand); + setOperationAction(ISD::SETCC, MVT::f64, Expand); + + // SPU has a legal FP -> signed INT instruction + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal); + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal); + setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom); + + // FDIV on SPU requires custom lowering + setOperationAction(ISD::FDIV, MVT::f32, Custom); + //setOperationAction(ISD::FDIV, MVT::f64, Custom); + + // SPU has [U|S]INT_TO_FP + setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal); + setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); + setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote); + setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal); + setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote); + setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote); + setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom); + + setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand); + setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand); + setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand); + setOperationAction(ISD::BIT_CONVERT, MVT::f64, Expand); + + // We cannot sextinreg(i1). Expand to shifts. + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); + + // Support label based line numbers. + setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + + // We want to legalize GlobalAddress and ConstantPool nodes into the + // appropriate instructions to materialize the address. + setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + setOperationAction(ISD::ConstantPool, MVT::f32, Custom); + setOperationAction(ISD::JumpTable, MVT::i32, Custom); + setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); + setOperationAction(ISD::ConstantPool, MVT::i64, Custom); + setOperationAction(ISD::ConstantPool, MVT::f64, Custom); + setOperationAction(ISD::JumpTable, MVT::i64, Custom); + + // RET must be custom lowered, to meet ABI requirements + setOperationAction(ISD::RET, MVT::Other, Custom); + + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VASTART , MVT::Other, Custom); + + // Use the default implementation. + setOperationAction(ISD::VAARG , MVT::Other, Expand); + setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); + setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); + setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand); + + // Cell SPU has instructions for converting between i64 and fp. + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); + setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); + + // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); + + // BUILD_PAIR can't be handled natively, and should be expanded to shl/or + setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand); + + // First set operation action for all vector types to expand. Then we + // will selectively turn on ones that can be effectively codegen'd. + addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass); + addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass); + addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass); + addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass); + addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass); + addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass); + + for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; + VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) { + // add/sub are legal for all supported vector VT's. + setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal); + setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal); + // mul has to be custom lowered. + setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom); + + setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal); + setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal); + setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal); + setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal); + setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal); + setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal); + + // These operations need to be expanded: + setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom); + + // Custom lower build_vector, constant pool spills, insert and + // extract vector elements: + setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom); + setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom); + setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom); + setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom); + setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom); + setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom); + } + + setOperationAction(ISD::MUL, MVT::v16i8, Custom); + setOperationAction(ISD::AND, MVT::v16i8, Custom); + setOperationAction(ISD::OR, MVT::v16i8, Custom); + setOperationAction(ISD::XOR, MVT::v16i8, Custom); + setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom); + + setSetCCResultType(MVT::i32); + setShiftAmountType(MVT::i32); + setSetCCResultContents(ZeroOrOneSetCCResult); + + setStackPointerRegisterToSaveRestore(SPU::R1); + + // We have target-specific dag combine patterns for the following nodes: + // e.g., setTargetDAGCombine(ISD::SUB); + + computeRegisterProperties(); +} + +const char * +SPUTargetLowering::getTargetNodeName(unsigned Opcode) const +{ + if (node_names.empty()) { + node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG"; + node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi"; + node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo"; + node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr"; + node_names[(unsigned) SPUISD::DFormAddr] = "SPUISD::DFormAddr"; + node_names[(unsigned) SPUISD::XFormAddr] = "SPUISD::XFormAddr"; + node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT"; + node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL"; + node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB"; + node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK"; + node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB"; + node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR"; + node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0"; + node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED"; + node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT"; + node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT"; + node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT"; + node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT"; + node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY"; + node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU"; + node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH"; + node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH"; + node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL"; + node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL"; + node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA"; + node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL"; + node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR"; + node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_Z] = + "SPUISD::ROTBYTES_RIGHT_Z"; + node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] = + "SPUISD::ROTBYTES_RIGHT_S"; + node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT"; + node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] = + "SPUISD::ROTBYTES_LEFT_CHAINED"; + node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI"; + node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB"; + node_names[(unsigned) SPUISD::SFPConstant] = "SPUISD::SFPConstant"; + node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp"; + node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst"; + node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64"; + } + + std::map::iterator i = node_names.find(Opcode); + + return ((i != node_names.end()) ? i->second : 0); +} + +//===----------------------------------------------------------------------===// +// Calling convention code: +//===----------------------------------------------------------------------===// + +#include "SPUGenCallingConv.inc" + +//===----------------------------------------------------------------------===// +// LowerOperation implementation +//===----------------------------------------------------------------------===// + +/// Custom lower loads for CellSPU +/*! + All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements + within a 16-byte block, we have to rotate to extract the requested element. + */ +static SDOperand +LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { + LoadSDNode *LN = cast(Op); + SDOperand basep = LN->getBasePtr(); + SDOperand the_chain = LN->getChain(); + MVT::ValueType VT = LN->getLoadedVT(); + MVT::ValueType OpVT = Op.Val->getValueType(0); + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + ISD::LoadExtType ExtType = LN->getExtensionType(); + unsigned alignment = LN->getAlignment(); + const valtype_map_s *vtm = getValueTypeMapEntry(VT); + SDOperand Ops[8]; + + // For an extending load of an i1 variable, just call it i8 (or whatever we + // were passed) and make it zero-extended: + if (VT == MVT::i1) { + VT = OpVT; + ExtType = ISD::ZEXTLOAD; + } + + switch (LN->getAddressingMode()) { + case ISD::UNINDEXED: { + SDOperand result; + SDOperand rot_op, rotamt; + SDOperand ptrp; + int c_offset; + int c_rotamt; + + // The vector type we really want to be when we load the 16-byte chunk + MVT::ValueType vecVT, opVecVT; + + if (VT != MVT::i1) + vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT))); + else + vecVT = MVT::v16i8; + + opVecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT))); + + if (basep.getOpcode() == ISD::ADD) { + const ConstantSDNode *CN = cast(basep.Val->getOperand(1)); + + assert(CN != NULL + && "LowerLOAD: ISD::ADD operand 1 is not constant"); + + c_offset = (int) CN->getValue(); + c_rotamt = (int) (c_offset & 0xf); + + // Adjust the rotation amount to ensure that the final result ends up in + // the preferred slot: + c_rotamt -= vtm->prefslot_byte; + ptrp = basep.getOperand(0); + } else { + c_offset = 0; + c_rotamt = -vtm->prefslot_byte; + ptrp = basep; + } + + if (alignment == 16) { + // 16-byte aligned load into preferred slot, no rotation + if (c_rotamt == 0) { + if (isMemoryOperand(ptrp)) + // Return unchanged + return SDOperand(); + else { + // Return modified D-Form address for pointer: + ptrp = DAG.getNode(SPUISD::DFormAddr, PtrVT, + ptrp, DAG.getConstant((c_offset & ~0xf), PtrVT)); + if (VT == OpVT) + return DAG.getLoad(VT, LN->getChain(), ptrp, + LN->getSrcValue(), LN->getSrcValueOffset(), + LN->isVolatile(), 16); + else + return DAG.getExtLoad(ExtType, VT, LN->getChain(), ptrp, LN->getSrcValue(), + LN->getSrcValueOffset(), OpVT, + LN->isVolatile(), 16); + } + } else { + // Need to rotate... + if (c_rotamt < 0) + c_rotamt += 16; + // Realign the base pointer, with a D-Form address + if ((c_offset & ~0xf) != 0 || !isMemoryOperand(ptrp)) + basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, + ptrp, DAG.getConstant((c_offset & ~0xf), MVT::i32)); + else + basep = ptrp; + + // Rotate the load: + rot_op = DAG.getLoad(MVT::v16i8, the_chain, basep, + LN->getSrcValue(), LN->getSrcValueOffset(), + LN->isVolatile(), 16); + the_chain = rot_op.getValue(1); + rotamt = DAG.getConstant(c_rotamt, MVT::i16); + + SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other); + Ops[0] = the_chain; + Ops[1] = rot_op; + Ops[2] = rotamt; + + result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3); + the_chain = result.getValue(1); + + if (VT == OpVT || ExtType == ISD::EXTLOAD) { + SDVTList scalarvts; + Ops[0] = the_chain; + Ops[1] = result; + if (OpVT == VT) { + scalarvts = DAG.getVTList(VT, MVT::Other); + } else { + scalarvts = DAG.getVTList(OpVT, MVT::Other); + } + + result = DAG.getNode(ISD::BIT_CONVERT, (OpVT == VT ? vecVT : opVecVT), + result); + Ops[0] = the_chain; + Ops[1] = result; + result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2); + the_chain = result.getValue(1); + } else { + // Handle the sign and zero-extending loads for i1 and i8: + unsigned NewOpC; + + if (ExtType == ISD::SEXTLOAD) { + NewOpC = (OpVT == MVT::i1 + ? SPUISD::EXTRACT_I1_SEXT + : SPUISD::EXTRACT_I8_SEXT); + } else if (ExtType == ISD::ZEXTLOAD) { + NewOpC = (OpVT == MVT::i1 + ? SPUISD::EXTRACT_I1_ZEXT + : SPUISD::EXTRACT_I8_ZEXT); + } + + result = DAG.getNode(NewOpC, OpVT, result); + } + + SDVTList retvts = DAG.getVTList(OpVT, MVT::Other); + SDOperand retops[2] = { result, the_chain }; + + result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2); + return result; + /*UNREACHED*/ + } + } else { + // Misaligned 16-byte load: + if (basep.getOpcode() == ISD::LOAD) { + LN = cast(basep); + if (LN->getAlignment() == 16) { + // We can verify that we're really loading from a 16-byte aligned + // chunk. Encapsulate basep as a D-Form address and return a new + // load: + basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, basep, + DAG.getConstant(0, PtrVT)); + if (OpVT == VT) + return DAG.getLoad(VT, LN->getChain(), basep, + LN->getSrcValue(), LN->getSrcValueOffset(), + LN->isVolatile(), 16); + else + return DAG.getExtLoad(ExtType, VT, LN->getChain(), basep, + LN->getSrcValue(), LN->getSrcValueOffset(), + OpVT, LN->isVolatile(), 16); + } + } + + // Catch all other cases where we can't guarantee that we have a + // 16-byte aligned entity, which means resorting to an X-form + // address scheme: + + SDOperand ZeroOffs = DAG.getConstant(0, PtrVT); + SDOperand loOp = DAG.getNode(SPUISD::Lo, VT, basep, ZeroOffs); + SDOperand hiOp = DAG.getNode(SPUISD::Hi, VT, basep, ZeroOffs); + + ptrp = DAG.getNode(ISD::ADD, PtrVT, loOp, hiOp); + + SDOperand alignLoad = + DAG.getLoad(opVecVT, LN->getChain(), ptrp, + LN->getSrcValue(), LN->getSrcValueOffset(), + LN->isVolatile(), 16); + + SDOperand insertEltOp = + DAG.getNode(SPUISD::INSERT_MASK, vecVT, ptrp); + + result = DAG.getNode(SPUISD::SHUFB, opVecVT, + alignLoad, + alignLoad, + DAG.getNode(ISD::BIT_CONVERT, opVecVT, insertEltOp)); + + result = DAG.getNode(SPUISD::EXTRACT_ELT0, OpVT, result); + + SDVTList retvts = DAG.getVTList(OpVT, MVT::Other); + SDOperand retops[2] = { result, the_chain }; + + result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2); + return result; + } + break; + } + case ISD::PRE_INC: + case ISD::PRE_DEC: + case ISD::POST_INC: + case ISD::POST_DEC: + case ISD::LAST_INDEXED_MODE: + cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than " + "UNINDEXED\n"; + cerr << (unsigned) LN->getAddressingMode() << "\n"; + abort(); + /*NOTREACHED*/ + } + + return SDOperand(); +} + +/// Custom lower stores for CellSPU +/*! + All CellSPU stores are aligned to 16-byte boundaries, so for elements + within a 16-byte block, we have to generate a shuffle to insert the + requested element into its place, then store the resulting block. + */ +static SDOperand +LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { + StoreSDNode *SN = cast(Op); + SDOperand Value = SN->getValue(); + MVT::ValueType VT = Value.getValueType(); + MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getStoredVT()); + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + SDOperand the_chain = SN->getChain(); + unsigned alignment = SN->getAlignment(); + const valtype_map_s *vtm = getValueTypeMapEntry(VT); + + switch (SN->getAddressingMode()) { + case ISD::UNINDEXED: { + SDOperand basep = SN->getBasePtr(); + SDOperand ptrOp; + int offset; + + if (basep.getOpcode() == ISD::ADD) { + const ConstantSDNode *CN = cast(basep.Val->getOperand(1)); + assert(CN != NULL + && "LowerSTORE: ISD::ADD operand 1 is not constant"); + offset = unsigned(CN->getValue()); + ptrOp = basep.getOperand(0); + DEBUG(cerr << "LowerSTORE: StoreSDNode ISD:ADD offset = " + << offset + << "\n"); + } else { + ptrOp = basep; + offset = 0; + } + + // The vector type we really want to load from the 16-byte chunk, except + // in the case of MVT::i1, which has to be v16i8. + unsigned vecVT, stVecVT; + + if (StVT != MVT::i1) + stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT))); + else + stVecVT = MVT::v16i8; + vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT))); + + // Realign the pointer as a D-Form address (ptrOp is the pointer, + // to force a register load with the address; basep is the actual + // dform addr offs($reg). + ptrOp = DAG.getNode(SPUISD::DFormAddr, PtrVT, ptrOp, + DAG.getConstant(0, PtrVT)); + basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, + ptrOp, DAG.getConstant((offset & ~0xf), PtrVT)); + + // Create the 16-byte aligned vector load + SDOperand alignLoad = + DAG.getLoad(vecVT, the_chain, basep, + SN->getSrcValue(), SN->getSrcValueOffset(), + SN->isVolatile(), 16); + the_chain = alignLoad.getValue(1); + + LoadSDNode *LN = cast(alignLoad); + SDOperand theValue = SN->getValue(); + SDOperand result; + + if (StVT != VT + && (theValue.getOpcode() == ISD::AssertZext + || theValue.getOpcode() == ISD::AssertSext)) { + // Drill down and get the value for zero- and sign-extended + // quantities + theValue = theValue.getOperand(0); + } + + SDOperand insertEltOp = + DAG.getNode(SPUISD::INSERT_MASK, stVecVT, + DAG.getNode(SPUISD::DFormAddr, PtrVT, + ptrOp, + DAG.getConstant((offset & 0xf), PtrVT))); + + result = DAG.getNode(SPUISD::SHUFB, vecVT, + DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue), + alignLoad, + DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp)); + + result = DAG.getStore(the_chain, result, basep, + LN->getSrcValue(), LN->getSrcValueOffset(), + LN->isVolatile(), LN->getAlignment()); + + return result; + /*UNREACHED*/ + } + case ISD::PRE_INC: + case ISD::PRE_DEC: + case ISD::POST_INC: + case ISD::POST_DEC: + case ISD::LAST_INDEXED_MODE: + cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than " + "UNINDEXED\n"; + cerr << (unsigned) SN->getAddressingMode() << "\n"; + abort(); + /*NOTREACHED*/ + } + + return SDOperand(); +} + +/// Generate the address of a constant pool entry. +static SDOperand +LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { + MVT::ValueType PtrVT = Op.getValueType(); + ConstantPoolSDNode *CP = cast(Op); + Constant *C = CP->getConstVal(); + SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); + const TargetMachine &TM = DAG.getTarget(); + SDOperand Zero = DAG.getConstant(0, PtrVT); + + if (TM.getRelocationModel() == Reloc::Static) { + if (!ST->usingLargeMem()) { + // Just return the SDOperand with the constant pool address in it. + return CPI; + } else { + // Generate hi/lo address pair + SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero); + SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero); + + return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi); + } + } + + assert(0 && + "LowerConstantPool: Relocation model other than static not supported."); + return SDOperand(); +} + +static SDOperand +LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { + MVT::ValueType PtrVT = Op.getValueType(); + JumpTableSDNode *JT = cast(Op); + SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); + SDOperand Zero = DAG.getConstant(0, PtrVT); + const TargetMachine &TM = DAG.getTarget(); + + if (TM.getRelocationModel() == Reloc::Static) { + if (!ST->usingLargeMem()) { + // Just return the SDOperand with the jump table address in it. + return JTI; + } else { + // Generate hi/lo address pair + SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero); + SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero); + + return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi); + } + } + + assert(0 && + "LowerJumpTable: Relocation model other than static not supported."); + return SDOperand(); +} + +static SDOperand +LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { + MVT::ValueType PtrVT = Op.getValueType(); + GlobalAddressSDNode *GSDN = cast(Op); + GlobalValue *GV = GSDN->getGlobal(); + SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset()); + SDOperand Zero = DAG.getConstant(0, PtrVT); + const TargetMachine &TM = DAG.getTarget(); + + if (TM.getRelocationModel() == Reloc::Static) { + if (!ST->usingLargeMem()) { + // Generate a local store address + return GA; + } else { + // Generate hi/lo address pair + SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero); + SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero); + + return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi); + } + } else { + cerr << "LowerGlobalAddress: Relocation model other than static not " + << "supported.\n"; + abort(); + /*NOTREACHED*/ + } + + return SDOperand(); +} + +//! Custom lower i64 integer constants +/*! + This code inserts all of the necessary juggling that needs to occur to load + a 64-bit constant into a register. + */ +static SDOperand +LowerConstant(SDOperand Op, SelectionDAG &DAG) { + unsigned VT = Op.getValueType(); + ConstantSDNode *CN = cast(Op.Val); + + if (VT == MVT::i64) { + SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64); + return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T)); + + } else { + cerr << "LowerConstant: unhandled constant type " + << MVT::getValueTypeString(VT) + << "\n"; + abort(); + /*NOTREACHED*/ + } + + return SDOperand(); +} + +//! Custom lower single precision floating point constants +/*! + "float" immediates can be lowered as if they were unsigned 32-bit integers. + The SPUISD::SFPConstant pseudo-instruction handles this in the instruction + target description. + */ +static SDOperand +LowerConstantFP(SDOperand Op, SelectionDAG &DAG) { + unsigned VT = Op.getValueType(); + ConstantFPSDNode *FP = cast(Op.Val); + + assert((FP != 0) && + "LowerConstantFP: Node is not ConstantFPSDNode"); + + const APFloat &apf = FP->getValueAPF(); + + if (VT == MVT::f32) { + return DAG.getNode(SPUISD::SFPConstant, VT, + DAG.getTargetConstantFP(apf.convertToFloat(), VT)); + } else if (VT == MVT::f64) { + uint64_t dbits = DoubleToBits(apf.convertToDouble()); + return DAG.getNode(ISD::BIT_CONVERT, VT, + LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG)); + } + + return SDOperand(); +} + +static SDOperand +LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex) +{ + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + SSARegMap *RegMap = MF.getSSARegMap(); + SmallVector ArgValues; + SDOperand Root = Op.getOperand(0); + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + + const unsigned *ArgRegs = SPURegisterInfo::getArgRegs(); + const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs(); + + unsigned ArgOffset = SPUFrameInfo::minStackSize(); + unsigned ArgRegIdx = 0; + unsigned StackSlotSize = SPUFrameInfo::stackSlotSize(); + + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + + // Add DAG nodes to load the arguments or copy them out of registers. + for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) { + SDOperand ArgVal; + bool needsLoad = false; + MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); + unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; + + switch (ObjectVT) { + default: { + cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + << MVT::getValueTypeString(ObjectVT) + << "\n"; + abort(); + } + case MVT::i8: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::R16CRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + case MVT::i16: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::R16CRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + case MVT::i32: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::R32CRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + case MVT::i64: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::R64CRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + case MVT::f32: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::R32FPRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + case MVT::f64: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::R64FPRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + case MVT::v2f64: + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + if (!isVarArg && ArgRegIdx < NumArgRegs) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT); + ++ArgRegIdx; + } else { + needsLoad = true; + } + break; + } + + // We need to load the argument to a virtual register if we determined above + // that we ran out of physical registers of the appropriate type + if (needsLoad) { + // If the argument is actually used, emit a load from the right stack + // slot. + if (!Op.Val->hasNUsesOfValue(0, ArgNo)) { + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, PtrVT); + ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0); + } else { + // Don't emit a dead load. + ArgVal = DAG.getNode(ISD::UNDEF, ObjectVT); + } + + ArgOffset += StackSlotSize; + } + + ArgValues.push_back(ArgVal); + } + + // If the function takes variable number of arguments, make a frame index for + // the start of the first vararg value... for expansion of llvm.va_start. + if (isVarArg) { + VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8, + ArgOffset); + SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); + // If this function is vararg, store any remaining integer argument regs to + // their spots on the stack so that they may be loaded by deferencing the + // result of va_next. + SmallVector MemOps; + for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) { + unsigned VReg = RegMap->createVirtualRegister(&SPU::GPRCRegClass); + MF.addLiveIn(ArgRegs[ArgRegIdx], VReg); + SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT); + SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0); + MemOps.push_back(Store); + // Increment the address by four for the next argument to store + SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT); + FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff); + } + if (!MemOps.empty()) + Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size()); + } + + ArgValues.push_back(Root); + + // Return the new list of results. + std::vector RetVT(Op.Val->value_begin(), + Op.Val->value_end()); + return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size()); +} + +/// isLSAAddress - Return the immediate to use if the specified +/// value is representable as a LSA address. +static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) { + ConstantSDNode *C = dyn_cast(Op); + if (!C) return 0; + + int Addr = C->getValue(); + if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero. + (Addr << 14 >> 14) != Addr) + return 0; // Top 14 bits have to be sext of immediate. + + return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val; +} + +static +SDOperand +LowerCALL(SDOperand Op, SelectionDAG &DAG) { + SDOperand Chain = Op.getOperand(0); +#if 0 + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; +#endif + SDOperand Callee = Op.getOperand(4); + unsigned NumOps = (Op.getNumOperands() - 5) / 2; + unsigned StackSlotSize = SPUFrameInfo::stackSlotSize(); + const unsigned *ArgRegs = SPURegisterInfo::getArgRegs(); + const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs(); + + // Handy pointer type + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + + // Accumulate how many bytes are to be pushed on the stack, including the + // linkage area, and parameter passing area. According to the SPU ABI, + // we minimally need space for [LR] and [SP] + unsigned NumStackBytes = SPUFrameInfo::minStackSize(); + + // Set up a copy of the stack pointer for use loading and storing any + // arguments that may not fit in the registers available for argument + // passing. + SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32); + + // Figure out which arguments are going to go in registers, and which in + // memory. + unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR] + unsigned ArgRegIdx = 0; + + // Keep track of registers passing arguments + std::vector > RegsToPass; + // And the arguments passed on the stack + SmallVector MemOpChains; + + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); + + // PtrOff will be used to store the current argument to the stack if a + // register cannot be found for it. + SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); + PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff); + + switch (Arg.getValueType()) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i32: + case MVT::i64: + case MVT::i128: + if (ArgRegIdx != NumArgRegs) { + RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg)); + } else { + MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + ArgOffset += StackSlotSize; + } + break; + case MVT::f32: + case MVT::f64: + if (ArgRegIdx != NumArgRegs) { + RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg)); + } else { + MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + ArgOffset += StackSlotSize; + } + break; + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + if (ArgRegIdx != NumArgRegs) { + RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg)); + } else { + MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + ArgOffset += StackSlotSize; + } + break; + } + } + + // Update number of stack bytes actually used, insert a call sequence start + NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize()); + Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT)); + + if (!MemOpChains.empty()) { + // Adjust the stack pointer for the stack arguments. + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, + &MemOpChains[0], MemOpChains.size()); + } + + // Build a sequence of copy-to-reg nodes chained together with token chain + // and flag operands which copy the outgoing args into the appropriate regs. + SDOperand InFlag; + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, + InFlag); + InFlag = Chain.getValue(1); + } + + std::vector NodeTys; + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + + SmallVector Ops; + unsigned CallOpc = SPUISD::CALL; + + // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every + // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol + // node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + GlobalValue *GV = G->getGlobal(); + unsigned CalleeVT = Callee.getValueType(); + + // Turn calls to targets that are defined (i.e., have bodies) into BRSL + // style calls, otherwise, external symbols are BRASL calls. + // NOTE: + // This may be an unsafe assumption for JIT and really large compilation + // units. + if (GV->isDeclaration()) { + Callee = DAG.getGlobalAddress(GV, CalleeVT); + } else { + Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, + DAG.getTargetGlobalAddress(GV, CalleeVT), + DAG.getConstant(0, PtrVT)); + } + } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType()); + else if (SDNode *Dest = isLSAAddress(Callee, DAG)) + // If this is an absolute destination address that appears to be a legal + // local store address, use the munged value. + Callee = SDOperand(Dest, 0); + + Ops.push_back(Chain); + Ops.push_back(Callee); + + // Add argument registers to the end of the list so that they are known live + // into the call. + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(RegsToPass[i].first, + RegsToPass[i].second.getValueType())); + + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size()); + InFlag = Chain.getValue(1); + + SDOperand ResultVals[3]; + unsigned NumResults = 0; + NodeTys.clear(); + + // If the call has results, copy the values out of the ret val registers. + switch (Op.Val->getValueType(0)) { + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: break; + case MVT::i32: + if (Op.Val->getValueType(1) == MVT::i32) { + Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1); + ResultVals[0] = Chain.getValue(0); + Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, + Chain.getValue(2)).getValue(1); + ResultVals[1] = Chain.getValue(0); + NumResults = 2; + NodeTys.push_back(MVT::i32); + } else { + Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1); + ResultVals[0] = Chain.getValue(0); + NumResults = 1; + } + NodeTys.push_back(MVT::i32); + break; + case MVT::i64: + Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1); + ResultVals[0] = Chain.getValue(0); + NumResults = 1; + NodeTys.push_back(MVT::i64); + break; + case MVT::f32: + case MVT::f64: + Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0), + InFlag).getValue(1); + ResultVals[0] = Chain.getValue(0); + NumResults = 1; + NodeTys.push_back(Op.Val->getValueType(0)); + break; + case MVT::v2f64: + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0), + InFlag).getValue(1); + ResultVals[0] = Chain.getValue(0); + NumResults = 1; + NodeTys.push_back(Op.Val->getValueType(0)); + break; + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(NumStackBytes, PtrVT)); + NodeTys.push_back(MVT::Other); + + // If the function returns void, just return the chain. + if (NumResults == 0) + return Chain; + + // Otherwise, merge everything together with a MERGE_VALUES node. + ResultVals[NumResults++] = Chain; + SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, + ResultVals, NumResults); + return Res.getValue(Op.ResNo); +} + +static SDOperand +LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) { + SmallVector RVLocs; + unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); + bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); + CCState CCInfo(CC, isVarArg, TM, RVLocs); + CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU); + + // If this is the first return lowered for this function, add the regs to the + // liveout set for the function. + if (DAG.getMachineFunction().liveout_empty()) { + for (unsigned i = 0; i != RVLocs.size(); ++i) + DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg()); + } + + SDOperand Chain = Op.getOperand(0); + SDOperand Flag; + + // Copy the result values into the output registers. + for (unsigned i = 0; i != RVLocs.size(); ++i) { + CCValAssign &VA = RVLocs[i]; + assert(VA.isRegLoc() && "Can only return in registers!"); + Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag); + Flag = Chain.getValue(1); + } + + if (Flag.Val) + return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag); + else + return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain); +} + + +//===----------------------------------------------------------------------===// +// Vector related lowering: +//===----------------------------------------------------------------------===// + +static ConstantSDNode * +getVecImm(SDNode *N) { + SDOperand OpVal(0, 0); + + // Check to see if this buildvec has a single non-undef value in its elements. + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue; + if (OpVal.Val == 0) + OpVal = N->getOperand(i); + else if (OpVal != N->getOperand(i)) + return 0; + } + + if (OpVal.Val != 0) { + if (ConstantSDNode *CN = dyn_cast(OpVal)) { + return CN; + } + } + + return 0; // All UNDEF: use implicit def.; not Constant node +} + +/// get_vec_i18imm - Test if this vector is a vector filled with the same value +/// and the value fits into an unsigned 18-bit constant, and if so, return the +/// constant +SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType) { + if (ConstantSDNode *CN = getVecImm(N)) { + uint64_t Value = CN->getValue(); + if (Value <= 0x3ffff) + return DAG.getConstant(Value, ValueType); + } + + return SDOperand(); +} + +/// get_vec_i16imm - Test if this vector is a vector filled with the same value +/// and the value fits into a signed 16-bit constant, and if so, return the +/// constant +SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType) { + if (ConstantSDNode *CN = getVecImm(N)) { + if (ValueType == MVT::i32) { + int Value = (int) CN->getValue(); + int SExtValue = ((Value & 0xffff) << 16) >> 16; + + if (Value == SExtValue) + return DAG.getConstant(Value, ValueType); + } else if (ValueType == MVT::i16) { + short Value = (short) CN->getValue(); + int SExtValue = ((int) Value << 16) >> 16; + + if (Value == (short) SExtValue) + return DAG.getConstant(Value, ValueType); + } else if (ValueType == MVT::i64) { + int64_t Value = CN->getValue(); + int64_t SExtValue = ((Value & 0xffff) << (64 - 16)) >> (64 - 16); + + if (Value == SExtValue) + return DAG.getConstant(Value, ValueType); + } + } + + return SDOperand(); +} + +/// get_vec_i10imm - Test if this vector is a vector filled with the same value +/// and the value fits into a signed 10-bit constant, and if so, return the +/// constant +SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType) { + if (ConstantSDNode *CN = getVecImm(N)) { + int Value = (int) CN->getValue(); + if ((ValueType == MVT::i32 && isS10Constant(Value)) + || (ValueType == MVT::i16 && isS10Constant((short) Value))) + return DAG.getConstant(Value, ValueType); + } + + return SDOperand(); +} + +/// get_vec_i8imm - Test if this vector is a vector filled with the same value +/// and the value fits into a signed 8-bit constant, and if so, return the +/// constant. +/// +/// @note: The incoming vector is v16i8 because that's the only way we can load +/// constant vectors. Thus, we test to see if the upper and lower bytes are the +/// same value. +SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType) { + if (ConstantSDNode *CN = getVecImm(N)) { + int Value = (int) CN->getValue(); + if (ValueType == MVT::i16 + && Value <= 0xffff /* truncated from uint64_t */ + && ((short) Value >> 8) == ((short) Value & 0xff)) + return DAG.getConstant(Value & 0xff, ValueType); + else if (ValueType == MVT::i8 + && (Value & 0xff) == Value) + return DAG.getConstant(Value, ValueType); + } + + return SDOperand(); +} + +/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value +/// and the value fits into a signed 16-bit constant, and if so, return the +/// constant +SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType) { + if (ConstantSDNode *CN = getVecImm(N)) { + uint64_t Value = CN->getValue(); + if ((ValueType == MVT::i32 + && ((unsigned) Value & 0xffff0000) == (unsigned) Value) + || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value)) + return DAG.getConstant(Value >> 16, ValueType); + } + + return SDOperand(); +} + +/// get_v4i32_imm - Catch-all for general 32-bit constant vectors +SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) { + if (ConstantSDNode *CN = getVecImm(N)) { + return DAG.getConstant((unsigned) CN->getValue(), MVT::i32); + } + + return SDOperand(); +} + +/// get_v4i32_imm - Catch-all for general 64-bit constant vectors +SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) { + if (ConstantSDNode *CN = getVecImm(N)) { + return DAG.getConstant((unsigned) CN->getValue(), MVT::i64); + } + + return SDOperand(); +} + +// If this is a vector of constants or undefs, get the bits. A bit in +// UndefBits is set if the corresponding element of the vector is an +// ISD::UNDEF value. For undefs, the corresponding VectorBits values are +// zero. Return true if this is not an array of constants, false if it is. +// +static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2], + uint64_t UndefBits[2]) { + // Start with zero'd results. + VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0; + + unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType()); + for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { + SDOperand OpVal = BV->getOperand(i); + + unsigned PartNo = i >= e/2; // In the upper 128 bits? + unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t. + + uint64_t EltBits = 0; + if (OpVal.getOpcode() == ISD::UNDEF) { + uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize); + UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize); + continue; + } else if (ConstantSDNode *CN = dyn_cast(OpVal)) { + EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize)); + } else if (ConstantFPSDNode *CN = dyn_cast(OpVal)) { + const APFloat &apf = CN->getValueAPF(); + EltBits = (CN->getValueType(0) == MVT::f32 + ? FloatToBits(apf.convertToFloat()) + : DoubleToBits(apf.convertToDouble())); + } else { + // Nonconstant element. + return true; + } + + VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize); + } + + //printf("%llx %llx %llx %llx\n", + // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]); + return false; +} + +/// If this is a splat (repetition) of a value across the whole vector, return +/// the smallest size that splats it. For example, "0x01010101010101..." is a +/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and +/// SplatSize = 1 byte. +static bool isConstantSplat(const uint64_t Bits128[2], + const uint64_t Undef128[2], + int MinSplatBits, + uint64_t &SplatBits, uint64_t &SplatUndef, + int &SplatSize) { + // Don't let undefs prevent splats from matching. See if the top 64-bits are + // the same as the lower 64-bits, ignoring undefs. + uint64_t Bits64 = Bits128[0] | Bits128[1]; + uint64_t Undef64 = Undef128[0] & Undef128[1]; + uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32); + uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32); + uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16); + uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16); + + if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) { + if (MinSplatBits < 64) { + + // Check that the top 32-bits are the same as the lower 32-bits, ignoring + // undefs. + if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) { + if (MinSplatBits < 32) { + + // If the top 16-bits are different than the lower 16-bits, ignoring + // undefs, we have an i32 splat. + if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) { + if (MinSplatBits < 16) { + // If the top 8-bits are different than the lower 8-bits, ignoring + // undefs, we have an i16 splat. + if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) { + // Otherwise, we have an 8-bit splat. + SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8); + SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8); + SplatSize = 1; + return true; + } + } else { + SplatBits = Bits16; + SplatUndef = Undef16; + SplatSize = 2; + return true; + } + } + } else { + SplatBits = Bits32; + SplatUndef = Undef32; + SplatSize = 4; + return true; + } + } + } else { + SplatBits = Bits128[0]; + SplatUndef = Undef128[0]; + SplatSize = 8; + return true; + } + } + + return false; // Can't be a splat if two pieces don't match. +} + +// If this is a case we can't handle, return null and let the default +// expansion code take care of it. If we CAN select this case, and if it +// selects to a single instruction, return Op. Otherwise, if we can codegen +// this case more efficiently than a constant pool load, lower it to the +// sequence of ops that should be used. +static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) { + MVT::ValueType VT = Op.getValueType(); + // If this is a vector of constants or undefs, get the bits. A bit in + // UndefBits is set if the corresponding element of the vector is an + // ISD::UNDEF value. For undefs, the corresponding VectorBits values are + // zero. + uint64_t VectorBits[2]; + uint64_t UndefBits[2]; + uint64_t SplatBits, SplatUndef; + int SplatSize; + if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits) + || !isConstantSplat(VectorBits, UndefBits, + MVT::getSizeInBits(MVT::getVectorElementType(VT)), + SplatBits, SplatUndef, SplatSize)) + return SDOperand(); // Not a constant vector, not a splat. + + switch (VT) { + default: + case MVT::v4f32: { + uint32_t Value32 = SplatBits; + assert(SplatSize == 4 + && "LowerBUILD_VECTOR: Unexpected floating point vector element."); + // NOTE: pretend the constant is an integer. LLVM won't load FP constants + SDOperand T = DAG.getConstant(Value32, MVT::i32); + return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T)); + break; + } + case MVT::v2f64: { + uint64_t f64val = SplatBits; + assert(SplatSize == 8 + && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size."); + // NOTE: pretend the constant is an integer. LLVM won't load FP constants + SDOperand T = DAG.getConstant(f64val, MVT::i64); + return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T)); + break; + } + case MVT::v16i8: { + // 8-bit constants have to be expanded to 16-bits + unsigned short Value16 = SplatBits | (SplatBits << 8); + SDOperand Ops[8]; + for (int i = 0; i < 8; ++i) + Ops[i] = DAG.getConstant(Value16, MVT::i16); + return DAG.getNode(ISD::BIT_CONVERT, VT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8)); + } + case MVT::v8i16: { + unsigned short Value16; + if (SplatSize == 2) + Value16 = (unsigned short) (SplatBits & 0xffff); + else + Value16 = (unsigned short) (SplatBits | (SplatBits << 8)); + SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT)); + SDOperand Ops[8]; + for (int i = 0; i < 8; ++i) Ops[i] = T; + return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8); + } + case MVT::v4i32: { + unsigned int Value = SplatBits; + SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT)); + return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T); + } + case MVT::v2i64: { + uint64_t val = SplatBits; + uint32_t upper = uint32_t(val >> 32); + uint32_t lower = uint32_t(val); + + if (val != 0) { + SDOperand LO32; + SDOperand HI32; + SmallVector ShufBytes; + SDOperand Result; + bool upper_special, lower_special; + + // NOTE: This code creates common-case shuffle masks that can be easily + // detected as common expressions. It is not attempting to create highly + // specialized masks to replace any and all 0's, 0xff's and 0x80's. + + // Detect if the upper or lower half is a special shuffle mask pattern: + upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000); + lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000); + + // Create lower vector if not a special pattern + if (!lower_special) { + SDOperand LO32C = DAG.getConstant(lower, MVT::i32); + LO32 = DAG.getNode(ISD::BIT_CONVERT, VT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + LO32C, LO32C, LO32C, LO32C)); + } + + // Create upper vector if not a special pattern + if (!upper_special) { + SDOperand HI32C = DAG.getConstant(upper, MVT::i32); + HI32 = DAG.getNode(ISD::BIT_CONVERT, VT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + HI32C, HI32C, HI32C, HI32C)); + } + + // If either upper or lower are special, then the two input operands are + // the same (basically, one of them is a "don't care") + if (lower_special) + LO32 = HI32; + if (upper_special) + HI32 = LO32; + if (lower_special && upper_special) { + // Unhappy situation... both upper and lower are special, so punt with + // a target constant: + SDOperand Zero = DAG.getConstant(0, MVT::i32); + HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero, + Zero, Zero); + } + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + SDOperand V; + bool process_upper, process_lower; + uint64_t val; + + process_upper = (upper_special && (i & 1) == 0); + process_lower = (lower_special && (i & 1) == 1); + + if (process_upper || process_lower) { + if ((process_upper && upper == 0) + || (process_lower && lower == 0)) + val = 0x80; + else if ((process_upper && upper == 0xffffffff) + || (process_lower && lower == 0xffffffff)) + val = 0xc0; + else if ((process_upper && upper == 0x80000000) + || (process_lower && lower == 0x80000000)) + val = (j == 0 ? 0xe0 : 0x80); + } else + val = i * 4 + j + ((i & 1) * 16); + + ShufBytes.push_back(DAG.getConstant(val, MVT::i8)); + } + } + + return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, + &ShufBytes[0], ShufBytes.size())); + } else { + // For zero, this can be lowered efficiently via v4i32 BUILD_VECTOR + SDOperand Zero = DAG.getConstant(0, MVT::i32); + return DAG.getNode(ISD::BIT_CONVERT, VT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + Zero, Zero, Zero, Zero)); + } + } + } + + return SDOperand(); +} + +/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on +/// which the Cell can operate. The code inspects V3 to ascertain whether the +/// permutation vector, V3, is monotonically increasing with one "exception" +/// element, e.g., (0, 1, _, 3). If this is the case, then generate a +/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool. +/// In either case, the net result is going to eventually invoke SHUFB to +/// permute/shuffle the bytes from V1 and V2. +/// \note +/// INSERT_MASK is eventually selected as one of the C*D instructions, generate +/// control word for byte/halfword/word insertion. This takes care of a single +/// element move from V2 into V1. +/// \note +/// SPUISD::SHUFB is eventually selected as Cell's shufb instructions. +static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { + SDOperand V1 = Op.getOperand(0); + SDOperand V2 = Op.getOperand(1); + SDOperand PermMask = Op.getOperand(2); + + if (V2.getOpcode() == ISD::UNDEF) V2 = V1; + + // If we have a single element being moved from V1 to V2, this can be handled + // using the C*[DX] compute mask instructions, but the vector elements have + // to be monotonically increasing with one exception element. + MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType()); + unsigned EltsFromV2 = 0; + unsigned V2Elt = 0; + unsigned V2EltIdx0 = 0; + unsigned CurrElt = 0; + bool monotonic = true; + if (EltVT == MVT::i8) + V2EltIdx0 = 16; + else if (EltVT == MVT::i16) + V2EltIdx0 = 8; + else if (EltVT == MVT::i32) + V2EltIdx0 = 4; + else + assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE"); + + for (unsigned i = 0, e = PermMask.getNumOperands(); + EltsFromV2 <= 1 && monotonic && i != e; + ++i) { + unsigned SrcElt; + if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF) + SrcElt = 0; + else + SrcElt = cast(PermMask.getOperand(i))->getValue(); + + if (SrcElt >= V2EltIdx0) { + ++EltsFromV2; + V2Elt = (V2EltIdx0 - SrcElt) << 2; + } else if (CurrElt != SrcElt) { + monotonic = false; + } + + ++CurrElt; + } + + if (EltsFromV2 == 1 && monotonic) { + // Compute mask and shuffle + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + unsigned VReg = RegMap->createVirtualRegister(&SPU::R32CRegClass); + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + // Initialize temporary register to 0 + SDOperand InitTempReg = + DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT)); + // Copy register's contents as index in INSERT_MASK: + SDOperand ShufMaskOp = + DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(), + DAG.getTargetConstant(V2Elt, MVT::i32), + DAG.getCopyFromReg(InitTempReg, VReg, PtrVT)); + // Use shuffle mask in SHUFB synthetic instruction: + return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp); + } else { + // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes. + unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8; + + SmallVector ResultMask; + for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) { + unsigned SrcElt; + if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF) + SrcElt = 0; + else + SrcElt = cast(PermMask.getOperand(i))->getValue(); + + for (unsigned j = 0; j != BytesPerElement; ++j) { + ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j, + MVT::i8)); + } + } + + SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, + &ResultMask[0], ResultMask.size()); + return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask); + } +} + +static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) { + SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar + + if (Op0.Val->getOpcode() == ISD::Constant) { + // For a constant, build the appropriate constant vector, which will + // eventually simplify to a vector register load. + + ConstantSDNode *CN = cast(Op0.Val); + SmallVector ConstVecValues; + MVT::ValueType VT; + size_t n_copies; + + // Create a constant vector: + switch (Op.getValueType()) { + default: assert(0 && "Unexpected constant value type in " + "LowerSCALAR_TO_VECTOR"); + case MVT::v16i8: n_copies = 16; VT = MVT::i8; break; + case MVT::v8i16: n_copies = 8; VT = MVT::i16; break; + case MVT::v4i32: n_copies = 4; VT = MVT::i32; break; + case MVT::v4f32: n_copies = 4; VT = MVT::f32; break; + case MVT::v2i64: n_copies = 2; VT = MVT::i64; break; + case MVT::v2f64: n_copies = 2; VT = MVT::f64; break; + } + + SDOperand CValue = DAG.getConstant(CN->getValue(), VT); + for (size_t j = 0; j < n_copies; ++j) + ConstVecValues.push_back(CValue); + + return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(), + &ConstVecValues[0], ConstVecValues.size()); + } else { + // Otherwise, copy the value from one register to another: + switch (Op0.getValueType()) { + default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR"); + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + case MVT::f32: + case MVT::f64: + return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0); + } + } + + return SDOperand(); +} + +static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) { + switch (Op.getValueType()) { + case MVT::v4i32: { + SDOperand rA = Op.getOperand(0); + SDOperand rB = Op.getOperand(1); + SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB); + SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA); + SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB); + SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1); + + return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2); + break; + } + + // Multiply two v8i16 vectors (pipeline friendly version): + // a) multiply lower halves, mask off upper 16-bit of 32-bit product + // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes) + // c) Use SELB to select upper and lower halves from the intermediate results + // + // NOTE: We really want to move the FSMBI to earlier to actually get the + // dual-issue. This code does manage to do this, even if it's a little on + // the wacky side + case MVT::v8i16: { + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + SDOperand Chain = Op.getOperand(0); + SDOperand rA = Op.getOperand(0); + SDOperand rB = Op.getOperand(1); + unsigned FSMBIreg = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + unsigned HiProdReg = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + + SDOperand FSMBOp = + DAG.getCopyToReg(Chain, FSMBIreg, + DAG.getNode(SPUISD::FSMBI, MVT::v8i16, + DAG.getConstant(0xcccc, MVT::i32))); + + SDOperand HHProd = + DAG.getCopyToReg(FSMBOp, HiProdReg, + DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB)); + + SDOperand HHProd_v4i32 = + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, + DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32)); + + return DAG.getNode(SPUISD::SELB, MVT::v8i16, + DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB), + DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), + DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, + HHProd_v4i32, + DAG.getConstant(16, MVT::i16))), + DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32)); + } + + // This M00sE is N at stI! (apologies to Monty Python) + // + // SPU doesn't know how to do any 8-bit multiplication, so the solution + // is to break it all apart, sign extend, and reassemble the various + // intermediate products. + case MVT::v16i8: { + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + SDOperand Chain = Op.getOperand(0); + SDOperand rA = Op.getOperand(0); + SDOperand rB = Op.getOperand(1); + SDOperand c8 = DAG.getConstant(8, MVT::i8); + SDOperand c16 = DAG.getConstant(16, MVT::i8); + + unsigned FSMBreg_2222 = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + unsigned LoProd_reg = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + unsigned HiProd_reg = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + + SDOperand LLProd = + DAG.getNode(SPUISD::MPY, MVT::v8i16, + DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA), + DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB)); + + SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8); + + SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8); + + SDOperand LHProd = + DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, + DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8); + + SDOperand FSMBdef_2222 = + DAG.getCopyToReg(Chain, FSMBreg_2222, + DAG.getNode(SPUISD::FSMBI, MVT::v8i16, + DAG.getConstant(0x2222, MVT::i32))); + + SDOperand FSMBuse_2222 = + DAG.getCopyFromReg(FSMBdef_2222, FSMBreg_2222, MVT::v4i32); + + SDOperand LoProd_1 = + DAG.getCopyToReg(Chain, LoProd_reg, + DAG.getNode(SPUISD::SELB, MVT::v8i16, LLProd, LHProd, + FSMBuse_2222)); + + SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32); + + SDOperand LoProd = + DAG.getNode(ISD::AND, MVT::v4i32, + DAG.getCopyFromReg(LoProd_1, LoProd_reg, MVT::v4i32), + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + LoProdMask, LoProdMask, + LoProdMask, LoProdMask)); + + SDOperand rAH = + DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16); + + SDOperand rBH = + DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16); + + SDOperand HLProd = + DAG.getNode(SPUISD::MPY, MVT::v8i16, + DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH), + DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH)); + + SDOperand HHProd_1 = + DAG.getNode(SPUISD::MPY, MVT::v8i16, + DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, + DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)), + DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, + DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8))); + + SDOperand HHProd = + DAG.getCopyToReg(Chain, HiProd_reg, + DAG.getNode(SPUISD::SELB, MVT::v8i16, + HLProd, + DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8), + FSMBuse_2222)); + + SDOperand HiProd = + DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, + DAG.getCopyFromReg(HHProd, HiProd_reg, MVT::v4i32), c16); + + return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8, + DAG.getNode(ISD::OR, MVT::v4i32, + LoProd, HiProd)); + } + + default: + cerr << "CellSPU: Unknown vector multiplication, got " + << MVT::getValueTypeString(Op.getValueType()) + << "\n"; + abort(); + /*NOTREACHED*/ + } + + return SDOperand(); +} + +static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) { + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + + SDOperand A = Op.getOperand(0); + SDOperand B = Op.getOperand(1); + unsigned VT = Op.getValueType(); + + unsigned VRegBR, VRegC; + + if (VT == MVT::f32) { + VRegBR = RegMap->createVirtualRegister(&SPU::R32FPRegClass); + VRegC = RegMap->createVirtualRegister(&SPU::R32FPRegClass); + } else { + VRegBR = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + VRegC = RegMap->createVirtualRegister(&SPU::VECREGRegClass); + } + // TODO: make sure we're feeding FPInterp the right arguments + // Right now: fi B, frest(B) + + // Computes BRcpl = + // (Floating Interpolate (FP Reciprocal Estimate B)) + SDOperand BRcpl = + DAG.getCopyToReg(DAG.getEntryNode(), VRegBR, + DAG.getNode(SPUISD::FPInterp, VT, B, + DAG.getNode(SPUISD::FPRecipEst, VT, B))); + + // Computes A * BRcpl and stores in a temporary register + SDOperand AxBRcpl = + DAG.getCopyToReg(BRcpl, VRegC, + DAG.getNode(ISD::FMUL, VT, A, + DAG.getCopyFromReg(BRcpl, VRegBR, VT))); + // What's the Chain variable do? It's magic! + // TODO: set Chain = Op(0).getEntryNode() + + return DAG.getNode(ISD::FADD, VT, + DAG.getCopyFromReg(AxBRcpl, VRegC, VT), + DAG.getNode(ISD::FMUL, VT, + DAG.getCopyFromReg(AxBRcpl, VRegBR, VT), + DAG.getNode(ISD::FSUB, VT, A, + DAG.getNode(ISD::FMUL, VT, B, + DAG.getCopyFromReg(AxBRcpl, VRegC, VT))))); +} + +// Expands double-precision FDIV +// Expects two doubles as inputs X and Y, does a floating point +// reciprocal estimate, and three iterations of Newton-Raphson +// to increase accuracy. +//static SDOperand LowerFDIVf64(SDOperand Op, SelectionDAG &DAG) { +// MachineFunction &MF = DAG.getMachineFunction(); +// SSARegMap *RegMap = MF.getSSARegMap(); +// +// SDOperand X = Op.getOperand(0); +// SDOperand Y = Op.getOperand(1); +//} + +static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) { + unsigned VT = Op.getValueType(); + SDOperand N = Op.getOperand(0); + SDOperand Elt = Op.getOperand(1); + SDOperand ShufMask[16]; + ConstantSDNode *C = dyn_cast(Elt); + + assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode"); + + int EltNo = (int) C->getValue(); + + // sanity checks: + if (VT == MVT::i8 && EltNo >= 16) + assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15"); + else if (VT == MVT::i16 && EltNo >= 8) + assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7"); + else if (VT == MVT::i32 && EltNo >= 4) + assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4"); + else if (VT == MVT::i64 && EltNo >= 2) + assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2"); + + if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) { + // i32 and i64: Element 0 is the preferred slot + return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N); + } + + // Need to generate shuffle mask and extract: + int prefslot_begin, prefslot_end; + int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8; + + switch (VT) { + case MVT::i8: { + prefslot_begin = prefslot_end = 3; + break; + } + case MVT::i16: { + prefslot_begin = 2; prefslot_end = 3; + break; + } + case MVT::i32: { + prefslot_begin = 0; prefslot_end = 3; + break; + } + case MVT::i64: { + prefslot_begin = 0; prefslot_end = 7; + break; + } + } + + for (int i = 0; i < 16; ++i) { + // zero fill uppper part of preferred slot, don't care about the + // other slots: + unsigned int mask_val; + + if (i <= prefslot_end) { + mask_val = + ((i < prefslot_begin) + ? 0x80 + : elt_byte + (i - prefslot_begin)); + + ShufMask[i] = DAG.getConstant(mask_val, MVT::i16); + } else + ShufMask[i] = ShufMask[i % (prefslot_end + 1)]; + } + + SDOperand ShufMaskVec = + DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, + &ShufMask[0], + sizeof(ShufMask) / sizeof(ShufMask[0])); + + return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, + DAG.getNode(SPUISD::SHUFB, N.getValueType(), + N, N, ShufMaskVec)); + +} + +static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) { + SDOperand VecOp = Op.getOperand(0); + SDOperand ValOp = Op.getOperand(1); + SDOperand IdxOp = Op.getOperand(2); + MVT::ValueType VT = Op.getValueType(); + + ConstantSDNode *CN = cast(IdxOp); + assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!"); + + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + // Use $2 because it's always 16-byte aligned and it's available: + SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT); + + SDOperand result = + DAG.getNode(SPUISD::SHUFB, VT, + DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp), + VecOp, + DAG.getNode(SPUISD::INSERT_MASK, VT, + DAG.getNode(ISD::ADD, PtrVT, + PtrBase, + DAG.getConstant(CN->getValue(), + PtrVT)))); + + return result; +} + +static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc) { + SDOperand N0 = Op.getOperand(0); // Everything has at least one operand + + assert(Op.getValueType() == MVT::i8); + switch (Opc) { + default: + assert(0 && "Unhandled i8 math operator"); + /*NOTREACHED*/ + break; + case ISD::SUB: { + // 8-bit subtraction: Promote the arguments up to 16-bits and truncate + // the result: + SDOperand N1 = Op.getOperand(1); + N0 = (N0.getOpcode() != ISD::Constant + ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0) + : DAG.getConstant(cast(N0)->getValue(), MVT::i16)); + N1 = (N1.getOpcode() != ISD::Constant + ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1) + : DAG.getConstant(cast(N1)->getValue(), MVT::i16)); + return DAG.getNode(ISD::TRUNCATE, MVT::i8, + DAG.getNode(Opc, MVT::i16, N0, N1)); + } + case ISD::ROTR: + case ISD::ROTL: { + SDOperand N1 = Op.getOperand(1); + unsigned N1Opc; + N0 = (N0.getOpcode() != ISD::Constant + ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0) + : DAG.getConstant(cast(N0)->getValue(), MVT::i16)); + N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE); + N1 = (N1.getOpcode() != ISD::Constant + ? DAG.getNode(N1Opc, MVT::i16, N1) + : DAG.getConstant(cast(N1)->getValue(), MVT::i16)); + SDOperand ExpandArg = + DAG.getNode(ISD::OR, MVT::i16, N0, + DAG.getNode(ISD::SHL, MVT::i16, + N0, DAG.getConstant(8, MVT::i16))); + return DAG.getNode(ISD::TRUNCATE, MVT::i8, + DAG.getNode(Opc, MVT::i16, ExpandArg, N1)); + } + case ISD::SRL: + case ISD::SHL: { + SDOperand N1 = Op.getOperand(1); + unsigned N1Opc; + N0 = (N0.getOpcode() != ISD::Constant + ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0) + : DAG.getConstant(cast(N0)->getValue(), MVT::i16)); + N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE); + N1 = (N1.getOpcode() != ISD::Constant + ? DAG.getNode(N1Opc, MVT::i16, N1) + : DAG.getConstant(cast(N1)->getValue(), MVT::i16)); + return DAG.getNode(ISD::TRUNCATE, MVT::i8, + DAG.getNode(Opc, MVT::i16, N0, N1)); + } + case ISD::SRA: { + SDOperand N1 = Op.getOperand(1); + unsigned N1Opc; + N0 = (N0.getOpcode() != ISD::Constant + ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0) + : DAG.getConstant(cast(N0)->getValue(), MVT::i16)); + N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE); + N1 = (N1.getOpcode() != ISD::Constant + ? DAG.getNode(N1Opc, MVT::i16, N1) + : DAG.getConstant(cast(N1)->getValue(), MVT::i16)); + return DAG.getNode(ISD::TRUNCATE, MVT::i8, + DAG.getNode(Opc, MVT::i16, N0, N1)); + } + case ISD::MUL: { + SDOperand N1 = Op.getOperand(1); + unsigned N1Opc; + N0 = (N0.getOpcode() != ISD::Constant + ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0) + : DAG.getConstant(cast(N0)->getValue(), MVT::i16)); + N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE); + N1 = (N1.getOpcode() != ISD::Constant + ? DAG.getNode(N1Opc, MVT::i16, N1) + : DAG.getConstant(cast(N1)->getValue(), MVT::i16)); + return DAG.getNode(ISD::TRUNCATE, MVT::i8, + DAG.getNode(Opc, MVT::i16, N0, N1)); + break; + } + } + + return SDOperand(); +} + +//! Lower byte immediate operations for v16i8 vectors: +static SDOperand +LowerByteImmed(SDOperand Op, SelectionDAG &DAG) { + SDOperand ConstVec; + SDOperand Arg; + MVT::ValueType VT = Op.getValueType(); + + ConstVec = Op.getOperand(0); + Arg = Op.getOperand(1); + if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) { + if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) { + ConstVec = ConstVec.getOperand(0); + } else { + ConstVec = Op.getOperand(1); + Arg = Op.getOperand(0); + if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) { + ConstVec = ConstVec.getOperand(0); + } + } + } + + if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) { + uint64_t VectorBits[2]; + uint64_t UndefBits[2]; + uint64_t SplatBits, SplatUndef; + int SplatSize; + + if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits) + && isConstantSplat(VectorBits, UndefBits, + MVT::getSizeInBits(MVT::getVectorElementType(VT)), + SplatBits, SplatUndef, SplatSize)) { + SDOperand tcVec[16]; + SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8); + const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]); + + // Turn the BUILD_VECTOR into a set of target constants: + for (size_t i = 0; i < tcVecSize; ++i) + tcVec[i] = tc; + + return DAG.getNode(Op.Val->getOpcode(), VT, Arg, + DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize)); + } + } + + return SDOperand(); +} + +//! Lower i32 multiplication +static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT, + unsigned Opc) { + switch (VT) { + default: + cerr << "CellSPU: Unknown LowerMUL value type, got " + << MVT::getValueTypeString(Op.getValueType()) + << "\n"; + abort(); + /*NOTREACHED*/ + + case MVT::i32: { + SDOperand rA = Op.getOperand(0); + SDOperand rB = Op.getOperand(1); + + return DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB), + DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)), + DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB)); + } + } + + return SDOperand(); +} + +//! Custom lowering for CTPOP (count population) +/*! + Custom lowering code that counts the number ones in the input + operand. SPU has such an instruction, but it counts the number of + ones per byte, which then have to be accumulated. +*/ +static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) { + unsigned VT = Op.getValueType(); + unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT))); + + switch (VT) { + case MVT::i8: { + SDOperand N = Op.getOperand(0); + SDOperand Elt0 = DAG.getConstant(0, MVT::i32); + + SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N); + SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote); + + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0); + } + + case MVT::i16: { + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + + unsigned CNTB_reg = RegMap->createVirtualRegister(&SPU::R16CRegClass); + + SDOperand N = Op.getOperand(0); + SDOperand Elt0 = DAG.getConstant(0, MVT::i16); + SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16); + SDOperand Shift1 = DAG.getConstant(8, MVT::i16); + + SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N); + SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote); + + // CNTB_result becomes the chain to which all of the virtual registers + // CNTB_reg, SUM1_reg become associated: + SDOperand CNTB_result = + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0); + + SDOperand CNTB_rescopy = + DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result); + + SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16); + + return DAG.getNode(ISD::AND, MVT::i16, + DAG.getNode(ISD::ADD, MVT::i16, + DAG.getNode(ISD::SRL, MVT::i16, + Tmp1, Shift1), + Tmp1), + Mask0); + } + + case MVT::i32: { + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + + unsigned CNTB_reg = RegMap->createVirtualRegister(&SPU::R32CRegClass); + unsigned SUM1_reg = RegMap->createVirtualRegister(&SPU::R32CRegClass); + + SDOperand N = Op.getOperand(0); + SDOperand Elt0 = DAG.getConstant(0, MVT::i32); + SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32); + SDOperand Shift1 = DAG.getConstant(16, MVT::i32); + SDOperand Shift2 = DAG.getConstant(8, MVT::i32); + + SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N); + SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote); + + // CNTB_result becomes the chain to which all of the virtual registers + // CNTB_reg, SUM1_reg become associated: + SDOperand CNTB_result = + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0); + + SDOperand CNTB_rescopy = + DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result); + + SDOperand Comp1 = + DAG.getNode(ISD::SRL, MVT::i32, + DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1); + + SDOperand Sum1 = + DAG.getNode(ISD::ADD, MVT::i32, + Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32)); + + SDOperand Sum1_rescopy = + DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1); + + SDOperand Comp2 = + DAG.getNode(ISD::SRL, MVT::i32, + DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32), + Shift2); + SDOperand Sum2 = + DAG.getNode(ISD::ADD, MVT::i32, Comp2, + DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32)); + + return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0); + } + + case MVT::i64: + break; + } + + return SDOperand(); +} + +/// LowerOperation - Provide custom lowering hooks for some operations. +/// +SDOperand +SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) +{ + switch (Op.getOpcode()) { + default: { + cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n"; + cerr << "Op.getOpcode() = " << Op.getOpcode() << "\n"; + cerr << "*Op.Val:\n"; + Op.Val->dump(); + abort(); + } + case ISD::LOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: + return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl()); + case ISD::STORE: + return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl()); + case ISD::ConstantPool: + return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl()); + case ISD::GlobalAddress: + return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl()); + case ISD::JumpTable: + return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl()); + case ISD::Constant: + return LowerConstant(Op, DAG); + case ISD::ConstantFP: + return LowerConstantFP(Op, DAG); + case ISD::FORMAL_ARGUMENTS: + return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); + case ISD::CALL: + return LowerCALL(Op, DAG); + case ISD::RET: + return LowerRET(Op, DAG, getTargetMachine()); + + // i8 math ops: + case ISD::SUB: + case ISD::ROTR: + case ISD::ROTL: + case ISD::SRL: + case ISD::SHL: + case ISD::SRA: + return LowerI8Math(Op, DAG, Op.getOpcode()); + + // Vector-related lowering. + case ISD::BUILD_VECTOR: + return LowerBUILD_VECTOR(Op, DAG); + case ISD::SCALAR_TO_VECTOR: + return LowerSCALAR_TO_VECTOR(Op, DAG); + case ISD::VECTOR_SHUFFLE: + return LowerVECTOR_SHUFFLE(Op, DAG); + case ISD::EXTRACT_VECTOR_ELT: + return LowerEXTRACT_VECTOR_ELT(Op, DAG); + case ISD::INSERT_VECTOR_ELT: + return LowerINSERT_VECTOR_ELT(Op, DAG); + + // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately: + case ISD::AND: + case ISD::OR: + case ISD::XOR: + return LowerByteImmed(Op, DAG); + + // Vector and i8 multiply: + case ISD::MUL: + if (MVT::isVector(Op.getValueType())) + return LowerVectorMUL(Op, DAG); + else if (Op.getValueType() == MVT::i8) + return LowerI8Math(Op, DAG, Op.getOpcode()); + else + return LowerMUL(Op, DAG, Op.getValueType(), Op.getOpcode()); + + case ISD::FDIV: + if (Op.getValueType() == MVT::f32 || Op.getValueType() == MVT::v4f32) + return LowerFDIVf32(Op, DAG); +// else if (Op.getValueType() == MVT::f64) +// return LowerFDIVf64(Op, DAG); + else + assert(0 && "Calling FDIV on unsupported MVT"); + + case ISD::CTPOP: + return LowerCTPOP(Op, DAG); + } + + return SDOperand(); +} + +//===----------------------------------------------------------------------===// +// Other Lowering Code +//===----------------------------------------------------------------------===// + +MachineBasicBlock * +SPUTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *BB) +{ + return BB; +} + +//===----------------------------------------------------------------------===// +// Target Optimization Hooks +//===----------------------------------------------------------------------===// + +SDOperand +SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const +{ +#if 0 + TargetMachine &TM = getTargetMachine(); + SelectionDAG &DAG = DCI.DAG; +#endif + SDOperand N0 = N->getOperand(0); // everything has at least one operand + + switch (N->getOpcode()) { + default: break; + + // Look for obvious optimizations for shift left: + // a) Replace 0 << V with 0 + // b) Replace V << 0 with V + // + // N.B: llvm will generate an undef node if the shift amount is greater than + // 15 (e.g.: V << 16), which will naturally trigger an assert. + case SPU::SHLIr32: + case SPU::SHLHIr16: + case SPU::SHLQBIIvec: + case SPU::ROTHIr16: + case SPU::ROTHIr16_i32: + case SPU::ROTIr32: + case SPU::ROTIr32_i16: + case SPU::ROTQBYIvec: + case SPU::ROTQBYBIvec: + case SPU::ROTQBIIvec: + case SPU::ROTHMIr16: + case SPU::ROTMIr32: + case SPU::ROTQMBYIvec: { + if (N0.getOpcode() == ISD::Constant) { + if (ConstantSDNode *C = cast(N0)) { + if (C->getValue() == 0) // 0 << V -> 0. + return N0; + } + } + SDOperand N1 = N->getOperand(1); + if (N1.getOpcode() == ISD::Constant) { + if (ConstantSDNode *C = cast(N1)) { + if (C->getValue() == 0) // V << 0 -> V + return N1; + } + } + break; + } + } + + return SDOperand(); +} + +//===----------------------------------------------------------------------===// +// Inline Assembly Support +//===----------------------------------------------------------------------===// + +/// getConstraintType - Given a constraint letter, return the type of +/// constraint it is for this target. +SPUTargetLowering::ConstraintType +SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const { + if (ConstraintLetter.size() == 1) { + switch (ConstraintLetter[0]) { + default: break; + case 'b': + case 'r': + case 'f': + case 'v': + case 'y': + return C_RegisterClass; + } + } + return TargetLowering::getConstraintType(ConstraintLetter); +} + +std::pair +SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const +{ + if (Constraint.size() == 1) { + // GCC RS6000 Constraint Letters + switch (Constraint[0]) { + case 'b': // R1-R31 + case 'r': // R0-R31 + if (VT == MVT::i64) + return std::make_pair(0U, SPU::R64CRegisterClass); + return std::make_pair(0U, SPU::R32CRegisterClass); + case 'f': + if (VT == MVT::f32) + return std::make_pair(0U, SPU::R32FPRegisterClass); + else if (VT == MVT::f64) + return std::make_pair(0U, SPU::R64FPRegisterClass); + break; + case 'v': + return std::make_pair(0U, SPU::GPRCRegisterClass); + } + } + + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); +} + +void +SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, + uint64_t Mask, + uint64_t &KnownZero, + uint64_t &KnownOne, + const SelectionDAG &DAG, + unsigned Depth ) const { + KnownZero = 0; + KnownOne = 0; +} + +// LowerAsmOperandForConstraint +void +SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG) { + // Default, for the time being, to the base class handler + TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG); +} + +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode. +bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const { + // SPU's addresses are 256K: + return (V > -(1 << 18) && V < (1 << 18) - 1); +} + +bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const { + return false; +} Added: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Tue Dec 4 16:23:35 2007 @@ -0,0 +1,139 @@ +//===-- SPUISelLowering.h - Cell SPU DAG Lowering Interface -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that Cell SPU uses to lower LLVM code into +// a selection DAG. +// +//===----------------------------------------------------------------------===// + +#ifndef SPU_ISELLOWERING_H +#define SPU_ISELLOWERING_H + +#include "llvm/Target/TargetLowering.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "SPU.h" + +namespace llvm { + namespace SPUISD { + enum NodeType { + // Start the numbering where the builting ops and target ops leave off. + FIRST_NUMBER = ISD::BUILTIN_OP_END+SPU::INSTRUCTION_LIST_END, + + // Pseudo instructions: + RET_FLAG, ///< Return with flag, matched by bi instruction + + Hi, ///< High address component (upper 16) + Lo, ///< Low address component (lower 16) + PCRelAddr, ///< Program counter relative address + DFormAddr, ///< D-Form address "imm($r)" + XFormAddr, ///< X-Form address "$r1($r2)" + + LDRESULT, ///< Load result (value, chain) + CALL, ///< CALL instruction + SHUFB, ///< Vector shuffle (permute) + INSERT_MASK, ///< Insert element shuffle mask + CNTB, ///< Count leading ones in bytes + PROMOTE_SCALAR, ///< Promote scalar->vector + EXTRACT_ELT0, ///< Extract element 0 + EXTRACT_ELT0_CHAINED, ///< Extract element 0, with chain + EXTRACT_I1_ZEXT, ///< Extract element 0 as i1, zero extend + EXTRACT_I1_SEXT, ///< Extract element 0 as i1, sign extend + EXTRACT_I8_ZEXT, ///< Extract element 0 as i8, zero extend + EXTRACT_I8_SEXT, ///< Extract element 0 as i8, sign extend + MPY, ///< 16-bit Multiply (low parts of a 32-bit) + MPYU, ///< Multiply Unsigned + MPYH, ///< Multiply High + MPYHH, ///< Multiply High-High + VEC_SHL, ///< Vector shift left + VEC_SRL, ///< Vector shift right (logical) + VEC_SRA, ///< Vector shift right (arithmetic) + VEC_ROTL, ///< Vector rotate left + VEC_ROTR, ///< Vector rotate right + ROTBYTES_RIGHT_Z, ///< Vector rotate right, by bytes, zero fill + ROTBYTES_RIGHT_S, ///< Vector rotate right, by bytes, sign fill + ROTBYTES_LEFT, ///< Rotate bytes (loads -> ROTQBYI) + ROTBYTES_LEFT_CHAINED, ///< Rotate bytes (loads -> ROTQBYI), with chain + FSMBI, ///< Form Select Mask for Bytes, Immediate + SELB, ///< Select bits -> (b & mask) | (a & ~mask) + SFPConstant, ///< Single precision floating point constant + FPInterp, ///< Floating point interpolate + FPRecipEst, ///< Floating point reciprocal estimate + SEXT32TO64, ///< Sign-extended 32-bit const -> 64-bits + LAST_SPUISD ///< Last user-defined instruction + }; + } + + /// Predicates that are used for node matching: + namespace SPU { + SDOperand get_vec_u18imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType); + SDOperand get_vec_i16imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType); + SDOperand get_vec_i10imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType); + SDOperand get_vec_i8imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType); + SDOperand get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG, + MVT::ValueType ValueType); + SDOperand get_v4i32_imm(SDNode *N, SelectionDAG &DAG); + SDOperand get_v2i64_imm(SDNode *N, SelectionDAG &DAG); + } + + class SPUTargetMachine; // forward dec'l. + + class SPUTargetLowering : + public TargetLowering + { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int ReturnAddrIndex; // FrameIndex for return slot. + SPUTargetMachine &SPUTM; + + public: + SPUTargetLowering(SPUTargetMachine &TM); + + /// getTargetNodeName() - This method returns the name of a target specific + /// DAG node. + virtual const char *getTargetNodeName(unsigned Opcode) const; + + /// LowerOperation - Provide custom lowering hooks for some operations. + /// + virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + + virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + + virtual void computeMaskedBitsForTargetNode(const SDOperand Op, + uint64_t Mask, + uint64_t &KnownZero, + uint64_t &KnownOne, + const SelectionDAG &DAG, + unsigned Depth = 0) const; + + virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *MBB); + + ConstraintType getConstraintType(const std::string &ConstraintLetter) const; + + std::pair + getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; + + void LowerAsmOperandForConstraint(SDOperand Op, char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); + + /// isLegalAddressImmediate - Return true if the integer value can be used + /// as the offset of the target addressing mode. + virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; + virtual bool isLegalAddressImmediate(GlobalValue *) const; + }; +} + +#endif Added: llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h Tue Dec 4 16:23:35 2007 @@ -0,0 +1,52 @@ +//==-- SPUInstrBuilder.h - Aides for building Cell SPU insts -----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +//===----------------------------------------------------------------------===// +// +// This file exposes functions that may be used with BuildMI from the +// MachineInstrBuilder.h file to simplify generating frame and constant pool +// references. +// +// For reference, the order of operands for memory references is: +// (Operand), Dest Reg, Base Reg, and either Reg Index or Immediate +// Displacement. +// +//===----------------------------------------------------------------------===// + +#ifndef SPU_INSTRBUILDER_H +#define SPU_INSTRBUILDER_H + +#include "llvm/CodeGen/MachineInstrBuilder.h" + +namespace llvm { + +/// addFrameReference - This function is used to add a reference to the base of +/// an abstract object on the stack frame of the current function. This +/// reference has base register as the FrameIndex offset until it is resolved. +/// This allows a constant offset to be specified as well... +/// +inline const MachineInstrBuilder& +addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0, + bool mem = true) { + if (mem) + return MIB.addImm(Offset).addFrameIndex(FI); + else + return MIB.addFrameIndex(FI).addImm(Offset); +} + +/// addConstantPoolReference - This function is used to add a reference to the +/// base of a constant value spilled to the per-function constant pool. The +/// reference has base register ConstantPoolIndex offset which is retained until +/// either machine code emission or assembly output. This allows an optional +/// offset to be added as well. +/// +inline const MachineInstrBuilder& +addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, + int Offset = 0) { + return MIB.addImm(Offset).addConstantPoolIndex(CPI); +} + +} // End llvm namespace + +#endif Added: llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td?rev=44582&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td Tue Dec 4 16:23:35 2007 @@ -0,0 +1,308 @@ +//==== SPUInstrFormats.td - Cell SPU Instruction Formats ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by The Aerospace Corporation.... +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// +// Cell SPU instruction formats. Note that these are notationally similar to +// PowerPC, like "A-Form". But the sizes of operands and fields differ. + +// This was kiped from the PPC instruction formats (seemed like a good idea...) + +class I + : Instruction { + field bits<32> Inst; + + let Name = ""; + let Namespace = "SPU"; + let OutOperandList = OOL; + let InOperandList = IOL; + let AsmString = asmstr; + let Itinerary = itin; +} + +// RR Format +class RRForm opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I { + bits<7> RA; + bits<7> RB; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-10} = opcode; + let Inst{11-17} = RB; + let Inst{18-24} = RA; + let Inst{25-31} = RT; +} + +let RB = 0 in { + // RR Format, where RB is zeroed (dont care): + class RRForm_1 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : RRForm + { } + + let RA = 0 in { + // RR Format, where RA and RB are zeroed (dont care): + // Used for reads from status control registers (see FPSCRRr32) + class RRForm_2 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : RRForm + { } + } +} + +let RT = 0 in { + // RR Format, where RT is zeroed (don't care), or as the instruction handbook + // says, "RT is a false target." Used in "Halt if" instructions + class RRForm_3 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : RRForm + { } +} + +// RRR Format +class RRRForm opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<7> RA; + bits<7> RB; + bits<7> RC; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-3} = opcode; + let Inst{4-10} = RT; + let Inst{11-17} = RB; + let Inst{18-24} = RA; + let Inst{25-31} = RC; +} + +// RI7 Format +class RI7Form opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<7> i7; + bits<7> RA; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-10} = opcode; + let Inst{11-17} = i7; + let Inst{18-24} = RA; + let Inst{25-31} = RT; +} + +// CVTIntFp Format +class CVTIntFPForm opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<7> RA; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-9} = opcode; + let Inst{10-17} = 0; + let Inst{18-24} = RA; + let Inst{25-31} = RT; +} + +let RA = 0 in { + class BICondForm opcode, string asmstr, list pattern> + : RRForm + { } + + let RT = 0 in { + // Branch instruction format (without D/E flag settings) + class BRForm opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : RRForm + { } + + class BIForm opcode, string asmstr, list pattern> + : RRForm + { } + + let RB = 0 in { + // Return instruction (bi, branch indirect), RA is zero (LR): + class RETForm pattern> + : BRForm<0b00010101100, (outs), (ins), asmstr, BranchResolv, + pattern> + { } + } + } +} + +// Branch indirect external data forms: +class BISLEDForm DE_flag, string asmstr, list pattern> + : I<(outs), (ins indcalltarget:$func), asmstr, BranchResolv> +{ + bits<7> Rcalldest; + + let Pattern = pattern; + + let Inst{0-10} = 0b11010101100; + let Inst{11} = 0; + let Inst{12-13} = DE_flag; + let Inst{14-17} = 0b0000; + let Inst{18-24} = Rcalldest; + let Inst{25-31} = 0b0000000; +} + +// RI10 Format +class RI10Form opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<10> i10; + bits<7> RA; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-7} = opcode; + let Inst{8-17} = i10; + let Inst{18-24} = RA; + let Inst{25-31} = RT; +} + +// RI10 Format, where the constant is zero (or effectively ignored by the +// SPU) +class RI10Form_1 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<7> RA; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-7} = opcode; + let Inst{8-17} = 0; + let Inst{18-24} = RA; + let Inst{25-31} = RT; +} + +// RI10 Format, where RT is ignored. +// This format is used primarily by the Halt If ... Immediate set of +// instructions +class RI10Form_2 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<10> i10; + bits<7> RA; + + let Pattern = pattern; + + let Inst{0-7} = opcode; + let Inst{8-17} = i10; + let Inst{18-24} = RA; + let Inst{25-31} = 0; +} + +// RI16 Format +class RI16Form opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<16> i16; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-8} = opcode; + let Inst{9-24} = i16; + let Inst{25-31} = RT; +} + +// Specialized version of the RI16 Format for unconditional branch relative and +// branch absolute, branch and set link. Note that for branch and set link, the +// link register doesn't have to be $lr, but this is actually hard coded into +// the instruction pattern. + +let RT = 0 in { + class UncondBranch opcode, dag OOL, dag IOL, string asmstr, + list pattern> + : RI16Form + { } + + class BranchSetLink opcode, dag OOL, dag IOL, string asmstr, + list pattern> + : RI16Form + { } +} + +// RI18 Format +class RI18Form opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I +{ + bits<18> i18; + bits<7> RT; + + let Pattern = pattern; + + let Inst{0-6} = opcode; + let Inst{7-24} = i18; + let Inst{25-31} = RT; +} + +//===----------------------------------------------------------------------===// +// Instruction formats for intrinsics: +//===----------------------------------------------------------------------===// + +// RI10 Format for v8i16 intrinsics +class RI10_Int_v8i16 opcode, string opc, InstrItinClass itin, + Intrinsic IntID> : + RI10Form; + +class RI10_Int_v4i32 opcode, string opc, InstrItinClass itin, + Intrinsic IntID> : + RI10Form; + +// RR Format for v8i16 intrinsics +class RR_Int_v8i16 opcode, string opc, InstrItinClass itin, + Intrinsic IntID> : + RRForm; + +// RR Format for v4i32 intrinsics +class RR_Int_v4i32 opcode, string opc, InstrItinClass itin, + Intrinsic IntID> : + RRForm; + +//===----------------------------------------------------------------------===// +// Pseudo instructions, like call frames: +//===----------------------------------------------------------------------===// + +class Pseudo pattern> + : I { + let Pattern = pattern; + let Inst{31-0} = 0; +} From scottm at aero.org Tue Dec 4 16:35:59 2007 From: scottm at aero.org (Scott Michel) Date: Tue, 04 Dec 2007 22:35:59 -0000 Subject: [llvm-commits] [llvm] r44584 - in /llvm/trunk/lib/Target/CellSPU: SPUInstrInfo.cpp SPUInstrInfo.h SPUInstrInfo.td Message-ID: <200712042235.lB4MZxhb032295@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 16:35:58 2007 New Revision: 44584 URL: http://llvm.org/viewvc/llvm-project?rev=44584&view=rev Log: More files in the CellSPU drop... Added: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Added: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=44584&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Tue Dec 4 16:35:58 2007 @@ -0,0 +1,184 @@ +//===- SPUInstrInfo.cpp - Cell SPU Instruction Information ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the Cell SPU implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#include "SPURegisterNames.h" +#include "SPUInstrInfo.h" +#include "SPUTargetMachine.h" +#include "SPUGenInstrInfo.inc" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include + +using namespace llvm; + +SPUInstrInfo::SPUInstrInfo(SPUTargetMachine &tm) + : TargetInstrInfo(SPUInsts, sizeof(SPUInsts)/sizeof(SPUInsts[0])), + TM(tm), + RI(*TM.getSubtargetImpl(), *this) +{ + /* NOP */ +} + +/// getPointerRegClass - Return the register class to use to hold pointers. +/// This is used for addressing modes. +const TargetRegisterClass * +SPUInstrInfo::getPointerRegClass() const +{ + return &SPU::R32CRegClass; +} + +bool +SPUInstrInfo::isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const { + // Primarily, ORI and OR are generated by copyRegToReg. But, there are other + // cases where we can safely say that what's being done is really a move + // (see how PowerPC does this -- it's the model for this code too.) + switch (MI.getOpcode()) { + default: + break; + case SPU::ORIv4i32: + case SPU::ORIr32: + case SPU::ORIf64: + case SPU::ORIf32: + case SPU::ORIr64: + case SPU::ORHIv8i16: + case SPU::ORHIr16: + // case SPU::ORHI1To2: + case SPU::ORBIv16i8: + //case SPU::ORBIr8: + case SPU::ORI2To4: + // case SPU::ORI1To4: + case SPU::AHIvec: + case SPU::AHIr16: + case SPU::AIvec: + case SPU::AIr32: + assert(MI.getNumOperands() == 3 && + MI.getOperand(0).isRegister() && + MI.getOperand(1).isRegister() && + MI.getOperand(2).isImmediate() && + "invalid SPU ORI/ORHI/ORBI/AHI/AI/SFI/SFHI instruction!"); + if (MI.getOperand(2).getImmedValue() == 0) { + sourceReg = MI.getOperand(1).getReg(); + destReg = MI.getOperand(0).getReg(); + return true; + } + break; +#if 0 + case SPU::ORIf64: + case SPU::ORIf32: + // Special case because there's no third immediate operand to the + // instruction (the constant is embedded in the instruction) + assert(MI.getOperand(0).isRegister() && + MI.getOperand(1).isRegister() && + "ORIf32/f64: operands not registers"); + sourceReg = MI.getOperand(1).getReg(); + destReg = MI.getOperand(0).getReg(); + return true; +#endif + // case SPU::ORv16i8_i8: + case SPU::ORv8i16_i16: + case SPU::ORv4i32_i32: + case SPU::ORv2i64_i64: + case SPU::ORv4f32_f32: + case SPU::ORv2f64_f64: + // case SPU::ORi8_v16i8: + case SPU::ORi16_v8i16: + case SPU::ORi32_v4i32: + case SPU::ORi64_v2i64: + case SPU::ORf32_v4f32: + case SPU::ORf64_v2f64: + case SPU::ORv16i8: + case SPU::ORv8i16: + case SPU::ORv4i32: + case SPU::ORr32: + case SPU::ORr64: + case SPU::ORgprc: + assert(MI.getNumOperands() == 3 && + MI.getOperand(0).isRegister() && + MI.getOperand(1).isRegister() && + MI.getOperand(2).isRegister() && + "invalid SPU OR(vec|r32|r64|gprc) instruction!"); + if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { + sourceReg = MI.getOperand(1).getReg(); + destReg = MI.getOperand(0).getReg(); + return true; + } + break; + } + + return false; +} + +unsigned +SPUInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case SPU::LQDv16i8: + case SPU::LQDv8i16: + case SPU::LQDv4i32: + case SPU::LQDv4f32: + case SPU::LQDv2f64: + case SPU::LQDr128: + case SPU::LQDr64: + case SPU::LQDr32: + case SPU::LQDr16: + case SPU::LQXv4i32: + case SPU::LQXr128: + case SPU::LQXr64: + case SPU::LQXr32: + case SPU::LQXr16: + if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && + MI->getOperand(2).isFrameIndex()) { + FrameIndex = MI->getOperand(2).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} + +unsigned +SPUInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case SPU::STQDv16i8: + case SPU::STQDv8i16: + case SPU::STQDv4i32: + case SPU::STQDv4f32: + case SPU::STQDv2f64: + case SPU::STQDr128: + case SPU::STQDr64: + case SPU::STQDr32: + case SPU::STQDr16: + // case SPU::STQDr8: + case SPU::STQXv16i8: + case SPU::STQXv8i16: + case SPU::STQXv4i32: + case SPU::STQXv4f32: + case SPU::STQXv2f64: + case SPU::STQXr128: + case SPU::STQXr64: + case SPU::STQXr32: + case SPU::STQXr16: + // case SPU::STQXr8: + if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && + MI->getOperand(2).isFrameIndex()) { + FrameIndex = MI->getOperand(2).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} Added: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h?rev=44584&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h Tue Dec 4 16:35:58 2007 @@ -0,0 +1,54 @@ +//===- SPUInstrInfo.h - Cell SPU Instruction Information --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the PowerPC implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef SPU_INSTRUCTIONINFO_H +#define SPU_INSTRUCTIONINFO_H + +#include "SPU.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "SPURegisterInfo.h" + +namespace llvm { + //! Cell SPU instruction information class + class SPUInstrInfo : public TargetInstrInfo + { + SPUTargetMachine &TM; + const SPURegisterInfo RI; + public: + SPUInstrInfo(SPUTargetMachine &tm); + + /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As + /// such, whenever a client has an instance of instruction info, it should + /// always be able to get register info as well (through this method). + /// + virtual const MRegisterInfo &getRegisterInfo() const { return RI; } + + /// getPointerRegClass - Return the register class to use to hold pointers. + /// This is used for addressing modes. + virtual const TargetRegisterClass *getPointerRegClass() const; + + // Return true if the instruction is a register to register move and + // leave the source and dest operands in the passed parameters. + // + virtual bool isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const; + + unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + }; +} + +#endif Added: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=44584&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Tue Dec 4 16:35:58 2007 @@ -0,0 +1,3145 @@ +//==- SPUInstrInfo.td - Describe the Cell SPU Instructions -*- tablegen -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by The Aerospace Corporation. +// +//===----------------------------------------------------------------------===// +// Cell SPU Instructions: +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// TODO Items (not urgent today, but would be nice, low priority) +// +// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by +// concatenating the byte argument b as "bbbb". Could recognize this bit pattern +// in 16-bit and 32-bit constants and reduce instruction count. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Pseudo instructions: +//===----------------------------------------------------------------------===// + +let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in { + def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm:$amt), + "${:comment} ADJCALLSTACKDOWN", + [(callseq_start imm:$amt)]>; + def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm:$amt), + "${:comment} ADJCALLSTACKUP", + [(callseq_end imm:$amt)]>; +} + +//===----------------------------------------------------------------------===// +// DWARF debugging Pseudo Instructions +//===----------------------------------------------------------------------===// + +def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), + "${:comment} .loc $file, $line, $col", + [(dwarf_loc (i32 imm:$line), (i32 imm:$col), + (i32 imm:$file))]>; + +//===----------------------------------------------------------------------===// +// Loads: +// NB: The ordering is actually important, since the instruction selection +// will try each of the instructions in sequence, i.e., the D-form first with +// the 10-bit displacement, then the A-form with the 16 bit displacement, and +// finally the X-form with the register-register. +//===----------------------------------------------------------------------===// + +let isLoad = 1 in { + def LQDv16i8: + RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set (v16i8 VECREG:$rT), (load dform_addr:$src))]>; + + def LQDv8i16: + RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set (v8i16 VECREG:$rT), (load dform_addr:$src))]>; + + def LQDv4i32: + RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set (v4i32 VECREG:$rT), (load dform_addr:$src))]>; + + def LQDv2i64: + RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set (v2i64 VECREG:$rT), (load dform_addr:$src))]>; + + def LQDv4f32: + RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set (v4f32 VECREG:$rT), (load dform_addr:$src))]>; + + def LQDv2f64: + RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set (v2f64 VECREG:$rT), (load dform_addr:$src))]>; + + def LQDr128: + RI10Form<0b00101100, (outs GPRC:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set GPRC:$rT, (load dform_addr:$src))]>; + + def LQDr64: + RI10Form<0b00101100, (outs R64C:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set R64C:$rT, (load dform_addr:$src))]>; + + def LQDr32: + RI10Form<0b00101100, (outs R32C:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set R32C:$rT, (load dform_addr:$src))]>; + + // Floating Point + def LQDf32: + RI10Form<0b00101100, (outs R32FP:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set R32FP:$rT, (load dform_addr:$src))]>; + + def LQDf64: + RI10Form<0b00101100, (outs R64FP:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set R64FP:$rT, (load dform_addr:$src))]>; + // END Floating Point + + def LQDr16: + RI10Form<0b00101100, (outs R16C:$rT), (ins memri10:$src), + "lqd\t$rT, $src", LoadStore, + [(set R16C:$rT, (load dform_addr:$src))]>; + + def LQAv16i8: + RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set (v16i8 VECREG:$rT), (load aform_addr:$src))]>; + + def LQAv8i16: + RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set (v8i16 VECREG:$rT), (load aform_addr:$src))]>; + + def LQAv4i32: + RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set (v4i32 VECREG:$rT), (load aform_addr:$src))]>; + + def LQAv2i64: + RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set (v2i64 VECREG:$rT), (load aform_addr:$src))]>; + + def LQAv4f32: + RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set (v4f32 VECREG:$rT), (load aform_addr:$src))]>; + + def LQAv2f64: + RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set (v2f64 VECREG:$rT), (load aform_addr:$src))]>; + + def LQAr128: + RI16Form<0b100001100, (outs GPRC:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set GPRC:$rT, (load aform_addr:$src))]>; + + def LQAr64: + RI16Form<0b100001100, (outs R64C:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set R64C:$rT, (load aform_addr:$src))]>; + + def LQAr32: + RI16Form<0b100001100, (outs R32C:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set R32C:$rT, (load aform_addr:$src))]>; + + def LQAf32: + RI16Form<0b100001100, (outs R32FP:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set R32FP:$rT, (load aform_addr:$src))]>; + + def LQAf64: + RI16Form<0b100001100, (outs R64FP:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set R64FP:$rT, (load aform_addr:$src))]>; + + def LQAr16: + RI16Form<0b100001100, (outs R16C:$rT), (ins addr256k:$src), + "lqa\t$rT, $src", LoadStore, + [(set R16C:$rT, (load aform_addr:$src))]>; + + def LQXv16i8: + RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set (v16i8 VECREG:$rT), (load xform_addr:$src))]>; + + def LQXv8i16: + RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set (v8i16 VECREG:$rT), (load xform_addr:$src))]>; + + def LQXv4i32: + RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set (v4i32 VECREG:$rT), (load xform_addr:$src))]>; + + def LQXv2i64: + RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set (v2i64 VECREG:$rT), (load xform_addr:$src))]>; + + def LQXv4f32: + RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set (v4f32 VECREG:$rT), (load xform_addr:$src))]>; + + def LQXv2f64: + RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set (v2f64 VECREG:$rT), (load xform_addr:$src))]>; + + def LQXr128: + RRForm<0b00100011100, (outs GPRC:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set GPRC:$rT, (load xform_addr:$src))]>; + + def LQXr64: + RRForm<0b00100011100, (outs R64C:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set R64C:$rT, (load xform_addr:$src))]>; + + def LQXr32: + RRForm<0b00100011100, (outs R32C:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set R32C:$rT, (load xform_addr:$src))]>; + + def LQXf32: + RRForm<0b00100011100, (outs R32FP:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set R32FP:$rT, (load xform_addr:$src))]>; + + def LQXf64: + RRForm<0b00100011100, (outs R64FP:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set R64FP:$rT, (load xform_addr:$src))]>; + + def LQXr16: + RRForm<0b00100011100, (outs R16C:$rT), (ins memrr:$src), + "lqx\t$rT, $src", LoadStore, + [(set R16C:$rT, (load xform_addr:$src))]>; + +/* Load quadword, PC relative: Not much use at this point in time. + Might be of use later for relocatable code. + def LQR : RI16Form<0b111001100, (outs VECREG:$rT), (ins s16imm:$disp), + "lqr\t$rT, $disp", LoadStore, + [(set VECREG:$rT, (load iaddr:$disp))]>; + */ + + // Catch-all for unaligned loads: +} + +//===----------------------------------------------------------------------===// +// Stores: +//===----------------------------------------------------------------------===// + +let isStore = 1 in { + def STQDv16i8 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store (v16i8 VECREG:$rT), dform_addr:$src)]>; + + def STQDv8i16 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store (v8i16 VECREG:$rT), dform_addr:$src)]>; + + def STQDv4i32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store (v4i32 VECREG:$rT), dform_addr:$src)]>; + + def STQDv2i64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store (v2i64 VECREG:$rT), dform_addr:$src)]>; + + def STQDv4f32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store (v4f32 VECREG:$rT), dform_addr:$src)]>; + + def STQDv2f64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store (v2f64 VECREG:$rT), dform_addr:$src)]>; + + def STQDr128 : RI10Form<0b00100100, (outs), (ins GPRC:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store GPRC:$rT, dform_addr:$src)]>; + + def STQDr64 : RI10Form<0b00100100, (outs), (ins R64C:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store R64C:$rT, dform_addr:$src)]>; + + def STQDr32 : RI10Form<0b00100100, (outs), (ins R32C:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store R32C:$rT, dform_addr:$src)]>; + + // Floating Point + def STQDf32 : RI10Form<0b00100100, (outs), (ins R32FP:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store R32FP:$rT, dform_addr:$src)]>; + + def STQDf64 : RI10Form<0b00100100, (outs), (ins R64FP:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store R64FP:$rT, dform_addr:$src)]>; + + def STQDr16 : RI10Form<0b00100100, (outs), (ins R16C:$rT, memri10:$src), + "stqd\t$rT, $src", LoadStore, + [(store R16C:$rT, dform_addr:$src)]>; + + def STQAv16i8 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store (v16i8 VECREG:$rT), aform_addr:$src)]>; + + def STQAv8i16 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store (v8i16 VECREG:$rT), aform_addr:$src)]>; + + def STQAv4i32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store (v4i32 VECREG:$rT), aform_addr:$src)]>; + + def STQAv2i64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store (v2i64 VECREG:$rT), aform_addr:$src)]>; + + def STQAv4f32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store (v4f32 VECREG:$rT), aform_addr:$src)]>; + + def STQAv2f64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store (v2f64 VECREG:$rT), aform_addr:$src)]>; + + def STQAr128 : RI10Form<0b00100100, (outs), (ins GPRC:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store GPRC:$rT, aform_addr:$src)]>; + + def STQAr64 : RI10Form<0b00100100, (outs), (ins R64C:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store R64C:$rT, aform_addr:$src)]>; + + def STQAr32 : RI10Form<0b00100100, (outs), (ins R32C:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store R32C:$rT, aform_addr:$src)]>; + + // Floating Point + def STQAf32 : RI10Form<0b00100100, (outs), (ins R32FP:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store R32FP:$rT, aform_addr:$src)]>; + + def STQAf64 : RI10Form<0b00100100, (outs), (ins R64FP:$rT, addr256k:$src), + "stqa\t$rT, $src", LoadStore, + [(store R64FP:$rT, aform_addr:$src)]>; + + def STQXv16i8 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store (v16i8 VECREG:$rT), xform_addr:$src)]>; + + def STQXv8i16 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store (v8i16 VECREG:$rT), xform_addr:$src)]>; + + def STQXv4i32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store (v4i32 VECREG:$rT), xform_addr:$src)]>; + + def STQXv2i64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store (v2i64 VECREG:$rT), xform_addr:$src)]>; + + def STQXv4f32 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store (v4f32 VECREG:$rT), xform_addr:$src)]>; + + def STQXv2f64 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store (v2f64 VECREG:$rT), xform_addr:$src)]>; + + def STQXr128 : RI10Form<0b00100100, (outs), (ins GPRC:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store GPRC:$rT, xform_addr:$src)]>; + + def STQXr64 : RI10Form<0b00100100, (outs), (ins R64C:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store R64C:$rT, xform_addr:$src)]>; + + def STQXr32 : RI10Form<0b00100100, (outs), (ins R32C:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store R32C:$rT, xform_addr:$src)]>; + + // Floating Point + def STQXf32 : RI10Form<0b00100100, (outs), (ins R32FP:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store R32FP:$rT, xform_addr:$src)]>; + + def STQXf64 : RI10Form<0b00100100, (outs), (ins R64FP:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store R64FP:$rT, xform_addr:$src)]>; + + def STQXr16 : RI10Form<0b00100100, (outs), (ins R16C:$rT, memrr:$src), + "stqx\t$rT, $src", LoadStore, + [(store R16C:$rT, xform_addr:$src)]>; + +/* Store quadword, PC relative: Not much use at this point in time. Might + be useful for relocatable code. + def STQR : RI16Form<0b111000100, (outs), (ins VECREG:$rT, s16imm:$disp), + "stqr\t$rT, $disp", LoadStore, + [(store VECREG:$rT, iaddr:$disp)]>; + */ +} + +//===----------------------------------------------------------------------===// +// Generate Controls for Insertion: +//===----------------------------------------------------------------------===// + +def CBD : + RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src), + "cbd\t$rT, $src", ShuffleOp, + [(set (v16i8 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>; + +def CBX : RRForm<0b00101011100, (outs VECREG:$rT), (ins memrr:$src), + "cbx\t$rT, $src", ShuffleOp, + [(set (v16i8 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>; + +def CHD : RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src), + "chd\t$rT, $src", ShuffleOp, + [(set (v8i16 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>; + +def CHX : RRForm<0b10101011100, (outs VECREG:$rT), (ins memrr:$src), + "chx\t$rT, $src", ShuffleOp, + [(set (v8i16 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>; + +def CWD : RI7Form<0b01101111100, (outs VECREG:$rT), (ins memri7:$src), + "cwd\t$rT, $src", ShuffleOp, + [(set (v4i32 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>; + +def CWX : RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), + "cwx\t$rT, $src", ShuffleOp, + [(set (v4i32 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>; + +def CDD : RI7Form<0b11101111100, (outs VECREG:$rT), (ins memri7:$src), + "cdd\t$rT, $src", ShuffleOp, + [(set (v2i64 VECREG:$rT), (SPUvecinsmask dform2_addr:$src))]>; + +def CDX : RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), + "cdx\t$rT, $src", ShuffleOp, + [(set (v2i64 VECREG:$rT), (SPUvecinsmask xform_addr:$src))]>; + +//===----------------------------------------------------------------------===// +// Constant formation: +//===----------------------------------------------------------------------===// + +def ILHv8i16: + RI16Form<0b110000010, (outs VECREG:$rT), (ins s16imm:$val), + "ilh\t$rT, $val", ImmLoad, + [(set (v8i16 VECREG:$rT), (v8i16 v8i16SExt16Imm:$val))]>; + +def ILHr16: + RI16Form<0b110000010, (outs R16C:$rT), (ins s16imm:$val), + "ilh\t$rT, $val", ImmLoad, + [(set R16C:$rT, immSExt16:$val)]>; + +// IL does sign extension! +def ILr64: + RI16Form<0b100000010, (outs R64C:$rT), (ins s16imm_i64:$val), + "il\t$rT, $val", ImmLoad, + [(set R64C:$rT, immSExt16:$val)]>; + +def ILv2i64: + RI16Form<0b100000010, (outs VECREG:$rT), (ins s16imm_i64:$val), + "il\t$rT, $val", ImmLoad, + [(set VECREG:$rT, (v2i64 v2i64SExt16Imm:$val))]>; + +def ILv4i32: + RI16Form<0b100000010, (outs VECREG:$rT), (ins s16imm:$val), + "il\t$rT, $val", ImmLoad, + [(set VECREG:$rT, (v4i32 v4i32SExt16Imm:$val))]>; + +def ILr32: + RI16Form<0b100000010, (outs R32C:$rT), (ins s16imm_i32:$val), + "il\t$rT, $val", ImmLoad, + [(set R32C:$rT, immSExt16:$val)]>; + +def ILf32: + RI16Form<0b100000010, (outs R32FP:$rT), (ins s16imm_f32:$val), + "il\t$rT, $val", ImmLoad, + [(set R32FP:$rT, (SPUFPconstant fpimmSExt16:$val))]>; + +def ILf64: + RI16Form<0b100000010, (outs R64FP:$rT), (ins s16imm_f64:$val), + "il\t$rT, $val", ImmLoad, + [(set R64FP:$rT, (SPUFPconstant fpimmSExt16:$val))]>; + +def ILHUv4i32: + RI16Form<0b010000010, (outs VECREG:$rT), (ins u16imm:$val), + "ilhu\t$rT, $val", ImmLoad, + [(set VECREG:$rT, (v4i32 immILHUvec:$val))]>; + +def ILHUr32: + RI16Form<0b010000010, (outs R32C:$rT), (ins u16imm:$val), + "ilhu\t$rT, $val", ImmLoad, + [(set R32C:$rT, hi16:$val)]>; + +// ILHUf32: Used to custom lower float constant loads +def ILHUf32: + RI16Form<0b010000010, (outs R32FP:$rT), (ins f16imm:$val), + "ilhu\t$rT, $val", ImmLoad, + [(set R32FP:$rT, (SPUFPconstant hi16_f32:$val))]>; + +// ILHUhi: Used for loading high portion of an address. Note the symbolHi +// printer used for the operand. +def ILHUhi : RI16Form<0b010000010, (outs R32C:$rT), (ins symbolHi:$val), + "ilhu\t$rT, $val", ImmLoad, + [(set R32C:$rT, hi16:$val)]>; + +// Immediate load address (can also be used to load 18-bit unsigned constants, +// see the zext 16->32 pattern) +def ILAr64: + RI18Form<0b1000010, (outs R64C:$rT), (ins u18imm_i64:$val), + "ila\t$rT, $val", LoadNOP, + [(set R64C:$rT, imm18:$val)]>; + +// TODO: ILAv2i64 + +def ILAv2i64: + RI18Form<0b1000010, (outs VECREG:$rT), (ins u18imm:$val), + "ila\t$rT, $val", LoadNOP, + [(set (v2i64 VECREG:$rT), v2i64Uns18Imm:$val)]>; + +def ILAv4i32: + RI18Form<0b1000010, (outs VECREG:$rT), (ins u18imm:$val), + "ila\t$rT, $val", LoadNOP, + [(set (v4i32 VECREG:$rT), v4i32Uns18Imm:$val)]>; + +def ILAr32: + RI18Form<0b1000010, (outs R32C:$rT), (ins u18imm:$val), + "ila\t$rT, $val", LoadNOP, + [(set R32C:$rT, imm18:$val)]>; + +def ILAf32: + RI18Form<0b1000010, (outs R32FP:$rT), (ins f18imm:$val), + "ila\t$rT, $val", LoadNOP, + [(set R32FP:$rT, (SPUFPconstant fpimm18:$val))]>; + +def ILAf64: + RI18Form<0b1000010, (outs R64FP:$rT), (ins f18imm_f64:$val), + "ila\t$rT, $val", LoadNOP, + [(set R64FP:$rT, (SPUFPconstant fpimm18:$val))]>; + +def ILAlo: + RI18Form<0b1000010, (outs R32C:$rT), (ins symbolLo:$val), + "ila\t$rT, $val", ImmLoad, + [(set R32C:$rT, imm18:$val)]>; + +def ILAlsa: + RI18Form<0b1000010, (outs R32C:$rT), (ins symbolLSA:$val), + "ila\t$rT, $val", ImmLoad, + [/* no pattern */]>; + +// Immediate OR, Halfword Lower: The "other" part of loading large constants +// into 32-bit registers. See the anonymous pattern Pat<(i32 imm:$imm), ...> +// Note that these are really two operand instructions, but they're encoded +// as three operands with the first two arguments tied-to each other. + +def IOHLvec: + RI16Form<0b100000110, (outs VECREG:$rT), (ins VECREG:$rS, u16imm:$val), + "iohl\t$rT, $val", ImmLoad, + [/* insert intrinsic here */]>, + RegConstraint<"$rS = $rT">, + NoEncode<"$rS">; + +def IOHLr32: + RI16Form<0b100000110, (outs R32C:$rT), (ins R32C:$rS, i32imm:$val), + "iohl\t$rT, $val", ImmLoad, + [/* insert intrinsic here */]>, + RegConstraint<"$rS = $rT">, + NoEncode<"$rS">; + +def IOHLf32: + RI16Form<0b100000110, (outs R32FP:$rT), (ins R32FP:$rS, f32imm:$val), + "iohl\t$rT, $val", ImmLoad, + [/* insert intrinsic here */]>, + RegConstraint<"$rS = $rT">, + NoEncode<"$rS">; + +// Form select mask for bytes using immediate, used in conjunction with the +// SELB instruction: + +def FSMBIv16i8 : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), + "fsmbi\t$rT, $val", SelectOp, + [(set (v16i8 VECREG:$rT), (SPUfsmbi_v16i8 immU16:$val))]>; + +def FSMBIv8i16 : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), + "fsmbi\t$rT, $val", SelectOp, + [(set (v8i16 VECREG:$rT), (SPUfsmbi_v8i16 immU16:$val))]>; + +def FSMBIvecv4i32 : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), + "fsmbi\t$rT, $val", SelectOp, + [(set (v4i32 VECREG:$rT), (SPUfsmbi_v4i32 immU16:$val))]>; + +//===----------------------------------------------------------------------===// +// Integer and Logical Operations: +//===----------------------------------------------------------------------===// + +def AHv8i16: + RRForm<0b00010011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ah\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (int_spu_si_ah VECREG:$rA, VECREG:$rB))]>; + +def : Pat<(add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), + (AHv8i16 VECREG:$rA, VECREG:$rB)>; + +// [(set (v8i16 VECREG:$rT), (add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def AHr16: + RRForm<0b00010011000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "ah\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (add R16C:$rA, R16C:$rB))]>; + +def AHIvec: + RI10Form<0b10111000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ahi\t$rT, $rA, $val", IntegerOp, + [(set (v8i16 VECREG:$rT), (add (v8i16 VECREG:$rA), + v8i16SExt10Imm:$val))]>; + +def AHIr16 : RI10Form<0b10111000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "ahi\t$rT, $rA, $val", IntegerOp, + [(set R16C:$rT, (add R16C:$rA, v8i16SExt10Imm:$val))]>; + +def Avec : RRForm<0b00000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "a\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (add (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def : Pat<(add (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)), + (Avec VECREG:$rA, VECREG:$rB)>; + +def Ar32 : RRForm<0b00000011000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "a\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (add R32C:$rA, R32C:$rB))]>; + +def AIvec: + RI10Form<0b00111000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ai\t$rT, $rA, $val", IntegerOp, + [(set (v4i32 VECREG:$rT), (add (v4i32 VECREG:$rA), + v4i32SExt10Imm:$val))]>; + +def AIr32 : RI10Form<0b00111000, (outs R32C:$rT), + (ins R32C:$rA, s10imm_i32:$val), + "ai\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (add R32C:$rA, i32ImmSExt10:$val))]>; + +def SFHvec : RRForm<0b00010010000, (outs VECREG:$rT), + (ins VECREG:$rA, VECREG:$rB), + "sfh\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (sub (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def SFHr16 : RRForm<0b00010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "sfh\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (sub R16C:$rA, R16C:$rB))]>; + +def SFHIvec: + RI10Form<0b10110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "sfhi\t$rT, $rA, $val", IntegerOp, + [(set (v8i16 VECREG:$rT), (sub v8i16SExt10Imm:$val, + (v8i16 VECREG:$rA)))]>; + +def SFHIr16 : RI10Form<0b10110000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "sfhi\t$rT, $rA, $val", IntegerOp, + [(set R16C:$rT, (sub i16ImmSExt10:$val, R16C:$rA))]>; + +def SFvec : RRForm<0b00000010000, (outs VECREG:$rT), + (ins VECREG:$rA, VECREG:$rB), + "sf\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (sub (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def SFr32 : RRForm<0b00000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "sf\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (sub R32C:$rA, R32C:$rB))]>; + +def SFIvec: + RI10Form<0b00110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "sfi\t$rT, $rA, $val", IntegerOp, + [(set (v4i32 VECREG:$rT), (sub v4i32SExt10Imm:$val, + (v4i32 VECREG:$rA)))]>; + +def SFIr32 : RI10Form<0b00110000, (outs R32C:$rT), + (ins R32C:$rA, s10imm_i32:$val), + "sfi\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (sub i32ImmSExt10:$val, R32C:$rA))]>; + +// ADDX: only available in vector form, doesn't match a pattern. +def ADDXvec: + RRForm<0b00000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, + VECREG:$rCarry), + "addx\t$rT, $rA, $rB", IntegerOp, + []>, + RegConstraint<"$rCarry = $rT">, + NoEncode<"$rCarry">; + +// CG: only available in vector form, doesn't match a pattern. +def CGvec: + RRForm<0b01000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, + VECREG:$rCarry), + "cg\t$rT, $rA, $rB", IntegerOp, + []>, + RegConstraint<"$rCarry = $rT">, + NoEncode<"$rCarry">; + +// SFX: only available in vector form, doesn't match a pattern +def SFXvec: + RRForm<0b10000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, + VECREG:$rCarry), + "sfx\t$rT, $rA, $rB", IntegerOp, + []>, + RegConstraint<"$rCarry = $rT">, + NoEncode<"$rCarry">; + +// BG: only available in vector form, doesn't match a pattern. +def BGvec: + RRForm<0b01000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, + VECREG:$rCarry), + "bg\t$rT, $rA, $rB", IntegerOp, + []>, + RegConstraint<"$rCarry = $rT">, + NoEncode<"$rCarry">; + +// BGX: only available in vector form, doesn't match a pattern. +def BGXvec: + RRForm<0b11000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, + VECREG:$rCarry), + "bgx\t$rT, $rA, $rB", IntegerOp, + []>, + RegConstraint<"$rCarry = $rT">, + NoEncode<"$rCarry">; + +// Halfword multiply variants: +// N.B: These can be used to build up larger quantities (16x16 -> 32) + +def MPYv8i16: + RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpy\t$rT, $rA, $rB", IntegerMulDiv, + [(set (v8i16 VECREG:$rT), (SPUmpy_v8i16 (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def MPYr16: + RRForm<0b00100011110, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "mpy\t$rT, $rA, $rB", IntegerMulDiv, + [(set R16C:$rT, (mul R16C:$rA, R16C:$rB))]>; + +def MPYUv4i32: + RRForm<0b00110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyu\t$rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), + (SPUmpyu_v4i32 (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def MPYUr16: + RRForm<0b00110011110, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB), + "mpyu\t$rT, $rA, $rB", IntegerMulDiv, + [(set R32C:$rT, (mul (zext R16C:$rA), + (zext R16C:$rB)))]>; + +def MPYUr32: + RRForm<0b00110011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "mpyu\t$rT, $rA, $rB", IntegerMulDiv, + [(set R32C:$rT, (SPUmpyu_i32 R32C:$rA, R32C:$rB))]>; + +// mpyi: multiply 16 x s10imm -> 32 result (custom lowering for 32 bit result, +// this only produces the lower 16 bits) +def MPYIvec: + RI10Form<0b00101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "mpyi\t$rT, $rA, $val", IntegerMulDiv, + [(set (v8i16 VECREG:$rT), (mul (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>; + +def MPYIr16: + RI10Form<0b00101110, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "mpyi\t$rT, $rA, $val", IntegerMulDiv, + [(set R16C:$rT, (mul R16C:$rA, i16ImmSExt10:$val))]>; + +// mpyui: same issues as other multiplies, plus, this doesn't match a +// pattern... but may be used during target DAG selection or lowering +def MPYUIvec: + RI10Form<0b10101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "mpyui\t$rT, $rA, $val", IntegerMulDiv, + []>; + +def MPYUIr16: + RI10Form<0b10101110, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "mpyui\t$rT, $rA, $val", IntegerMulDiv, + []>; + +// mpya: 16 x 16 + 16 -> 32 bit result +def MPYAvec: + RRRForm<0b0011, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (add (v4i32 (bitconvert (mul (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))), + (v4i32 VECREG:$rC)))]>; + +def MPYAr32: + RRRForm<0b0011, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC), + "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, + [(set R32C:$rT, (add (sext (mul R16C:$rA, R16C:$rB)), + R32C:$rC))]>; + +def : Pat<(add (mul (sext R16C:$rA), (sext R16C:$rB)), R32C:$rC), + (MPYAr32 R16C:$rA, R16C:$rB, R32C:$rC)>; + +def MPYAr32_sextinreg: + RRRForm<0b0011, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC), + "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, + [(set R32C:$rT, (add (mul (sext_inreg R32C:$rA, i16), + (sext_inreg R32C:$rB, i16)), + R32C:$rC))]>; + +//def MPYAr32: +// RRRForm<0b0011, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC), +// "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, +// [(set R32C:$rT, (add (sext (mul R16C:$rA, R16C:$rB)), +// R32C:$rC))]>; + +// mpyh: multiply high, used to synthesize 32-bit multiplies +def MPYHv4i32: + RRForm<0b10100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyh\t$rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), + (SPUmpyh_v4i32 (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def MPYHr32: + RRForm<0b10100011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "mpyh\t$rT, $rA, $rB", IntegerMulDiv, + [(set R32C:$rT, (SPUmpyh_i32 R32C:$rA, R32C:$rB))]>; + +// mpys: multiply high and shift right (returns the top half of +// a 16-bit multiply, sign extended to 32 bits.) +def MPYSvec: + RRForm<0b11100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpys\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +def MPYSr16: + RRForm<0b11100011110, (outs R32C:$rT), (ins R16C:$rA, R16C:$rB), + "mpys\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +// mpyhh: multiply high-high (returns the 32-bit result from multiplying +// the top 16 bits of the $rA, $rB) +def MPYHHv8i16: + RRForm<0b01100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhh\t$rT, $rA, $rB", IntegerMulDiv, + [(set (v8i16 VECREG:$rT), + (SPUmpyhh_v8i16 (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def MPYHHr32: + RRForm<0b01100011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "mpyhh\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +// mpyhha: Multiply high-high, add to $rT: +def MPYHHAvec: + RRForm<0b01100010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhha\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +def MPYHHAr32: + RRForm<0b01100010110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "mpyhha\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +// mpyhhu: Multiply high-high, unsigned +def MPYHHUvec: + RRForm<0b01110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhhu\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +def MPYHHUr32: + RRForm<0b01110011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "mpyhhu\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +// mpyhhau: Multiply high-high, unsigned +def MPYHHAUvec: + RRForm<0b01110010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +def MPYHHAUr32: + RRForm<0b01110010110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv, + []>; + +// clz: Count leading zeroes +def CLZv4i32: + RRForm_1<0b10100101010, (outs VECREG:$rT), (ins VECREG:$rA), + "clz\t$rT, $rA", IntegerOp, + [/* intrinsic */]>; + +def CLZr32: + RRForm_1<0b10100101010, (outs R32C:$rT), (ins R32C:$rA), + "clz\t$rT, $rA", IntegerOp, + [(set R32C:$rT, (ctlz R32C:$rA))]>; + +// cntb: Count ones in bytes (aka "population count") +// NOTE: This instruction is really a vector instruction, but the custom +// lowering code uses it in unorthodox ways to support CTPOP for other +// data types! +def CNTBv16i8: + RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA), + "cntb\t$rT, $rA", IntegerOp, + [(set (v16i8 VECREG:$rT), (SPUcntb_v16i8 (v16i8 VECREG:$rA)))]>; + +def CNTBv8i16 : + RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA), + "cntb\t$rT, $rA", IntegerOp, + [(set (v8i16 VECREG:$rT), (SPUcntb_v8i16 (v8i16 VECREG:$rA)))]>; + +def CNTBv4i32 : + RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA), + "cntb\t$rT, $rA", IntegerOp, + [(set (v4i32 VECREG:$rT), (SPUcntb_v4i32 (v4i32 VECREG:$rA)))]>; + +// fsmb: Form select mask for bytes. N.B. Input operand, $rA, is 16-bits +def FSMB: + RRForm_1<0b01101101100, (outs VECREG:$rT), (ins R16C:$rA), + "fsmb\t$rT, $rA", SelectOp, + []>; + +// fsmh: Form select mask for halfwords. N.B., Input operand, $rA, is +// only 8-bits wide (even though it's input as 16-bits here) +def FSMH: + RRForm_1<0b10101101100, (outs VECREG:$rT), (ins R16C:$rA), + "fsmh\t$rT, $rA", SelectOp, + []>; + +// fsm: Form select mask for words. Like the other fsm* instructions, +// only the lower 4 bits of $rA are significant. +def FSM: + RRForm_1<0b00101101100, (outs VECREG:$rT), (ins R16C:$rA), + "fsm\t$rT, $rA", SelectOp, + []>; + +// gbb: Gather all low order bits from each byte in $rA into a single 16-bit +// quantity stored into $rT +def GBB: + RRForm_1<0b01001101100, (outs R16C:$rT), (ins VECREG:$rA), + "gbb\t$rT, $rA", GatherOp, + []>; + +// gbh: Gather all low order bits from each halfword in $rA into a single +// 8-bit quantity stored in $rT +def GBH: + RRForm_1<0b10001101100, (outs R16C:$rT), (ins VECREG:$rA), + "gbh\t$rT, $rA", GatherOp, + []>; + +// gb: Gather all low order bits from each word in $rA into a single +// 4-bit quantity stored in $rT +def GB: + RRForm_1<0b00001101100, (outs R16C:$rT), (ins VECREG:$rA), + "gb\t$rT, $rA", GatherOp, + []>; + +// avgb: average bytes +def AVGB: + RRForm<0b11001011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "avgb\t$rT, $rA, $rB", ByteOp, + []>; + +// absdb: absolute difference of bytes +def ABSDB: + RRForm<0b11001010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "absdb\t$rT, $rA, $rB", ByteOp, + []>; + +// sumb: sum bytes into halfwords +def SUMB: + RRForm<0b11001010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "sumb\t$rT, $rA, $rB", ByteOp, + []>; + +// Sign extension operations: +def XSBHvec: + RRForm_1<0b01101101010, (outs VECREG:$rDst), (ins VECREG:$rSrc), + "xsbh\t$rDst, $rSrc", IntegerOp, + [(set (v8i16 VECREG:$rDst), (sext (v16i8 VECREG:$rSrc)))]>; + +// Ordinary form for XSBH +def XSBHr16: + RRForm_1<0b01101101010, (outs R16C:$rDst), (ins R16C:$rSrc), + "xsbh\t$rDst, $rSrc", IntegerOp, + [(set R16C:$rDst, (sext_inreg R16C:$rSrc, i8))]>; + +// 32-bit form for XSBH: used to sign extend 8-bit quantities to 16-bit +// quantities to 32-bit quantities via a 32-bit register (see the sext 8->32 +// pattern below). Intentionally doesn't match a pattern because we want the +// sext 8->32 pattern to do the work for us, namely because we need the extra +// XSHWr32. +def XSBHr32: + RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R32C:$rSrc), + "xsbh\t$rDst, $rSrc", IntegerOp, + [(set R32C:$rDst, (sext_inreg R32C:$rSrc, i8))]>; + +// Sign extend halfwords to words: +def XSHWvec: + RRForm_1<0b01101101010, (outs VECREG:$rDest), (ins VECREG:$rSrc), + "xshw\t$rDest, $rSrc", IntegerOp, + [(set (v4i32 VECREG:$rDest), (sext (v8i16 VECREG:$rSrc)))]>; + +def XSHWr32: + RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R32C:$rSrc), + "xshw\t$rDst, $rSrc", IntegerOp, + [(set R32C:$rDst, (sext_inreg R32C:$rSrc, i16))]>; + +def XSHWr16: + RRForm_1<0b01101101010, (outs R32C:$rDst), (ins R16C:$rSrc), + "xshw\t$rDst, $rSrc", IntegerOp, + [(set R32C:$rDst, (sext R16C:$rSrc))]>; + +def XSWDvec: + RRForm_1<0b01100101010, (outs VECREG:$rDst), (ins VECREG:$rSrc), + "xswd\t$rDst, $rSrc", IntegerOp, + [(set (v2i64 VECREG:$rDst), (sext (v4i32 VECREG:$rSrc)))]>; + +def XSWDr64: + RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R64C:$rSrc), + "xswd\t$rDst, $rSrc", IntegerOp, + [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>; + +def XSWDr32: + RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R32C:$rSrc), + "xswd\t$rDst, $rSrc", IntegerOp, + [(set R64C:$rDst, (SPUsext32_to_64 R32C:$rSrc))]>; + +def : Pat<(sext R32C:$inp), + (XSWDr32 R32C:$inp)>; + +// AND operations +def ANDv16i8: + RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (and (v16i8 VECREG:$rA), + (v16i8 VECREG:$rB)))]>; + +def ANDv8i16: + RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (and (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def ANDv4i32: + RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (and (v4i32 VECREG:$rA), + (v4i32 VECREG:$rB)))]>; + +def ANDr32: + RRForm<0b10000011000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (and R32C:$rA, R32C:$rB))]>; + +//===--------------------------------------------- +// Special instructions to perform the fabs instruction +def ANDfabs32: + RRForm<0b10000011000, (outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [/* Intentionally does not match a pattern */]>; + +def ANDfabs64: + RRForm<0b10000011000, (outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [/* Intentionally does not match a pattern */]>; + +// Could use ANDv4i32, but won't for clarity +def ANDfabsvec: + RRForm<0b10000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [/* Intentionally does not match a pattern */]>; + +//===--------------------------------------------- + +def ANDr16: + RRForm<0b10000011000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (and R16C:$rA, R16C:$rB))]>; + +// Hacked form of AND to zero-extend 16-bit quantities to 32-bit +// quantities -- see 16->32 zext pattern. +// +// This pattern is somewhat artificial, since it might match some +// compiler generated pattern but it is unlikely to do so. +def AND2To4: + RRForm<0b10000011000, (outs R32C:$rT), (ins R16C:$rA, R32C:$rB), + "and\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (and (zext R16C:$rA), R32C:$rB))]>; + +// N.B.: vnot_conv is one of those special target selection pattern fragments, +// in which we expect there to be a bit_convert on the constant. Bear in mind +// that llvm translates "not " to "xor , -1" (or in this case, a +// constant -1 vector.) +def ANDCv16i8: + RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "andc\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (and (v16i8 VECREG:$rA), + (vnot (v16i8 VECREG:$rB))))]>; + +def ANDCv8i16: + RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "andc\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (and (v8i16 VECREG:$rA), + (vnot (v8i16 VECREG:$rB))))]>; + +def ANDCv4i32: + RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "andc\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (and (v4i32 VECREG:$rA), + (vnot (v4i32 VECREG:$rB))))]>; + +def ANDCr32: + RRForm<0b10000011010, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "andc\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (and R32C:$rA, (not R32C:$rB)))]>; + +def ANDCr16: + RRForm<0b10000011010, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "andc\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (and R16C:$rA, (not R16C:$rB)))]>; + +def ANDBIv16i8: + RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "andbi\t$rT, $rA, $val", IntegerOp, + [(set (v16i8 VECREG:$rT), + (and (v16i8 VECREG:$rA), (v16i8 v16i8U8Imm:$val)))]>; + +def ANDHIv8i16: + RI10Form<0b10101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "andhi\t$rT, $rA, $val", IntegerOp, + [(set (v8i16 VECREG:$rT), + (and (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>; + +def ANDHIr16: + RI10Form<0b10101000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "andhi\t$rT, $rA, $val", IntegerOp, + [(set R16C:$rT, (and R16C:$rA, i16ImmSExt10:$val))]>; + +def ANDIv4i32: + RI10Form<0b00101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "andi\t$rT, $rA, $val", IntegerOp, + [(set (v4i32 VECREG:$rT), + (and (v4i32 VECREG:$rA), v4i32SExt10Imm:$val))]>; + +def ANDIr32: + RI10Form<0b10101000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), + "andi\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (and R32C:$rA, i32ImmSExt10:$val))]>; + +// Hacked form of ANDI to zero-extend i16 quantities to i32. See the +// zext 16->32 pattern below. +// +// Note that this pattern is somewhat artificial, since it might match +// something the compiler generates but is unlikely to occur in practice. +def ANDI2To4: + RI10Form<0b10101000, (outs R32C:$rT), (ins R16C:$rA, s10imm_i32:$val), + "andi\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (and (zext R16C:$rA), i32ImmSExt10:$val))]>; + +// Bitwise OR group: +// Bitwise "or" (N.B.: These are also register-register copy instructions...) +def ORv16i8: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (or (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; + +def ORv8i16: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (or (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def ORv4i32: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def ORv4f32: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set (v4f32 VECREG:$rT), + (v4f32 (bitconvert (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))))]>; + +def ORv2f64: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set (v2f64 VECREG:$rT), + (v2f64 (bitconvert (or (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)))))]>; + +def ORgprc: + RRForm<0b10000010000, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set GPRC:$rT, (or GPRC:$rA, GPRC:$rB))]>; + +def ORr64: + RRForm<0b10000010000, (outs R64C:$rT), (ins R64C:$rA, R64C:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set R64C:$rT, (or R64C:$rA, R64C:$rB))]>; + +def ORr32: + RRForm<0b10000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (or R32C:$rA, R32C:$rB))]>; + +def ORr16: + RRForm<0b10000010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (or R16C:$rA, R16C:$rB))]>; + +// ORv*_*: Used in scalar->vector promotions: +def ORv8i16_i16: + RRForm<0b10000010000, (outs VECREG:$rT), (ins R16C:$rA, R16C:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(v8i16 (SPUpromote_scalar R16C:$rA)), + (ORv8i16_i16 R16C:$rA, R16C:$rA)>; + +def ORv4i32_i32: + RRForm<0b10000010000, (outs VECREG:$rT), (ins R32C:$rA, R32C:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(v4i32 (SPUpromote_scalar R32C:$rA)), + (ORv4i32_i32 R32C:$rA, R32C:$rA)>; + +def ORv2i64_i64: + RRForm<0b10000010000, (outs VECREG:$rT), (ins R64C:$rA, R64C:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(v2i64 (SPUpromote_scalar R64C:$rA)), + (ORv2i64_i64 R64C:$rA, R64C:$rA)>; + +def ORv4f32_f32: + RRForm<0b10000010000, (outs VECREG:$rT), (ins R32FP:$rA, R32FP:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(v4f32 (SPUpromote_scalar R32FP:$rA)), + (ORv4f32_f32 R32FP:$rA, R32FP:$rA)>; + +def ORv2f64_f64: + RRForm<0b10000010000, (outs VECREG:$rT), (ins R64FP:$rA, R64FP:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(v2f64 (SPUpromote_scalar R64FP:$rA)), + (ORv2f64_f64 R64FP:$rA, R64FP:$rA)>; + +// ORi*_v*: Used to extract vector element 0 (the preferred slot) +def ORi16_v8i16: + RRForm<0b10000010000, (outs R16C:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(SPUextract_elt0 (v8i16 VECREG:$rA)), + (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>; + +def : Pat<(SPUextract_elt0_chained (v8i16 VECREG:$rA)), + (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>; + +def ORi32_v4i32: + RRForm<0b10000010000, (outs R32C:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(SPUextract_elt0 (v4i32 VECREG:$rA)), + (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>; + +def : Pat<(SPUextract_elt0_chained (v4i32 VECREG:$rA)), + (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>; + +def ORi64_v2i64: + RRForm<0b10000010000, (outs R64C:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(SPUextract_elt0 (v2i64 VECREG:$rA)), + (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>; + +def : Pat<(SPUextract_elt0_chained (v2i64 VECREG:$rA)), + (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>; + +def ORf32_v4f32: + RRForm<0b10000010000, (outs R32FP:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(SPUextract_elt0 (v4f32 VECREG:$rA)), + (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>; + +def : Pat<(SPUextract_elt0_chained (v4f32 VECREG:$rA)), + (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>; + +def ORf64_v2f64: + RRForm<0b10000010000, (outs R64FP:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t$rT, $rA, $rB", IntegerOp, + [/* no pattern */]>; + +def : Pat<(SPUextract_elt0 (v2f64 VECREG:$rA)), + (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>; + +def : Pat<(SPUextract_elt0_chained (v2f64 VECREG:$rA)), + (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>; + +// ORC: Bitwise "or" with complement (match before ORvec, ORr32) +def ORCv16i8: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "orc\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (or (v16i8 VECREG:$rA), + (vnot (v16i8 VECREG:$rB))))]>; + +def ORCv8i16: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "orc\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (or (v8i16 VECREG:$rA), + (vnot (v8i16 VECREG:$rB))))]>; + +def ORCv4i32: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "orc\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (or (v4i32 VECREG:$rA), + (vnot (v4i32 VECREG:$rB))))]>; + +def ORCr32: + RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "orc\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (or R32C:$rA, (not R32C:$rB)))]>; + +def ORCr16: + RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "orc\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (or R16C:$rA, (not R16C:$rB)))]>; + +// OR byte immediate +def ORBIv16i8: + RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "orbi\t$rT, $rA, $val", IntegerOp, + [(set (v16i8 VECREG:$rT), + (or (v16i8 VECREG:$rA), (v16i8 v16i8U8Imm:$val)))]>; + +// OR halfword immediate +def ORHIv8i16: + RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "orhi\t$rT, $rA, $val", IntegerOp, + [(set (v8i16 VECREG:$rT), (or (v8i16 VECREG:$rA), + v8i16SExt10Imm:$val))]>; + +def ORHIr16: + RI10Form<0b10100000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "orhi\t$rT, $rA, $val", IntegerOp, + [(set R16C:$rT, (or R16C:$rA, i16ImmSExt10:$val))]>; + +// Bitwise "or" with immediate +def ORIv4i32: + RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ori\t$rT, $rA, $val", IntegerOp, + [(set (v4i32 VECREG:$rT), (or (v4i32 VECREG:$rA), + v4i32SExt10Imm:$val))]>; + +def ORIr32: + RI10Form<0b00100000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), + "ori\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (or R32C:$rA, i32ImmSExt10:$val))]>; + +// Hacked forms of or immediate to copy one 32- and 64-bit FP register +// to another. Do not match patterns. +def ORIf32: + RI10Form_1<0b00100000, (outs R32FP:$rT), (ins R32FP:$rA, s10imm_i32:$val), + "ori\t$rT, $rA, $val", IntegerOp, + [/* no pattern */]>; + +def ORIf64: + RI10Form_1<0b00100000, (outs R64FP:$rT), (ins R64FP:$rA, s10imm_i32:$val), + "ori\t$rT, $rA, $val", IntegerOp, + [/* no pattern */]>; + +def ORIr64: + RI10Form_1<0b00100000, (outs R64C:$rT), (ins R64C:$rA, s10imm_i32:$val), + "ori\t$rT, $rA, $val", IntegerOp, + [/* no pattern */]>; + +// ORI2To4: hacked version of the ori instruction to extend 16-bit quantities +// to 32-bit quantities. used exclusively to match "anyext" conversions (vide +// infra "anyext 16->32" pattern.) +def ORI2To4: + RI10Form<0b00100000, (outs R32C:$rT), (ins R16C:$rA, s10imm_i32:$val), + "ori\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (or (anyext R16C:$rA), i32ImmSExt10:$val))]>; + +// ORX: "or" across the vector: or's $rA's word slots leaving the result in +// $rT[0], slots 1-3 are zeroed. +// +// Needs to match an intrinsic pattern. +def ORXv4i32: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "orx\t$rT, $rA, $rB", IntegerOp, + []>; + +def XORv16i8: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (xor (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; + +def XORv8i16: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (xor (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def XORv4i32: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def XORr32: + RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (xor R32C:$rA, R32C:$rB))]>; + +//==---------------------------------------------------------- +// Special forms for floating point instructions. +// Bitwise ORs and ANDs don't make sense for normal floating +// point numbers. These operations (fneg and fabs), however, +// require bitwise logical ops to manipulate the sign bit. +def XORfneg32: + RRForm<0b10010010000, (outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [/* Intentionally does not match a pattern, see fneg32 */]>; + +// KLUDGY! Better way to do this without a VECREG? bitconvert? +// VECREG is assumed to contain two identical 64-bit masks, so +// it doesn't matter which word we select for the xor +def XORfneg64: + RRForm<0b10010010000, (outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [/* Intentionally does not match a pattern, see fneg64 */]>; + +// Could use XORv4i32, but will use this for clarity +def XORfnegvec: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [/* Intentionally does not match a pattern, see fneg{32,64} */]>; + +//==---------------------------------------------------------- + +def XORr16: + RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "xor\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (xor R16C:$rA, R16C:$rB))]>; + +def XORBIv16i8: + RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "xorbi\t$rT, $rA, $val", IntegerOp, + [(set (v16i8 VECREG:$rT), (xor (v16i8 VECREG:$rA), v16i8U8Imm:$val))]>; + +def XORHIv8i16: + RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "xorhi\t$rT, $rA, $val", IntegerOp, + [(set (v8i16 VECREG:$rT), (xor (v8i16 VECREG:$rA), + v8i16SExt10Imm:$val))]>; + +def XORHIr16: + RI10Form<0b10100000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "xorhi\t$rT, $rA, $val", IntegerOp, + [(set R16C:$rT, (xor R16C:$rA, i16ImmSExt10:$val))]>; + +def XORIv4i32: + RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "xori\t$rT, $rA, $val", IntegerOp, + [(set (v4i32 VECREG:$rT), (xor (v4i32 VECREG:$rA), + v4i32SExt10Imm:$val))]>; + +def XORIr32: + RI10Form<0b00100000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), + "xori\t$rT, $rA, $val", IntegerOp, + [(set R32C:$rT, (xor R32C:$rA, i32ImmSExt10:$val))]>; + +// NAND: +def NANDv16i8: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nand\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (vnot (and (v16i8 VECREG:$rA), + (v16i8 VECREG:$rB))))]>; + +def NANDv8i16: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nand\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (vnot (and (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB))))]>; + +def NANDv4i32: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nand\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (vnot (and (v4i32 VECREG:$rA), + (v4i32 VECREG:$rB))))]>; + +def NANDr32: + RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "nand\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (not (and R32C:$rA, R32C:$rB)))]>; + +def NANDr16: + RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "nand\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (not (and R16C:$rA, R16C:$rB)))]>; + +// NOR: +def NORv16i8: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nor\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (vnot (or (v16i8 VECREG:$rA), + (v16i8 VECREG:$rB))))]>; + +def NORv8i16: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nor\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (vnot (or (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB))))]>; + +def NORv4i32: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nor\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (vnot (or (v4i32 VECREG:$rA), + (v4i32 VECREG:$rB))))]>; + +def NORr32: + RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "nor\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (not (or R32C:$rA, R32C:$rB)))]>; + +def NORr16: + RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "nor\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (not (or R16C:$rA, R16C:$rB)))]>; + +// EQV: Equivalence (1 for each same bit, otherwise 0) +def EQVv16i8: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "eqv\t$rT, $rA, $rB", IntegerOp, + [(set (v16i8 VECREG:$rT), (or (and (v16i8 VECREG:$rA), + (v16i8 VECREG:$rB)), + (and (vnot (v16i8 VECREG:$rA)), + (vnot (v16i8 VECREG:$rB)))))]>; + +def : Pat<(xor (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rB))), + (EQVv16i8 VECREG:$rA, VECREG:$rB)>; + +def : Pat<(xor (vnot (v16i8 VECREG:$rA)), (v16i8 VECREG:$rB)), + (EQVv16i8 VECREG:$rA, VECREG:$rB)>; + +def EQVv8i16: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "eqv\t$rT, $rA, $rB", IntegerOp, + [(set (v8i16 VECREG:$rT), (or (and (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)), + (and (vnot (v8i16 VECREG:$rA)), + (vnot (v8i16 VECREG:$rB)))))]>; + +def : Pat<(xor (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rB))), + (EQVv8i16 VECREG:$rA, VECREG:$rB)>; + +def : Pat<(xor (vnot (v8i16 VECREG:$rA)), (v8i16 VECREG:$rB)), + (EQVv8i16 VECREG:$rA, VECREG:$rB)>; + +def EQVv4i32: + RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "eqv\t$rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), (or (and (v4i32 VECREG:$rA), + (v4i32 VECREG:$rB)), + (and (vnot (v4i32 VECREG:$rA)), + (vnot (v4i32 VECREG:$rB)))))]>; + +def : Pat<(xor (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rB))), + (EQVv4i32 VECREG:$rA, VECREG:$rB)>; + +def : Pat<(xor (vnot (v4i32 VECREG:$rA)), (v4i32 VECREG:$rB)), + (EQVv4i32 VECREG:$rA, VECREG:$rB)>; + +def EQVr32: + RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "eqv\t$rT, $rA, $rB", IntegerOp, + [(set R32C:$rT, (or (and R32C:$rA, R32C:$rB), + (and (not R32C:$rA), (not R32C:$rB))))]>; + +def : Pat<(xor R32C:$rA, (not R32C:$rB)), + (EQVr32 R32C:$rA, R32C:$rB)>; + +def : Pat<(xor (not R32C:$rA), R32C:$rB), + (EQVr32 R32C:$rA, R32C:$rB)>; + +def EQVr16: + RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "eqv\t$rT, $rA, $rB", IntegerOp, + [(set R16C:$rT, (or (and R16C:$rA, R16C:$rB), + (and (not R16C:$rA), (not R16C:$rB))))]>; + +def : Pat<(xor R16C:$rA, (not R16C:$rB)), + (EQVr16 R16C:$rA, R16C:$rB)>; + +def : Pat<(xor (not R16C:$rA), R16C:$rB), + (EQVr16 R16C:$rA, R16C:$rB)>; + +// gcc optimizes (p & q) | (~p & ~q) -> ~(p | q) | (p & q), so match that +// pattern also: +def : Pat<(or (vnot (or (v16i8 VECREG:$rA), (v16i8 VECREG:$rB))), + (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rB))), + (EQVv16i8 VECREG:$rA, VECREG:$rB)>; + +def : Pat<(or (vnot (or (v8i16 VECREG:$rA), (v8i16 VECREG:$rB))), + (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rB))), + (EQVv8i16 VECREG:$rA, VECREG:$rB)>; + +def : Pat<(or (vnot (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB))), + (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB))), + (EQVv4i32 VECREG:$rA, VECREG:$rB)>; + +def : Pat<(or (not (or R32C:$rA, R32C:$rB)), (and R32C:$rA, R32C:$rB)), + (EQVr32 R32C:$rA, R32C:$rB)>; + +def : Pat<(or (not (or R16C:$rA, R16C:$rB)), (and R16C:$rA, R16C:$rB)), + (EQVr16 R16C:$rA, R16C:$rB)>; + +// Select bits: +def SELBv16i8: + RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "selb\t$rT, $rA, $rB, $rC", IntegerOp, + [(set (v16i8 VECREG:$rT), + (SPUselb_v16i8 (v16i8 VECREG:$rA), (v16i8 VECREG:$rB), + (v16i8 VECREG:$rC)))]>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), + (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), + (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), + (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), + (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), + (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), + (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), + (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), + (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), + (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), + (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), + (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), + (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), + (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), + (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), + (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), + (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), + (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def SELBv8i16: + RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "selb\t$rT, $rA, $rB, $rC", IntegerOp, + [(set (v8i16 VECREG:$rT), + (SPUselb_v8i16 (v8i16 VECREG:$rA), (v8i16 VECREG:$rB), + (v8i16 VECREG:$rC)))]>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), + (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), + (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), + (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), + (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), + (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), + (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), + (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), + (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), + (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), + (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), + (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), + (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), + (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), + (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), + (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), + (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), + (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def SELBv4i32: + RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "selb\t$rT, $rA, $rB, $rC", IntegerOp, + [(set (v4i32 VECREG:$rT), + (SPUselb_v4i32 (v4i32 VECREG:$rA), (v4i32 VECREG:$rB), + (v4i32 VECREG:$rC)))]>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), + (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), + (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), + (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), + (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), + (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), + (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), + (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), + (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), + (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), + (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), + (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), + (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), + (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), + (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), + (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), + (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), + (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def SELBr32: + RRRForm<0b1000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC), + "selb\t$rT, $rA, $rB, $rC", IntegerOp, + []>; + +// And the various patterns that can be matched... (all 8 of them :-) +def : Pat<(or (and R32C:$rA, R32C:$rC), + (and R32C:$rB, (not R32C:$rC))), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and R32C:$rC, R32C:$rA), + (and R32C:$rB, (not R32C:$rC))), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and R32C:$rA, R32C:$rC), + (and (not R32C:$rC), R32C:$rB)), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and R32C:$rC, R32C:$rA), + (and (not R32C:$rC), R32C:$rB)), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and R32C:$rA, (not R32C:$rC)), + (and R32C:$rB, R32C:$rC)), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and R32C:$rA, (not R32C:$rC)), + (and R32C:$rC, R32C:$rB)), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and (not R32C:$rC), R32C:$rA), + (and R32C:$rB, R32C:$rC)), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def : Pat<(or (and (not R32C:$rC), R32C:$rA), + (and R32C:$rC, R32C:$rB)), + (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; + +def SELBr16: + RRRForm<0b1000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB, R16C:$rC), + "selb\t$rT, $rA, $rB, $rC", IntegerOp, + []>; + +def : Pat<(or (and R16C:$rA, R16C:$rC), + (and R16C:$rB, (not R16C:$rC))), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and R16C:$rC, R16C:$rA), + (and R16C:$rB, (not R16C:$rC))), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and R16C:$rA, R16C:$rC), + (and (not R16C:$rC), R16C:$rB)), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and R16C:$rC, R16C:$rA), + (and (not R16C:$rC), R16C:$rB)), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and R16C:$rA, (not R16C:$rC)), + (and R16C:$rB, R16C:$rC)), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and R16C:$rA, (not R16C:$rC)), + (and R16C:$rC, R16C:$rB)), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and (not R16C:$rC), R16C:$rA), + (and R16C:$rB, R16C:$rC)), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +def : Pat<(or (and (not R16C:$rC), R16C:$rA), + (and R16C:$rC, R16C:$rB)), + (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; + +//===----------------------------------------------------------------------===// +// Vector shuffle... +//===----------------------------------------------------------------------===// + +def SHUFB: + RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "shufb\t$rT, $rA, $rB, $rC", IntegerOp, + [/* insert intrinsic here */]>; + +// SPUshuffle is generated in LowerVECTOR_SHUFFLE and gets replaced with SHUFB. +// See the SPUshuffle SDNode operand above, which sets up the DAG pattern +// matcher to emit something when the LowerVECTOR_SHUFFLE generates a node with +// the SPUISD::SHUFB opcode. +def : Pat<(SPUshuffle (v16i8 VECREG:$rA), (v16i8 VECREG:$rB), VECREG:$rC), + (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(SPUshuffle (v8i16 VECREG:$rA), (v8i16 VECREG:$rB), VECREG:$rC), + (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(SPUshuffle (v4i32 VECREG:$rA), (v4i32 VECREG:$rB), VECREG:$rC), + (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : Pat<(SPUshuffle (v2i64 VECREG:$rA), (v2i64 VECREG:$rB), VECREG:$rC), + (SHUFB VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +//===----------------------------------------------------------------------===// +// Shift and rotate group: +//===----------------------------------------------------------------------===// + +def SHLHv8i16: + RRForm<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB), + "shlh\t$rT, $rA, $rB", RotateShift, + [(set (v8i16 VECREG:$rT), + (SPUvec_shl_v8i16 (v8i16 VECREG:$rA), R16C:$rB))]>; + +// $rB gets promoted to 32-bit register type when confronted with +// this llvm assembly code: +// +// define i16 @shlh_i16_1(i16 %arg1, i16 %arg2) { +// %A = shl i16 %arg1, %arg2 +// ret i16 %A +// } +// +// However, we will generate this code when lowering 8-bit shifts and rotates. + +def SHLHr16: + RRForm<0b11111010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "shlh\t$rT, $rA, $rB", RotateShift, + [(set R16C:$rT, (shl R16C:$rA, R16C:$rB))]>; + +def SHLHr16_r32: + RRForm<0b11111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB), + "shlh\t$rT, $rA, $rB", RotateShift, + [(set R16C:$rT, (shl R16C:$rA, R32C:$rB))]>; + +def SHLHIv8i16: + RI7Form<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "shlhi\t$rT, $rA, $val", RotateShift, + [(set (v8i16 VECREG:$rT), + (SPUvec_shl_v8i16 (v8i16 VECREG:$rA), (i16 uimm7:$val)))]>; + +def : Pat<(SPUvec_shl_v8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val)), + (SHLHIv8i16 VECREG:$rA, imm:$val)>; + +def SHLHIr16: + RI7Form<0b11111010000, (outs R16C:$rT), (ins R16C:$rA, u7imm_i32:$val), + "shlhi\t$rT, $rA, $val", RotateShift, + [(set R16C:$rT, (shl R16C:$rA, (i32 uimm7:$val)))]>; + +def : Pat<(shl R16C:$rA, (i16 uimm7:$val)), + (SHLHIr16 R16C:$rA, uimm7:$val)>; + +def SHLv4i32: + RRForm<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB), + "shl\t$rT, $rA, $rB", RotateShift, + [(set (v4i32 VECREG:$rT), + (SPUvec_shl_v4i32 (v4i32 VECREG:$rA), R16C:$rB))]>; + +def SHLr32: + RRForm<0b11111010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "shl\t$rT, $rA, $rB", RotateShift, + [(set R32C:$rT, (shl R32C:$rA, R32C:$rB))]>; + +def SHLIv4i32: + RI7Form<0b11111010000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "shli\t$rT, $rA, $val", RotateShift, + [(set (v4i32 VECREG:$rT), + (SPUvec_shl_v4i32 (v4i32 VECREG:$rA), (i16 uimm7:$val)))]>; + +def: Pat<(SPUvec_shl_v4i32 (v4i32 VECREG:$rA), (i32 uimm7:$val)), + (SHLIv4i32 VECREG:$rA, uimm7:$val)>; + +def SHLIr32: + RI7Form<0b11111010000, (outs R32C:$rT), (ins R32C:$rA, u7imm_i32:$val), + "shli\t$rT, $rA, $val", RotateShift, + [(set R32C:$rT, (shl R32C:$rA, (i32 uimm7:$val)))]>; + +def : Pat<(shl R32C:$rA, (i16 uimm7:$val)), + (SHLIr32 R32C:$rA, uimm7:$val)>; + +// SHLQBI vec form: Note that this will shift the entire vector (the 128-bit +// register) to the left. Vector form is here to ensure type correctness. +def SHLQBIvec: + RRForm<0b11011011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "shlqbi\t$rT, $rA, $rB", RotateShift, + [/* intrinsic */]>; + +// See note above on SHLQBI. +def SHLQBIIvec: + RI7Form<0b11011111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "shlqbii\t$rT, $rA, $val", RotateShift, + [/* intrinsic */]>; + +// SHLQBY, SHLQBYI vector forms: Shift the entire vector to the left by bytes, +// not by bits. +def SHLQBYvec: + RI7Form<0b11111011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "shlqbyi\t$rT, $rA, $rB", RotateShift, + [/* intrinsic */]>; + +def SHLQBYIvec: + RI7Form<0b11111111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "shlqbyi\t$rT, $rA, $val", RotateShift, + [/* intrinsic */]>; + +// ROTH v8i16 form: +def ROTHv8i16: + RRForm<0b00111010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "roth\t$rT, $rA, $rB", RotateShift, + [(set (v8i16 VECREG:$rT), + (SPUvec_rotl_v8i16 VECREG:$rA, VECREG:$rB))]>; + +def ROTHr16: + RRForm<0b00111010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "roth\t$rT, $rA, $rB", RotateShift, + [(set R16C:$rT, (rotl R16C:$rA, R16C:$rB))]>; + +def ROTHr16_r32: + RRForm<0b00111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB), + "roth\t$rT, $rA, $rB", RotateShift, + [(set R16C:$rT, (rotl R16C:$rA, R32C:$rB))]>; + +def ROTHIv8i16: + RI7Form<0b00111110000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "rothi\t$rT, $rA, $val", RotateShift, + [(set (v8i16 VECREG:$rT), + (SPUvec_rotl_v8i16 VECREG:$rA, (i16 uimm7:$val)))]>; + +def : Pat<(SPUvec_rotl_v8i16 VECREG:$rA, (i16 uimm7:$val)), + (ROTHIv8i16 VECREG:$rA, imm:$val)>; + +def : Pat<(SPUvec_rotl_v8i16 VECREG:$rA, (i32 uimm7:$val)), + (ROTHIv8i16 VECREG:$rA, imm:$val)>; + +def ROTHIr16: + RI7Form<0b00111110000, (outs R16C:$rT), (ins R16C:$rA, u7imm:$val), + "rothi\t$rT, $rA, $val", RotateShift, + [(set R16C:$rT, (rotl R16C:$rA, (i16 uimm7:$val)))]>; + +def ROTHIr16_i32: + RI7Form<0b00111110000, (outs R16C:$rT), (ins R16C:$rA, u7imm_i32:$val), + "rothi\t$rT, $rA, $val", RotateShift, + [(set R16C:$rT, (rotl R16C:$rA, (i32 uimm7:$val)))]>; + +def ROTv4i32: + RRForm<0b00011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), + "rot\t$rT, $rA, $rB", RotateShift, + [(set (v4i32 VECREG:$rT), + (SPUvec_rotl_v4i32 (v4i32 VECREG:$rA), R32C:$rB))]>; + +def ROTr32: + RRForm<0b00011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "rot\t$rT, $rA, $rB", RotateShift, + [(set R32C:$rT, (rotl R32C:$rA, R32C:$rB))]>; + +def ROTIv4i32: + RI7Form<0b00011110000, (outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val), + "roti\t$rT, $rA, $val", RotateShift, + [(set (v4i32 VECREG:$rT), + (SPUvec_rotl_v4i32 (v4i32 VECREG:$rA), (i32 uimm7:$val)))]>; + +def : Pat<(SPUvec_rotl_v4i32 (v4i32 VECREG:$rA), (i16 uimm7:$val)), + (ROTIv4i32 VECREG:$rA, imm:$val)>; + +def ROTIr32: + RI7Form<0b00011110000, (outs R32C:$rT), (ins R32C:$rA, u7imm_i32:$val), + "roti\t$rT, $rA, $val", RotateShift, + [(set R32C:$rT, (rotl R32C:$rA, (i32 uimm7:$val)))]>; + +def ROTIr32_i16: + RI7Form<0b00111110000, (outs R32C:$rT), (ins R32C:$rA, u7imm:$val), + "roti\t$rT, $rA, $val", RotateShift, + [(set R32C:$rT, (rotl R32C:$rA, (i16 uimm7:$val)))]>; + +// ROTQBY* vector forms: This rotates the entire vector, but vector registers +// are used here for type checking (instances where ROTQBI is used actually +// use vector registers) +def ROTQBYvec: + RRForm<0b00111011100, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB), + "rotqby\t$rT, $rA, $rB", RotateShift, + [(set (v16i8 VECREG:$rT), (SPUrotbytes_left (v16i8 VECREG:$rA), R16C:$rB))]>; + +def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R16C:$rB), + (ROTQBYvec VECREG:$rA, R16C:$rB)>; + +// See ROTQBY note above. +def ROTQBYIvec: + RI7Form<0b00111111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "rotqbyi\t$rT, $rA, $val", RotateShift, + [(set (v16i8 VECREG:$rT), + (SPUrotbytes_left (v16i8 VECREG:$rA), (i16 uimm7:$val)))]>; + +def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), (i16 uimm7:$val)), + (ROTQBYIvec VECREG:$rA, uimm7:$val)>; + +// See ROTQBY note above. +def ROTQBYBIvec: + RI7Form<0b00110011100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), + "rotqbybi\t$rT, $rA, $val", RotateShift, + [/* intrinsic */]>; + +// See ROTQBY note above. +// +// Assume that the user of this instruction knows to shift the rotate count +// into bit 29 +def ROTQBIvec: + RRForm<0b00011011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "rotqbi\t$rT, $rA, $rB", RotateShift, + [/* insert intrinsic here */]>; + +// See ROTQBY note above. +def ROTQBIIvec: + RI7Form<0b00011111100, (outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val), + "rotqbii\t$rT, $rA, $val", RotateShift, + [/* insert intrinsic here */]>; + +// ROTHM v8i16 form: +// NOTE(1): No vector rotate is generated by the C/C++ frontend (today), +// so this only matches a synthetically generated/lowered code +// fragment. +// NOTE(2): $rB must be negated before the right rotate! +def ROTHMv8i16: + RRForm<0b10111010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), + "rothm\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), R32C:$rB), + (ROTHMv8i16 VECREG:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), R16C:$rB), + (ROTHMv8i16 VECREG:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def : Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), /* R8C */ R16C:$rB), + (ROTHMv8i16 VECREG:$rA, + (SFIr32 (XSHWr16 /* (XSBHr8 R8C */ R16C:$rB) /*)*/, 0))>; + +// ROTHM r16 form: Rotate 16-bit quantity to right, zero fill at the left +// Note: This instruction doesn't match a pattern because rB must be negated +// for the instruction to work. Thus, the pattern below the instruction! +def ROTHMr16: + RRForm<0b10111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB), + "rothm\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated! */]>; + +def : Pat<(srl R16C:$rA, R32C:$rB), + (ROTHMr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(srl R16C:$rA, R16C:$rB), + (ROTHMr16 R16C:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def : Pat<(srl R16C:$rA, /* R8C */ R16C:$rB), + (ROTHMr16 R16C:$rA, + (SFIr32 (XSHWr16 /* (XSBHr8 R8C */ R16C:$rB) /* ) */, 0))>; + +// ROTHMI v8i16 form: See the comment for ROTHM v8i16. The difference here is +// that the immediate can be complemented, so that the user doesn't have to +// worry about it. +def ROTHMIv8i16: + RI7Form<0b10111110000, (outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val), + "rothmi\t$rT, $rA, $val", RotateShift, + [(set (v8i16 VECREG:$rT), + (SPUvec_srl_v8i16 (v8i16 VECREG:$rA), (i32 imm:$val)))]>; + +def: Pat<(SPUvec_srl_v8i16 (v8i16 VECREG:$rA), (i16 imm:$val)), + (ROTHMIv8i16 VECREG:$rA, imm:$val)>; + +def ROTHMIr16: + RI7Form<0b10111110000, (outs R16C:$rT), (ins R16C:$rA, rothNeg7imm:$val), + "rothmi\t$rT, $rA, $val", RotateShift, + [(set R16C:$rT, (srl R16C:$rA, (i32 uimm7:$val)))]>; + +def: Pat<(srl R16C:$rA, (i16 uimm7:$val)), + (ROTHMIr16 R16C:$rA, uimm7:$val)>; + +// ROTM v4i32 form: See the ROTHM v8i16 comments. +def ROTMv4i32: + RRForm<0b10011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), + "rotm\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, R32C:$rB), + (ROTMv4i32 VECREG:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, R16C:$rB), + (ROTMv4i32 VECREG:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, /* R8C */ R16C:$rB), + (ROTMv4i32 VECREG:$rA, + (SFIr32 (XSHWr16 /* (XSBHr8 R8C */ R16C:$rB) /*)*/, 0))>; + +def ROTMr32: + RRForm<0b10011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "rotm\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(srl R32C:$rA, R32C:$rB), + (ROTMr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(srl R32C:$rA, R16C:$rB), + (ROTMr32 R32C:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +// ROTMI v4i32 form: See the comment for ROTHM v8i16. +def ROTMIv4i32: + RI7Form<0b10011110000, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), + "rotmi\t$rT, $rA, $val", RotateShift, + [(set (v4i32 VECREG:$rT), + (SPUvec_srl_v4i32 VECREG:$rA, (i32 uimm7:$val)))]>; + +def : Pat<(SPUvec_srl_v4i32 VECREG:$rA, (i16 uimm7:$val)), + (ROTMIv4i32 VECREG:$rA, uimm7:$val)>; + +// ROTMI r32 form: know how to complement the immediate value. +def ROTMIr32: + RI7Form<0b10011110000, (outs R32C:$rT), (ins R32C:$rA, rotNeg7imm:$val), + "rotmi\t$rT, $rA, $val", RotateShift, + [(set R32C:$rT, (srl R32C:$rA, (i32 uimm7:$val)))]>; + +def : Pat<(srl R32C:$rA, (i16 imm:$val)), + (ROTMIr32 R32C:$rA, uimm7:$val)>; + +// ROTQMBYvec: This is a vector form merely so that when used in an +// instruction pattern, type checking will succeed. This instruction assumes +// that the user knew to complement $rB. +def ROTQMBYvec: + RRForm<0b10111011100, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), + "rotqmby\t$rT, $rA, $rB", RotateShift, + [(set (v16i8 VECREG:$rT), + (SPUrotbytes_right_zfill (v16i8 VECREG:$rA), R32C:$rB))]>; + +def ROTQMBYIvec: + RI7Form<0b10111111100, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), + "rotqmbyi\t$rT, $rA, $val", RotateShift, + [(set (v16i8 VECREG:$rT), + (SPUrotbytes_right_zfill (v16i8 VECREG:$rA), (i32 uimm7:$val)))]>; + +def : Pat<(SPUrotbytes_right_zfill VECREG:$rA, (i16 uimm7:$val)), + (ROTQMBYIvec VECREG:$rA, uimm7:$val)>; + +def ROTQMBYBIvec: + RRForm<0b10110011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "rotqmbybi\t$rT, $rA, $rB", RotateShift, + [/* intrinsic */]>; + +def ROTQMBIvec: + RRForm<0b10011011100, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "rotqmbi\t$rT, $rA, $rB", RotateShift, + [/* intrinsic */]>; + +def ROTQMBIIvec: + RI7Form<0b10011111100, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), + "rotqmbii\t$rT, $rA, $val", RotateShift, + [/* intrinsic */]>; + +def ROTMAHv8i16: + RRForm<0b01111010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), + "rotmah\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(SPUvec_sra_v8i16 VECREG:$rA, R32C:$rB), + (ROTMAHv8i16 VECREG:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(SPUvec_sra_v8i16 VECREG:$rA, R16C:$rB), + (ROTMAHv8i16 VECREG:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def ROTMAHr16: + RRForm<0b01111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB), + "rotmah\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(sra R16C:$rA, R32C:$rB), + (ROTMAHr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(sra R16C:$rA, R16C:$rB), + (ROTMAHr16 R16C:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def ROTMAHIv8i16: + RRForm<0b01111110000, (outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val), + "rotmahi\t$rT, $rA, $val", RotateShift, + [(set (v8i16 VECREG:$rT), + (SPUvec_sra_v8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val)))]>; + +def : Pat<(SPUvec_sra_v8i16 (v8i16 VECREG:$rA), (i16 uimm7:$val)), + (ROTMAHIv8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val))>; + +def ROTMAHIr16: + RRForm<0b01111110000, (outs R16C:$rT), (ins R16C:$rA, rothNeg7imm_i16:$val), + "rotmahi\t$rT, $rA, $val", RotateShift, + [(set R16C:$rT, (sra R16C:$rA, (i16 uimm7:$val)))]>; + +def : Pat<(sra R16C:$rA, (i32 imm:$val)), + (ROTMAHIr16 R16C:$rA, uimm7:$val)>; + +def ROTMAv4i32: + RRForm<0b01011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), + "rotma\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(SPUvec_sra_v4i32 VECREG:$rA, R32C:$rB), + (ROTMAv4i32 (v4i32 VECREG:$rA), (SFIr32 R32C:$rB, 0))>; + +def : Pat<(SPUvec_sra_v4i32 VECREG:$rA, R16C:$rB), + (ROTMAv4i32 (v4i32 VECREG:$rA), + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def ROTMAr32: + RRForm<0b01011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "rotma\t$rT, $rA, $rB", RotateShift, + [/* see patterns below - $rB must be negated */]>; + +def : Pat<(sra R32C:$rA, R32C:$rB), + (ROTMAr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>; + +def : Pat<(sra R32C:$rA, R16C:$rB), + (ROTMAr32 R32C:$rA, + (SFIr32 (XSHWr16 R16C:$rB), 0))>; + +def ROTMAIv4i32: + RRForm<0b01011110000, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), + "rotmai\t$rT, $rA, $val", RotateShift, + [(set (v4i32 VECREG:$rT), + (SPUvec_sra_v4i32 VECREG:$rA, (i32 uimm7:$val)))]>; + +def : Pat<(SPUvec_sra_v4i32 VECREG:$rA, (i16 uimm7:$val)), + (ROTMAIv4i32 VECREG:$rA, uimm7:$val)>; + +def ROTMAIr32: + RRForm<0b01011110000, (outs R32C:$rT), (ins R32C:$rA, rotNeg7imm:$val), + "rotmai\t$rT, $rA, $val", RotateShift, + [(set R32C:$rT, (sra R32C:$rA, (i32 uimm7:$val)))]>; + +def : Pat<(sra R32C:$rA, (i16 uimm7:$val)), + (ROTMAIr32 R32C:$rA, uimm7:$val)>; + +//===----------------------------------------------------------------------===// +// Branch and conditionals: +//===----------------------------------------------------------------------===// + +let isTerminator = 1, isBarrier = 1 in { + // Halt If Equal (r32 preferred slot only, no vector form) + def HEQr32: + RRForm_3<0b00011011110, (outs), (ins R32C:$rA, R32C:$rB), + "heq\t$rA, $rB", BranchResolv, + [/* no pattern to match */]>; + + def HEQIr32 : + RI10Form_2<0b11111110, (outs), (ins R32C:$rA, s10imm:$val), + "heqi\t$rA, $val", BranchResolv, + [/* no pattern to match */]>; + + // HGT/HGTI: These instructions use signed arithmetic for the comparison, + // contrasting with HLGT/HLGTI, which use unsigned comparison: + def HGTr32: + RRForm_3<0b00011010010, (outs), (ins R32C:$rA, R32C:$rB), + "hgt\t$rA, $rB", BranchResolv, + [/* no pattern to match */]>; + + def HGTIr32: + RI10Form_2<0b11110010, (outs), (ins R32C:$rA, s10imm:$val), + "hgti\t$rA, $val", BranchResolv, + [/* no pattern to match */]>; + + def HLGTr32: + RRForm_3<0b00011011010, (outs), (ins R32C:$rA, R32C:$rB), + "hlgt\t$rA, $rB", BranchResolv, + [/* no pattern to match */]>; + + def HLGTIr32: + RI10Form_2<0b11111010, (outs), (ins R32C:$rA, s10imm:$val), + "hlgti\t$rA, $val", BranchResolv, + [/* no pattern to match */]>; +} + +// Comparison operators: + +def CEQBv16i8: + RRForm<0b00001011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ceqb\t$rT, $rA, $rB", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQBIv16i8: + RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, s7imm:$val), + "ceqbi\t$rT, $rA, $val", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQHr16: + RRForm<0b00010011110, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), + "ceqh\t$rT, $rA, $rB", ByteOp, + [/* no pattern to match */]>; + +def CEQHv8i16: + RRForm<0b00010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ceqh\t$rT, $rA, $rB", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQHIr16: + RI10Form<0b10111110, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), + "ceqhi\t$rT, $rA, $val", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQHIv8i16: + RI10Form<0b10111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ceqhi\t$rT, $rA, $val", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQr32: + RRForm<0b00000011110, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), + "ceq\t$rT, $rA, $rB", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQv4i32: + RRForm<0b00000011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ceq\t$rT, $rA, $rB", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQIr32: + RI10Form<0b00111110, (outs R32C:$rT), (ins R32C:$rA, s10imm:$val), + "ceqi\t$rT, $rA, $val", ByteOp, + [/* no pattern to match: intrinsic */]>; + +def CEQIv4i32: + RI10Form<0b00111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ceqi\t$rT, $rA, $val", ByteOp, + [/* no pattern to match: intrinsic */]>; + +let isCall = 1, + // All calls clobber the non-callee-saved registers: + Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, + R10,R11,R12,R13,R14,R15,R16,R17,R18,R19, + R20,R21,R22,R23,R24,R25,R26,R27,R28,R29, + R30,R31,R32,R33,R34,R35,R36,R37,R38,R39, + R40,R41,R42,R43,R44,R45,R46,R47,R48,R49, + R50,R51,R52,R53,R54,R55,R56,R57,R58,R59, + R60,R61,R62,R63,R64,R65,R66,R67,R68,R69, + R70,R71,R72,R73,R74,R75,R76,R77,R78,R79], + // All of these instructions use $lr (aka $0) + Uses = [R0] in { + // Branch relative and set link: Used if we actually know that the target + // is within [-32768, 32767] bytes of the target + def BRSL: + BranchSetLink<0b011001100, (outs), (ins relcalltarget:$func, variable_ops), + "brsl\t$$lr, $func", + [(SPUcall (SPUpcrel tglobaladdr:$func, 0))]>; + + // Branch absolute and set link: Used if we actually know that the target + // is an absolute address + def BRASL: + BranchSetLink<0b011001100, (outs), (ins calltarget:$func, variable_ops), + "brasl\t$$lr, $func", + [(SPUcall tglobaladdr:$func)]>; + + // Branch indirect and set link if external data. These instructions are not + // actually generated, matched by an intrinsic: + def BISLED_00: BISLEDForm<0b11, "bisled\t$$lr, $func", [/* empty pattern */]>; + def BISLED_E0: BISLEDForm<0b10, "bisled\t$$lr, $func", [/* empty pattern */]>; + def BISLED_0D: BISLEDForm<0b01, "bisled\t$$lr, $func", [/* empty pattern */]>; + def BISLED_ED: BISLEDForm<0b00, "bisled\t$$lr, $func", [/* empty pattern */]>; + + // Branch indirect and set link. This is the "X-form" address version of a + // function call + def BISL: + BIForm<0b10010101100, "bisl\t$$lr, $func", [(SPUcall R32C:$func)]>; +} + +// Unconditional branches: +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { + def BR : + UncondBranch<0b001001100, (outs), (ins brtarget:$dest), + "br\t$dest", + [(br bb:$dest)]>; + + // Unconditional, absolute address branch + def BRA: + UncondBranch<0b001100000, (outs), (ins brtarget:$dest), + "bra\t$dest", + [/* no pattern */]>; + + // Indirect branch + def BI: + BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>; + + // Various branches: + def BRNZ: + RI16Form<0b010000100, (outs), (ins R32C:$rCond, brtarget:$dest), + "brnz\t$rCond,$dest", + BranchResolv, + [(brcond R32C:$rCond, bb:$dest)]>; + + def BRZ: + RI16Form<0b000000100, (outs), (ins R32C:$rT, brtarget:$dest), + "brz\t$rT,$dest", + BranchResolv, + [/* no pattern */]>; + + def BRHNZ: + RI16Form<0b011000100, (outs), (ins R16C:$rCond, brtarget:$dest), + "brhnz\t$rCond,$dest", + BranchResolv, + [(brcond R16C:$rCond, bb:$dest)]>; + + def BRHZ: + RI16Form<0b001000100, (outs), (ins R16C:$rT, brtarget:$dest), + "brhz\t$rT,$dest", + BranchResolv, + [/* no pattern */]>; + +/* + def BINZ: + BICondForm<0b10010100100, "binz\t$rA, $func", + [(SPUbinz R32C:$rA, R32C:$func)]>; + + def BIZ: + BICondForm<0b00010100100, "biz\t$rA, $func", + [(SPUbiz R32C:$rA, R32C:$func)]>; +*/ +} + +def : Pat<(brcond (i16 (seteq R16C:$rA, 0)), bb:$dest), + (BRHZ R16C:$rA, bb:$dest)>; +def : Pat<(brcond (i16 (setne R16C:$rA, 0)), bb:$dest), + (BRHNZ R16C:$rA, bb:$dest)>; + +def : Pat<(brcond (i32 (seteq R32C:$rA, 0)), bb:$dest), + (BRZ R32C:$rA, bb:$dest)>; +def : Pat<(brcond (i32 (setne R32C:$rA, 0)), bb:$dest), + (BRZ R32C:$rA, bb:$dest)>; + +let isTerminator = 1, isBarrier = 1 in { + let isReturn = 1 in { + def RET: + RETForm<"bi\t$$lr", [(retflag)]>; + } +} + +//===----------------------------------------------------------------------===// +// Various brcond predicates: +//===----------------------------------------------------------------------===// +/* +def : Pat<(brcond (i32 (seteq R32C:$rA, 0)), bb:$dest), + (BRZ R32C:$rA, bb:$dest)>; + +def : Pat<(brcond (i32 (seteq R32C:$rA, R32C:$rB)), bb:$dest), + (BRNZ (CEQr32 R32C:$rA, R32C:$rB), bb:$dest)>; + +def : Pat<(brcond (i16 (seteq R16C:$rA, i16ImmSExt10:$val)), bb:$dest), + (BRHNZ (CEQHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; + +def : Pat<(brcond (i16 (seteq R16C:$rA, R16C:$rB)), bb:$dest), + (BRHNZ (CEQHr16 R16C:$rA, R16C:$rB), bb:$dest)>; +*/ + +//===----------------------------------------------------------------------===// +// Single precision floating point instructions +//===----------------------------------------------------------------------===// + +def FAv4f32: + RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fa\t$rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (fadd (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)))]>; + +def FAf32 : + RRForm<0b00100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), + "fa\t$rT, $rA, $rB", SPrecFP, + [(set R32FP:$rT, (fadd R32FP:$rA, R32FP:$rB))]>; + +def FSv4f32: + RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fs\t$rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (fsub (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)))]>; + +def FSf32 : + RRForm<0b10100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), + "fs\t$rT, $rA, $rB", SPrecFP, + [(set R32FP:$rT, (fsub R32FP:$rA, R32FP:$rB))]>; + +// Floating point reciprocal estimate +def FREv4f32 : + RRForm_1<0b00011101100, (outs VECREG:$rT), (ins VECREG:$rA), + "frest\t$rT, $rA", SPrecFP, + [(set (v4f32 VECREG:$rT), (SPUreciprocalEst (v4f32 VECREG:$rA)))]>; + +def FREf32 : + RRForm_1<0b00011101100, (outs R32FP:$rT), (ins R32FP:$rA), + "frest\t$rT, $rA", SPrecFP, + [(set R32FP:$rT, (SPUreciprocalEst R32FP:$rA))]>; + +// Floating point interpolate (used in conjunction with reciprocal estimate) +def FIv4f32 : + RRForm<0b00101011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fi\t$rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (SPUinterpolate (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def FIf32 : + RRForm<0b00101011110, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), + "fi\t$rT, $rA, $rB", SPrecFP, + [(set R32FP:$rT, (SPUinterpolate R32FP:$rA, R32FP:$rB))]>; + +// Floating Compare Equal +def FCEQf32 : + RRForm<0b01000011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), + "fceq\t$rT, $rA, $rB", SPrecFP, + [(set R32C:$rT, (setoeq R32FP:$rA, R32FP:$rB))]>; + +def FCMEQf32 : + RRForm<0b01010011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), + "fcmeq\t$rT, $rA, $rB", SPrecFP, + [(set R32C:$rT, (setoeq (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; + +def FCGTf32 : + RRForm<0b01000011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), + "fcgt\t$rT, $rA, $rB", SPrecFP, + [(set R32C:$rT, (setogt R32FP:$rA, R32FP:$rB))]>; + +def FCMGTf32 : + RRForm<0b01010011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), + "fcmgt\t$rT, $rA, $rB", SPrecFP, + [(set R32C:$rT, (setogt (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; + +// FP Status and Control Register Write +// Why isn't rT a don't care in the ISA? +// Should we create a special RRForm_3 for this guy and zero out the rT? +def FSCRWf32 : + RRForm_1<0b01011101110, (outs R32FP:$rT), (ins R32FP:$rA), + "fscrwr\t$rA", SPrecFP, + [/* This instruction requires an intrinsic. Note: rT is unused. */]>; + +// FP Status and Control Register Read +def FSCRRf32 : + RRForm_2<0b01011101110, (outs R32FP:$rT), (ins), + "fscrrd\t$rT", SPrecFP, + [/* This instruction requires an intrinsic */]>; + +// llvm instruction space +// How do these map onto cell instructions? +// fdiv rA rB +// frest rC rB # c = 1/b (both lines) +// fi rC rB rC +// fm rD rA rC # d = a * 1/b +// fnms rB rD rB rA # b = - (d * b - a) --should == 0 in a perfect world +// fma rB rB rC rD # b = b * c + d +// = -(d *b -a) * c + d +// = a * c - c ( a *b *c - a) + +// fcopysign (???) + +// Library calls: +// These llvm instructions will actually map to library calls. +// All that's needed, then, is to check that the appropriate library is +// imported and do a brsl to the proper function name. +// frem # fmod(x, y): x - (x/y) * y +// (Note: fmod(double, double), fmodf(float,float) +// fsqrt? +// fsin? +// fcos? +// Unimplemented SPU instruction space +// floating reciprocal absolute square root estimate (frsqest) + +// The following are probably just intrinsics +// status and control register write +// status and control register read + +//-------------------------------------- +// Floating point multiply instructions +//-------------------------------------- + +def FMv4f32: + RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fm\t$rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (fmul (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def FMf32 : + RRForm<0b01100011010, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), + "fm\t$rT, $rA, $rB", SPrecFP, + [(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>; + +// Floating point multiply and add +// e.g. d = c + (a * b) +def FMAv4f32: + RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "fma\t$rT, $rA, $rB, $rC", SPrecFP, + [(set (v4f32 VECREG:$rT), + (fadd (v4f32 VECREG:$rC), + (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB))))]>; + +def FMAf32: + RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), + "fma\t$rT, $rA, $rB, $rC", SPrecFP, + [(set R32FP:$rT, (fadd R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>; + +// FP multiply and subtract +// Subtracts value in rC from product +// res = a * b - c +def FMSv4f32 : + RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "fms\t$rT, $rA, $rB, $rC", SPrecFP, + [(set (v4f32 VECREG:$rT), + (fsub (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)), + (v4f32 VECREG:$rC)))]>; + +def FMSf32 : + RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), + "fms\t$rT, $rA, $rB, $rC", SPrecFP, + [(set R32FP:$rT, + (fsub (fmul R32FP:$rA, R32FP:$rB), R32FP:$rC))]>; + +// Floating Negative Mulitply and Subtract +// Subtracts product from value in rC +// res = fneg(fms a b c) +// = - (a * b - c) +// = c - a * b +// NOTE: subtraction order +// fsub a b = a - b +// fs a b = b - a? +def FNMSf32 : + RRRForm<0b1101, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), + "fnms\t$rT, $rA, $rB, $rC", SPrecFP, + [(set R32FP:$rT, (fsub R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>; + +def FNMSv4f32 : + RRRForm<0b1101, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "fnms\t$rT, $rA, $rB, $rC", SPrecFP, + [(set (v4f32 VECREG:$rT), + (fsub (v4f32 VECREG:$rC), + (fmul (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB))))]>; + +//-------------------------------------- +// Floating Point Conversions +// Signed conversions: +def CSiFv4f32: + CVTIntFPForm<0b0101101110, (outs VECREG:$rT), (ins VECREG:$rA), + "csflt\t$rT, $rA, 0", SPrecFP, + [(set (v4f32 VECREG:$rT), (sint_to_fp (v4i32 VECREG:$rA)))]>; + +// Convert signed integer to floating point +def CSiFf32 : + CVTIntFPForm<0b0101101110, (outs R32FP:$rT), (ins R32C:$rA), + "csflt\t$rT, $rA, 0", SPrecFP, + [(set R32FP:$rT, (sint_to_fp R32C:$rA))]>; + +// Convert unsigned into to float +def CUiFv4f32 : + CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), + "cuflt\t$rT, $rA, 0", SPrecFP, + [(set (v4f32 VECREG:$rT), (uint_to_fp (v4i32 VECREG:$rA)))]>; + +def CUiFf32 : + CVTIntFPForm<0b1101101110, (outs R32FP:$rT), (ins R32C:$rA), + "cuflt\t$rT, $rA, 0", SPrecFP, + [(set R32FP:$rT, (uint_to_fp R32C:$rA))]>; + +// Convert float to unsigned int +// Assume that scale = 0 + +def CFUiv4f32 : + CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), + "cfltu\t$rT, $rA, 0", SPrecFP, + [(set (v4i32 VECREG:$rT), (fp_to_uint (v4f32 VECREG:$rA)))]>; + +def CFUif32 : + CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA), + "cfltu\t$rT, $rA, 0", SPrecFP, + [(set R32C:$rT, (fp_to_uint R32FP:$rA))]>; + +// Convert float to signed int +// Assume that scale = 0 + +def CFSiv4f32 : + CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), + "cflts\t$rT, $rA, 0", SPrecFP, + [(set (v4i32 VECREG:$rT), (fp_to_sint (v4f32 VECREG:$rA)))]>; + +def CFSif32 : + CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA), + "cflts\t$rT, $rA, 0", SPrecFP, + [(set R32C:$rT, (fp_to_sint R32FP:$rA))]>; + +//===----------------------------------------------------------------------==// +// Single<->Double precision conversions +//===----------------------------------------------------------------------==// + +// NOTE: We use "vec" name suffix here to avoid confusion (e.g. input is a +// v4f32, output is v2f64--which goes in the name?) + +// Floating point extend single to double +// NOTE: Not sure if passing in v4f32 to FESDvec is correct since it +// operates on two double-word slots (i.e. 1st and 3rd fp numbers +// are ignored). +def FESDvec : + RRForm_1<0b00011101110, (outs VECREG:$rT), (ins VECREG:$rA), + "fesd\t$rT, $rA", SPrecFP, + [(set (v2f64 VECREG:$rT), (fextend (v4f32 VECREG:$rA)))]>; + +def FESDf32 : + RRForm_1<0b00011101110, (outs R64FP:$rT), (ins R32FP:$rA), + "fesd\t$rT, $rA", SPrecFP, + [(set R64FP:$rT, (fextend R32FP:$rA))]>; + +// Floating point round double to single +//def FRDSvec : +// RRForm_1<0b10011101110, (outs VECREG:$rT), (ins VECREG:$rA), +// "frds\t$rT, $rA,", SPrecFP, +// [(set (v4f32 R32FP:$rT), (fround (v2f64 R64FP:$rA)))]>; + +def FRDSf64 : + RRForm_1<0b10011101110, (outs R32FP:$rT), (ins R64FP:$rA), + "frds\t$rT, $rA", SPrecFP, + [(set R32FP:$rT, (fround R64FP:$rA))]>; + +//ToDo include anyextend? + +//===----------------------------------------------------------------------==// +// Double precision floating point instructions +//===----------------------------------------------------------------------==// +def FAf64 : + RRForm<0b00110011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), + "dfa\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fadd R64FP:$rA, R64FP:$rB))]>; + +def FAv2f64 : + RRForm<0b00110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfa\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (fadd (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; + +def FSf64 : + RRForm<0b10100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), + "dfs\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fsub R64FP:$rA, R64FP:$rB))]>; + +def FSv2f64 : + RRForm<0b10100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfs\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), + (fsub (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; + +def FMf64 : + RRForm<0b01100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), + "dfm\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fmul R64FP:$rA, R64FP:$rB))]>; + +def FMv2f64: + RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfm\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), + (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; + +def FMAf64: + RRForm<0b00111010110, (outs R64FP:$rT), + (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), + "dfma\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +def FMAv2f64: + RRForm<0b00111010110, (outs VECREG:$rT), + (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "dfma\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), + (fadd (v2f64 VECREG:$rC), + (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB))))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +def FMSf64 : + RRForm<0b10111010110, (outs R64FP:$rT), + (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), + "dfms\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +def FMSv2f64 : + RRForm<0b10111010110, (outs VECREG:$rT), + (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "dfms\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), + (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)), + (v2f64 VECREG:$rC)))]>; + +// FNMS: - (a * b - c) +// - (a * b) + c => c - (a * b) +def FNMSf64 : + RRForm<0b01111010110, (outs R64FP:$rT), + (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), + "dfnms\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fsub R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +def : Pat<(fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)), + (FNMSf64 R64FP:$rA, R64FP:$rB, R64FP:$rC)>; + +def FNMSv2f64 : + RRForm<0b01111010110, (outs VECREG:$rT), + (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "dfnms\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), + (fsub (v2f64 VECREG:$rC), + (fmul (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB))))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +def : Pat<(fneg (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)), + (v2f64 VECREG:$rC))), + (FNMSv2f64 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +// - (a * b + c) +// - (a * b) - c +def FNMAf64 : + RRForm<0b11111010110, (outs R64FP:$rT), + (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), + "dfnma\t$rT, $rA, $rB", DPrecFP, + [(set R64FP:$rT, (fneg (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB))))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +def FNMAv2f64 : + RRForm<0b11111010110, (outs VECREG:$rT), + (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "dfnma\t$rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), + (fneg (fadd (v2f64 VECREG:$rC), + (fmul (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))))]>, + RegConstraint<"$rC = $rT">, + NoEncode<"$rC">; + +//===----------------------------------------------------------------------==// +// Floating point negation and absolute value +//===----------------------------------------------------------------------==// + +def : Pat<(fneg (v4f32 VECREG:$rA)), + (XORfnegvec (v4f32 VECREG:$rA), + (v4f32 (ILHUv4i32 0x8000)))>; + +def : Pat<(fneg R32FP:$rA), + (XORfneg32 R32FP:$rA, (ILHUr32 0x8000))>; + +def : Pat<(fneg (v2f64 VECREG:$rA)), + (XORfnegvec (v2f64 VECREG:$rA), + (v2f64 (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80)))>; + +def : Pat<(fneg R64FP:$rA), + (XORfneg64 R64FP:$rA, + (ANDBIv16i8 (FSMBIv16i8 0x8080), 0x80))>; + +// Floating point absolute value + +def : Pat<(fabs R32FP:$rA), + (ANDfabs32 R32FP:$rA, (IOHLr32 (ILHUr32 0x7fff), 0xffff))>; + +def : Pat<(fabs (v4f32 VECREG:$rA)), + (ANDfabsvec (v4f32 VECREG:$rA), + (v4f32 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>; + +def : Pat<(fabs R64FP:$rA), + (ANDfabs64 R64FP:$rA, (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f))>; + +def : Pat<(fabs (v2f64 VECREG:$rA)), + (ANDfabsvec (v2f64 VECREG:$rA), + (v2f64 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>; + +//===----------------------------------------------------------------------===// +// Execution, Load NOP (execute NOPs belong in even pipeline, load NOPs belong +// in the odd pipeline) +//===----------------------------------------------------------------------===// + +def ENOP : I<(outs), (ins), "enop", ExecNOP> { + let Pattern = []; + + let Inst{0-10} = 0b10000000010; + let Inst{11-17} = 0; + let Inst{18-24} = 0; + let Inst{25-31} = 0; +} + +def LNOP : I<(outs), (ins), "lnop", LoadNOP> { + let Pattern = []; + + let Inst{0-10} = 0b10000000000; + let Inst{11-17} = 0; + let Inst{18-24} = 0; + let Inst{25-31} = 0; +} + +//===----------------------------------------------------------------------===// +// Bit conversions (type conversions between vector/packed types) +// NOTE: Promotions are handled using the XS* instructions. Truncation +// is not handled. +//===----------------------------------------------------------------------===// +def : Pat<(v16i8 (bitconvert (v8i16 VECREG:$src))), (v16i8 VECREG:$src)>; +def : Pat<(v16i8 (bitconvert (v4i32 VECREG:$src))), (v16i8 VECREG:$src)>; +def : Pat<(v16i8 (bitconvert (v2i64 VECREG:$src))), (v16i8 VECREG:$src)>; +def : Pat<(v16i8 (bitconvert (v4f32 VECREG:$src))), (v16i8 VECREG:$src)>; +def : Pat<(v16i8 (bitconvert (v2f64 VECREG:$src))), (v16i8 VECREG:$src)>; + +def : Pat<(v8i16 (bitconvert (v16i8 VECREG:$src))), (v8i16 VECREG:$src)>; +def : Pat<(v8i16 (bitconvert (v4i32 VECREG:$src))), (v8i16 VECREG:$src)>; +def : Pat<(v8i16 (bitconvert (v2i64 VECREG:$src))), (v8i16 VECREG:$src)>; +def : Pat<(v8i16 (bitconvert (v4f32 VECREG:$src))), (v8i16 VECREG:$src)>; +def : Pat<(v8i16 (bitconvert (v2f64 VECREG:$src))), (v8i16 VECREG:$src)>; + +def : Pat<(v4i32 (bitconvert (v16i8 VECREG:$src))), (v4i32 VECREG:$src)>; +def : Pat<(v4i32 (bitconvert (v8i16 VECREG:$src))), (v4i32 VECREG:$src)>; +def : Pat<(v4i32 (bitconvert (v2i64 VECREG:$src))), (v4i32 VECREG:$src)>; +def : Pat<(v4i32 (bitconvert (v4f32 VECREG:$src))), (v4i32 VECREG:$src)>; +def : Pat<(v4i32 (bitconvert (v2f64 VECREG:$src))), (v4i32 VECREG:$src)>; + +def : Pat<(v2i64 (bitconvert (v16i8 VECREG:$src))), (v2i64 VECREG:$src)>; +def : Pat<(v2i64 (bitconvert (v8i16 VECREG:$src))), (v2i64 VECREG:$src)>; +def : Pat<(v2i64 (bitconvert (v4i32 VECREG:$src))), (v2i64 VECREG:$src)>; +def : Pat<(v2i64 (bitconvert (v4f32 VECREG:$src))), (v2i64 VECREG:$src)>; +def : Pat<(v2i64 (bitconvert (v2f64 VECREG:$src))), (v2i64 VECREG:$src)>; + +def : Pat<(v4f32 (bitconvert (v16i8 VECREG:$src))), (v4f32 VECREG:$src)>; +def : Pat<(v4f32 (bitconvert (v8i16 VECREG:$src))), (v4f32 VECREG:$src)>; +def : Pat<(v4f32 (bitconvert (v2i64 VECREG:$src))), (v4f32 VECREG:$src)>; +def : Pat<(v4f32 (bitconvert (v4i32 VECREG:$src))), (v4f32 VECREG:$src)>; +def : Pat<(v4f32 (bitconvert (v2f64 VECREG:$src))), (v4f32 VECREG:$src)>; + +def : Pat<(v2f64 (bitconvert (v16i8 VECREG:$src))), (v2f64 VECREG:$src)>; +def : Pat<(v2f64 (bitconvert (v8i16 VECREG:$src))), (v2f64 VECREG:$src)>; +def : Pat<(v2f64 (bitconvert (v4i32 VECREG:$src))), (v2f64 VECREG:$src)>; +def : Pat<(v2f64 (bitconvert (v2i64 VECREG:$src))), (v2f64 VECREG:$src)>; +def : Pat<(v2f64 (bitconvert (v2f64 VECREG:$src))), (v2f64 VECREG:$src)>; + +def : Pat<(f32 (bitconvert (i32 R32C:$src))), (f32 R32FP:$src)>; + +//===----------------------------------------------------------------------===// +// Instruction patterns: +//===----------------------------------------------------------------------===// + +// General 32-bit constants: +def : Pat<(i32 imm:$imm), + (IOHLr32 (ILHUr32 (HI16 imm:$imm)), (LO16 imm:$imm))>; + +// Single precision float constants: +def : Pat<(SPUFPconstant (f32 fpimm:$imm)), + (IOHLf32 (ILHUf32 (HI16_f32 fpimm:$imm)), (LO16_f32 fpimm:$imm))>; + +// General constant 32-bit vectors +def : Pat<(v4i32 v4i32Imm:$imm), + (IOHLvec (v4i32 (ILHUv4i32 (HI16_vec v4i32Imm:$imm))), + (LO16_vec v4i32Imm:$imm))>; + +//===----------------------------------------------------------------------===// +// Call instruction patterns: +//===----------------------------------------------------------------------===// +// Return void +def : Pat<(ret), + (RET)>; + +//===----------------------------------------------------------------------===// +// Zero/Any/Sign extensions +//===----------------------------------------------------------------------===// + +// zext 1->32: Zero extend i1 to i32 +def : Pat<(SPUextract_i1_zext R32C:$rSrc), + (ANDIr32 R32C:$rSrc, 0x1)>; + +// sext 8->32: Sign extend bytes to words +def : Pat<(sext_inreg R32C:$rSrc, i8), + (XSHWr32 (XSBHr32 R32C:$rSrc))>; + +def : Pat<(SPUextract_i8_sext VECREG:$rSrc), + (XSHWr32 (XSBHr32 (ORi32_v4i32 (v4i32 VECREG:$rSrc), + (v4i32 VECREG:$rSrc))))>; + +def : Pat<(SPUextract_i8_zext VECREG:$rSrc), + (ANDIr32 (ORi32_v4i32 (v4i32 VECREG:$rSrc), (v4i32 VECREG:$rSrc)), + 0xff)>; + +// zext 16->32: Zero extend halfwords to words (note that we have to juggle the +// 0xffff constant since it will not fit into an immediate.) +def : Pat<(i32 (zext R16C:$rSrc)), + (AND2To4 R16C:$rSrc, (ILAr32 0xffff))>; + +def : Pat<(i32 (zext (and R16C:$rSrc, 0xf))), + (ANDI2To4 R16C:$rSrc, 0xf)>; + +def : Pat<(i32 (zext (and R16C:$rSrc, 0xff))), + (ANDI2To4 R16C:$rSrc, 0xff)>; + +def : Pat<(i32 (zext (and R16C:$rSrc, 0xfff))), + (ANDI2To4 R16C:$rSrc, 0xfff)>; + +// anyext 16->32: Extend 16->32 bits, irrespective of sign +def : Pat<(i32 (anyext R16C:$rSrc)), + (ORI2To4 R16C:$rSrc, 0)>; + +//===----------------------------------------------------------------------===// +// Address translation: SPU, like PPC, has to split addresses into high and +// low parts in order to load them into a register. +//===----------------------------------------------------------------------===// + +def : Pat<(SPUhi tglobaladdr:$in, 0), (ILHUhi tglobaladdr:$in)>; +def : Pat<(SPUlo tglobaladdr:$in, 0), (ILAlo tglobaladdr:$in)>; +def : Pat<(SPUdform tglobaladdr:$in, imm:$imm), (ILAlsa tglobaladdr:$in)>; +def : Pat<(SPUhi tconstpool:$in , 0), (ILHUhi tconstpool:$in)>; +def : Pat<(SPUlo tconstpool:$in , 0), (ILAlo tconstpool:$in)>; +def : Pat<(SPUdform tconstpool:$in, imm:$imm), (ILAlsa tconstpool:$in)>; +def : Pat<(SPUhi tjumptable:$in, 0), (ILHUhi tjumptable:$in)>; +def : Pat<(SPUlo tjumptable:$in, 0), (ILAlo tjumptable:$in)>; +def : Pat<(SPUdform tjumptable:$in, imm:$imm), (ILAlsa tjumptable:$in)>; + +// Force load of global address to a register. These forms show up in +// SPUISD::DFormAddr pseudo instructions: +/* +def : Pat<(add tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>; +def : Pat<(add tconstpool:$in, 0), (ILAlsa tglobaladdr:$in)>; +def : Pat<(add tjumptable:$in, 0), (ILAlsa tglobaladdr:$in)>; + */ +// Instrinsics: +include "CellSDKIntrinsics.td" From dpatel at apple.com Tue Dec 4 16:54:48 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 04 Dec 2007 22:54:48 -0000 Subject: [llvm-commits] [llvm] r44586 - in /llvm/trunk: autoconf/configure.ac configure Message-ID: <200712042254.lB4Msn2s000673@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 4 16:54:47 2007 New Revision: 44586 URL: http://llvm.org/viewvc/llvm-project?rev=44586&view=rev Log: Add --with-llvmgcc= and --with-llvmgxx= configure options. Modified: llvm/trunk/autoconf/configure.ac llvm/trunk/configure Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=44586&r1=44585&r2=44586&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Tue Dec 4 16:54:47 2007 @@ -421,6 +421,28 @@ *) AC_MSG_ERROR([Invalid path for --with-llvmgccdir. Provide full path]) ;; esac +dnl Allow a specific llvm-gcc compiler to be used with this LLVM config. +AC_ARG_WITH(llvmgcc, + AS_HELP_STRING([--with-llvmgcc], + [Specify location of llvm-gcc driver (default searches PATH)]), + LLVMGCC=$with_llvmgcc + WITH_LLVMGCCDIR="",) + +dnl Allow a specific llvm-g++ compiler to be used with this LLVM config. +AC_ARG_WITH(llvmgxx, + AS_HELP_STRING([--with-llvmgxx], + [Specify location of llvm-g++ driver (default searches PATH)]), + LLVMGXX=$with_llvmgxx + WITH_LLVMGCCDIR="",) + +if test -n "$LLVMGCC" && test -z "$LLVMGXX"; then + AC_MSG_ERROR([Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used]); +fi + +if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then + AC_MSG_ERROR([Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used]); +fi + dnl Specify extra build options AC_ARG_WITH(extra-options, AS_HELP_STRING([--with-extra-options], @@ -589,8 +611,12 @@ AC_PATH_PROG(LLVMGCC, $LLVMGCC, []) AC_PATH_PROG(LLVMGXX, $LLVMGXX, []) else - LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}" - LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}" + if test -z "$LLVMGCC"; then + LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}" + fi + if test -z "$LLVMGXX"; then + LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}" + fi AC_SUBST(LLVMGCC,$LLVMGCC) AC_SUBST(LLVMGXX,$LLVMGXX) fi Modified: llvm/trunk/configure URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=44586&r1=44585&r2=44586&view=diff ============================================================================== --- llvm/trunk/configure (original) +++ llvm/trunk/configure Tue Dec 4 16:54:47 2007 @@ -1562,6 +1562,10 @@ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-llvmgccdir Specify location of llvm-gcc install dir (default searches PATH) + --with-llvmgcc Specify location of llvm-gcc driver (default + searches PATH) + --with-llvmgxx Specify location of llvm-g++ driver (default + searches PATH) --with-extra-options Specify addtional options to compile LLVM with --with-ocaml-libdir Specify install location for ocaml bindings (default is stdlib) @@ -4816,6 +4820,34 @@ esac +# Check whether --with-llvmgcc was given. +if test "${with_llvmgcc+set}" = set; then + withval=$with_llvmgcc; LLVMGCC=$with_llvmgcc + WITH_LLVMGCCDIR="" +fi + + + +# Check whether --with-llvmgxx was given. +if test "${with_llvmgxx+set}" = set; then + withval=$with_llvmgxx; LLVMGXX=$with_llvmgxx + WITH_LLVMGCCDIR="" +fi + + +if test -n "$LLVMGCC" && test -z "$LLVMGXX"; then + { { echo "$as_me:$LINENO: error: Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used" >&5 +echo "$as_me: error: Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used" >&2;} + { (exit 1); exit 1; }; }; +fi + +if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then + { { echo "$as_me:$LINENO: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used" >&5 +echo "$as_me: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used" >&2;} + { (exit 1); exit 1; }; }; +fi + + # Check whether --with-extra-options was given. if test "${with_extra_options+set}" = set; then withval=$with_extra_options; @@ -10545,7 +10577,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext + echo '#line 12724 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -14407,11 +14439,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14410: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14442: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14414: \$? = $ac_status" >&5 + echo "$as_me:14446: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14675,11 +14707,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14678: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14710: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14682: \$? = $ac_status" >&5 + echo "$as_me:14714: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14779,11 +14811,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14782: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14814: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14786: \$? = $ac_status" >&5 + echo "$as_me:14818: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17231,7 +17263,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:19734: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:19706: \$? = $ac_status" >&5 + echo "$as_me:19738: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -19803,11 +19835,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:19806: $lt_compile\"" >&5) + (eval echo "\"\$as_me:19838: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:19810: \$? = $ac_status" >&5 + echo "$as_me:19842: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21373,11 +21405,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21376: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21408: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:21380: \$? = $ac_status" >&5 + echo "$as_me:21412: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -21477,11 +21509,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21480: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21512: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:21484: \$? = $ac_status" >&5 + echo "$as_me:21516: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -23712,11 +23744,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23715: $lt_compile\"" >&5) + (eval echo "\"\$as_me:23747: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:23719: \$? = $ac_status" >&5 + echo "$as_me:23751: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -23980,11 +24012,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23983: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24015: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:23987: \$? = $ac_status" >&5 + echo "$as_me:24019: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24084,11 +24116,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24087: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24119: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:24091: \$? = $ac_status" >&5 + echo "$as_me:24123: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -26876,8 +26908,12 @@ else - LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}" - LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}" + if test -z "$LLVMGCC"; then + LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}" + fi + if test -z "$LLVMGXX"; then + LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}" + fi LLVMGCC=$LLVMGCC LLVMGXX=$LLVMGXX From evan.cheng at apple.com Tue Dec 4 17:57:56 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 04 Dec 2007 23:57:56 -0000 Subject: [llvm-commits] [llvm] r44587 - /llvm/trunk/lib/CodeGen/VirtRegMap.cpp Message-ID: <200712042357.lB4Nvuln004528@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 4 17:57:55 2007 New Revision: 44587 URL: http://llvm.org/viewvc/llvm-project?rev=44587&view=rev Log: Remove a unsafe optimization. This fixes 401.bzip2. Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44587&r1=44586&r2=44587&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Tue Dec 4 17:57:55 2007 @@ -1040,14 +1040,6 @@ // Check to see if this stack slot is available. unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId); - if (!PhysReg && DoReMat) { - // This use is rematerializable. But perhaps the value is available in - // a register if the definition is not deleted. If so, check if we can - // reuse the value. - ReuseSlot = VRM.getStackSlot(VirtReg); - if (ReuseSlot != VirtRegMap::NO_STACK_SLOT) - PhysReg = Spills.getSpillSlotOrReMatPhysReg(ReuseSlot); - } // If this is a sub-register use, make sure the reuse register is in the // right register class. For example, for x86 not all of the 32-bit From kremenek at apple.com Tue Dec 4 18:13:07 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 05 Dec 2007 00:13:07 -0000 Subject: [llvm-commits] [llvm] r44589 - /llvm/trunk/include/llvm/Bitcode/Serialize.h Message-ID: <200712050013.lB50D77d005655@zion.cs.uiuc.edu> Author: kremenek Date: Tue Dec 4 18:13:07 2007 New Revision: 44589 URL: http://llvm.org/viewvc/llvm-project?rev=44589&view=rev Log: Added "Emitter" functor to allow easy emitting of elements of a container using std::for_each. Modified: llvm/trunk/include/llvm/Bitcode/Serialize.h Modified: llvm/trunk/include/llvm/Bitcode/Serialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialize.h?rev=44589&r1=44588&r2=44589&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialize.h Tue Dec 4 18:13:07 2007 @@ -37,6 +37,17 @@ template inline void Emit(const T& X) { SerializeTrait::Emit(*this,X); } + template + struct Emitter { + Serializer &S; + + Emitter(Serializer& s) : S(s) {} + void operator()(const T& x) const { S.Emit(x); } + }; + + template + Emitter MakeEmitter() { return Emitter(*this); } + void EmitInt(uint64_t X); void EmitSInt(int64_t X); From dalej at apple.com Tue Dec 4 19:10:19 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 05 Dec 2007 01:10:19 -0000 Subject: [llvm-commits] [llvm] r44594 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200712050110.lB51AK66008577@zion.cs.uiuc.edu> Author: johannes Date: Tue Dec 4 19:10:19 2007 New Revision: 44594 URL: http://llvm.org/viewvc/llvm-project?rev=44594&view=rev Log: Handle 0 correctly in string->APFloat conversion. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=44594&r1=44593&r2=44594&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Dec 4 19:10:19 2007 @@ -2145,7 +2145,7 @@ 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] */ - if (*D.firstSigDigit == '0') { + if (*D.firstSigDigit == 0) { category = fcZero; fs = opOK; } else if ((D.normalizedExponent + 1) * 28738 From scottm at aero.org Tue Dec 4 19:24:07 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 01:24:07 -0000 Subject: [llvm-commits] [llvm] r44595 - in /llvm/trunk/lib/Target/CellSPU: SPUMachineFunction.h SPUNodes.td SPUOperands.td SPURegisterInfo.cpp SPURegisterInfo.h SPURegisterInfo.td SPUSchedule.td SPUSubtarget.cpp SPUSubtarget.h SPUTargetAsmInfo.cpp SPUTargetAsmInfo.h SPUTargetMachine.cpp SPUTargetMachine.h Message-ID: <200712050124.lB51O73h009068@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 19:24:05 2007 New Revision: 44595 URL: http://llvm.org/viewvc/llvm-project?rev=44595&view=rev Log: Main CellSPU backend files checked in. Intrinsics and autoconf files remain. Added: llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h llvm/trunk/lib/Target/CellSPU/SPUNodes.td llvm/trunk/lib/Target/CellSPU/SPUOperands.td llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td llvm/trunk/lib/Target/CellSPU/SPUSchedule.td llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h Added: llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h Tue Dec 4 19:24:05 2007 @@ -0,0 +1,45 @@ +//===-- SPUMachineFunctionInfo.h - Private data used for CellSPU --*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the IBM Cell SPU specific subclass of MachineFunctionInfo. +// +//===----------------------------------------------------------------------===// + +#ifndef SPU_MACHINE_FUNCTION_INFO_H +#define SPU_MACHINE_FUNCTION_INFO_H + +#include "llvm/CodeGen/MachineFunction.h" + +namespace llvm { + +/// SPUFunctionInfo - Cell SPU target-specific information for each +/// MachineFunction +class SPUFunctionInfo : public MachineFunctionInfo { +private: + /// UsesLR - Indicates whether LR is used in the current function. + /// + bool UsesLR; + +public: + SPUFunctionInfo(MachineFunction& MF) + : UsesLR(false) + {} + + void setUsesLR(bool U) { UsesLR = U; } + bool usesLR() { return UsesLR; } + +}; + +} // end of namespace llvm + + +#endif + Added: llvm/trunk/lib/Target/CellSPU/SPUNodes.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Tue Dec 4 19:24:05 2007 @@ -0,0 +1,219 @@ +//=- SPUNodes.h - Specialized SelectionDAG nodes used for CellSPU -*- C++ -*-=// +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +//===----------------------------------------------------------------------===// +// +// Type profiles and SelectionDAG nodes used by CellSPU +// +//===----------------------------------------------------------------------===// + +// Type profile for a call sequence +def SDT_SPUCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; + +// SPU_GenControl: Type profile for generating control words for insertions +def SPU_GenControl : SDTypeProfile<1, 1, []>; +def SPUvecinsmask : SDNode<"SPUISD::INSERT_MASK", SPU_GenControl, []>; + +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq, + [SDNPHasChain, SDNPOutFlag]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq, + [SDNPHasChain, SDNPOutFlag]>; +//===----------------------------------------------------------------------===// +// Operand constraints: +//===----------------------------------------------------------------------===// + +def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; +def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + +// Operand type constraints for vector shuffle/permute operations +def SDT_SPUshuffle : SDTypeProfile<1, 3, [ + SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> +]>; + +// Unary, binary v16i8 operator type constraints: +def SPUv16i8_unop: SDTypeProfile<1, 1, [ + SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>]>; + +def SPUv16i8_binop: SDTypeProfile<1, 2, [ + SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; + +// Binary v8i16 operator type constraints: +def SPUv8i16_unop: SDTypeProfile<1, 1, [ + SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>]>; + +def SPUv8i16_binop: SDTypeProfile<1, 2, [ + SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; + +// Binary v4i32 operator type constraints: +def SPUv4i32_unop: SDTypeProfile<1, 1, [ + SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>]>; + +def SPUv4i32_binop: SDTypeProfile<1, 2, [ + SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; + +// FSMBI type constraints: There are several variations for the various +// vector types (this avoids having to bit_convert all over the place.) +def SPUfsmbi_type_v16i8: SDTypeProfile<1, 1, [ + SDTCisVT<0, v16i8>, SDTCisVT<1, i32>]>; + +def SPUfsmbi_type_v8i16: SDTypeProfile<1, 1, [ + SDTCisVT<0, v8i16>, SDTCisVT<1, i32>]>; + +def SPUfsmbi_type_v4i32: SDTypeProfile<1, 1, [ + SDTCisVT<0, v4i32>, SDTCisVT<1, i32>]>; + +// SELB type constraints: +def SPUselb_type_v16i8: SDTypeProfile<1, 3, [ + SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, + SDTCisSameAs<0, 3> ]>; + +def SPUselb_type_v8i16: SDTypeProfile<1, 3, [ + SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, + SDTCisSameAs<0, 3> ]>; + +def SPUselb_type_v4i32: SDTypeProfile<1, 3, [ + SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, + SDTCisSameAs<0, 3> ]>; + +// SPU Vector shift pseudo-instruction type constraints +def SPUvecshift_type_v16i8: SDTypeProfile<1, 2, [ + SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; + +def SPUvecshift_type_v8i16: SDTypeProfile<1, 2, [ + SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; + +def SPUvecshift_type_v4i32: SDTypeProfile<1, 2, [ + SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>; + +//===----------------------------------------------------------------------===// +// Synthetic/pseudo-instructions +//===----------------------------------------------------------------------===// + +// SPU CNTB: +def SPUcntb_v16i8: SDNode<"SPUISD::CNTB", SPUv16i8_unop, []>; +def SPUcntb_v8i16: SDNode<"SPUISD::CNTB", SPUv8i16_unop, []>; +def SPUcntb_v4i32: SDNode<"SPUISD::CNTB", SPUv4i32_unop, []>; + +// SPU vector shuffle node, matched by the SPUISD::SHUFB enum (see +// SPUISelLowering.h): +def SPUshuffle: SDNode<"SPUISD::SHUFB", SDT_SPUshuffle, []>; + +// SPU 16-bit multiply +def SPUmpy_v16i8: SDNode<"SPUISD::MPY", SPUv16i8_binop, []>; +def SPUmpy_v8i16: SDNode<"SPUISD::MPY", SPUv8i16_binop, []>; +def SPUmpy_v4i32: SDNode<"SPUISD::MPY", SPUv4i32_binop, []>; + +// SPU multiply unsigned, used in instruction lowering for v4i32 +// multiplies: +def SPUmpyu_v4i32: SDNode<"SPUISD::MPYU", SPUv4i32_binop, []>; +def SPUmpyu_i32: SDNode<"SPUISD::MPYU", SDTIntBinOp, []>; + +// SPU 16-bit multiply high x low, shift result 16-bits +// Used to compute intermediate products for 32-bit multiplies +def SPUmpyh_v4i32: SDNode<"SPUISD::MPYH", SPUv4i32_binop, []>; +def SPUmpyh_i32: SDNode<"SPUISD::MPYH", SDTIntBinOp, []>; + +// SPU 16-bit multiply high x high, 32-bit product +// Used to compute intermediate products for 16-bit multiplies +def SPUmpyhh_v8i16: SDNode<"SPUISD::MPYHH", SPUv8i16_binop, []>; + +// Vector shifts (ISD::SHL,SRL,SRA are for _integers_ only): +def SPUvec_shl_v8i16: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v8i16, []>; +def SPUvec_srl_v8i16: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v8i16, []>; +def SPUvec_sra_v8i16: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v8i16, []>; + +def SPUvec_shl_v4i32: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v4i32, []>; +def SPUvec_srl_v4i32: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v4i32, []>; +def SPUvec_sra_v4i32: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v4i32, []>; + +def SPUvec_rotl_v8i16: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v8i16, []>; +def SPUvec_rotl_v4i32: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v4i32, []>; + +def SPUvec_rotr_v8i16: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v8i16, []>; +def SPUvec_rotr_v4i32: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v4i32, []>; + +def SPUrotbytes_right_zfill: SDNode<"SPUISD::ROTBYTES_RIGHT_Z", + SPUvecshift_type_v16i8, []>; +def SPUrotbytes_right_sfill: SDNode<"SPUISD::ROTBYTES_RIGHT_S", + SPUvecshift_type_v16i8, []>; +def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT", + SPUvecshift_type_v16i8, []>; + +def SPUrotbytes_left_chained : SDNode<"SPUISD::ROTBYTES_LEFT_CHAINED", + SPUvecshift_type_v16i8, [SDNPHasChain]>; + +// SPU form select mask for bytes, immediate +def SPUfsmbi_v16i8: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v16i8, []>; +def SPUfsmbi_v8i16: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v8i16, []>; +def SPUfsmbi_v4i32: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v4i32, []>; + +// SPU select bits instruction +def SPUselb_v16i8: SDNode<"SPUISD::SELB", SPUselb_type_v16i8, []>; +def SPUselb_v8i16: SDNode<"SPUISD::SELB", SPUselb_type_v8i16, []>; +def SPUselb_v4i32: SDNode<"SPUISD::SELB", SPUselb_type_v4i32, []>; + +// SPU single precision floating point constant load +def SPUFPconstant: SDNode<"SPUISD::SFPConstant", SDTFPUnaryOp, []>; + +// SPU floating point interpolate +def SPUinterpolate : SDNode<"SPUISD::FPInterp", SDTFPBinOp, []>; + +// SPU floating point reciprocal estimate (used for fdiv) +def SPUreciprocalEst: SDNode<"SPUISD::FPRecipEst", SDTFPUnaryOp, []>; + +def SDT_vec_promote : SDTypeProfile<1, 1, []>; +def SPUpromote_scalar: SDNode<"SPUISD::PROMOTE_SCALAR", SDT_vec_promote, []>; + +def SPU_vec_demote : SDTypeProfile<1, 1, []>; +def SPUextract_elt0: SDNode<"SPUISD::EXTRACT_ELT0", SPU_vec_demote, []>; +def SPU_vec_demote_chained : SDTypeProfile<1, 2, []>; +def SPUextract_elt0_chained: SDNode<"SPUISD::EXTRACT_ELT0_CHAINED", + SPU_vec_demote_chained, [SDNPHasChain]>; +def SPUextract_i1_sext: SDNode<"SPUISD::EXTRACT_I1_SEXT", SPU_vec_demote, []>; +def SPUextract_i1_zext: SDNode<"SPUISD::EXTRACT_I1_ZEXT", SPU_vec_demote, []>; +def SPUextract_i8_sext: SDNode<"SPUISD::EXTRACT_I8_SEXT", SPU_vec_demote, []>; +def SPUextract_i8_zext: SDNode<"SPUISD::EXTRACT_I8_ZEXT", SPU_vec_demote, []>; + +// Address high and low components, used for [r+r] type addressing +def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>; +def SPUlo : SDNode<"SPUISD::Lo", SDTIntBinOp, []>; + +// PC-relative address +def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>; + +// D-Form "imm($reg)" addresses +def SPUdform : SDNode<"SPUISD::DFormAddr", SDTIntBinOp, []>; + +// SPU 32-bit sign-extension to 64-bits +def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>; + +// Branches: + +def SPUbrnz : SDNode<"SPUISD::BR_NOTZERO", SDTBrcond, [SDNPHasChain]>; +def SPUbrz : SDNode<"SPUISD::BR_ZERO", SDTBrcond, [SDNPHasChain]>; +/* def SPUbinz : SDNode<"SPUISD::BR_NOTZERO", SDTBrind, [SDNPHasChain]>; +def SPUbiz : SDNode<"SPUISD::BR_ZERO", SPUBrind, [SDNPHasChain]>; */ + +//===----------------------------------------------------------------------===// +// Constraints: (taken from PPCInstrInfo.td) +//===----------------------------------------------------------------------===// + +class RegConstraint { + string Constraints = C; +} + +class NoEncode { + string DisableEncoding = E; +} + +//===----------------------------------------------------------------------===// +// Return (flag isn't quite what it means: the operations are flagged so that +// instruction scheduling doesn't disassociate them.) +//===----------------------------------------------------------------------===// + +def retflag : SDNode<"SPUISD::RET_FLAG", SDTRet, + [SDNPHasChain, SDNPOptInFlag]>; Added: llvm/trunk/lib/Target/CellSPU/SPUOperands.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUOperands.td?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUOperands.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPUOperands.td Tue Dec 4 19:24:05 2007 @@ -0,0 +1,574 @@ +//===- SPUOperands.td - Cell SPU Instruction Operands ------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by The Aerospace Corporation. +// +//===----------------------------------------------------------------------===// +// Cell SPU Instruction Operands: +//===----------------------------------------------------------------------===// + +def LO16 : SDNodeXFormgetValue(); + // Transformation function: get the low 16 bits. + return getI32Imm(val & 0xffff); +}]>; + +def LO16_vec : SDNodeXFormgetOpcode() == ISD::BUILD_VECTOR + && "LO16_vec got something other than a BUILD_VECTOR"); + + // Get first constant operand... + for (unsigned i = 0, e = N->getNumOperands(); OpVal.Val == 0 && i != e; ++i) { + if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue; + if (OpVal.Val == 0) + OpVal = N->getOperand(i); + } + + assert(OpVal.Val != 0 && "LO16_vec did not locate a node"); + ConstantSDNode *CN = dyn_cast(OpVal); + return getI32Imm((unsigned)CN->getValue() & 0xffff); +}]>; + +// Transform an immediate, returning the high 16 bits shifted down: +def HI16 : SDNodeXFormgetValue() >> 16); +}]>; + +// Transformation function: shift the high 16 bit immediate from a build_vector +// node into the low 16 bits, and return a 16-bit constant. +def HI16_vec : SDNodeXFormgetOpcode() == ISD::BUILD_VECTOR + && "HI16_vec got something other than a BUILD_VECTOR"); + + // Get first constant operand... + for (unsigned i = 0, e = N->getNumOperands(); OpVal.Val == 0 && i != e; ++i) { + if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue; + if (OpVal.Val == 0) + OpVal = N->getOperand(i); + } + + assert(OpVal.Val != 0 && "HI16_vec did not locate a node"); + ConstantSDNode *CN = dyn_cast(OpVal); + return getI32Imm((unsigned)CN->getValue() >> 16); +}]>; + +// simm7 predicate - True if the immediate fits in an 7-bit signed +// field. +def simm7: PatLeaf<(imm), [{ + int sextVal = ((((int) N->getValue()) << 25) >> 25); + return (sextVal >= -64 && sextVal <= 63); +}]>; + +// uimm7 predicate - True if the immediate fits in an 7-bit unsigned +// field. +def uimm7: PatLeaf<(imm), [{ + return (N->getValue() <= 0x7f); +}]>; + +// immSExt8 predicate - True if the immediate fits in an 8-bit sign extended +// field. +def immSExt8 : PatLeaf<(imm), [{ + int Value = (int) N->getValue(); + int Value8 = (Value << 24) >> 24; + return (Value < 0xff && (Value8 >= -128 && Value8 < 127)); +}]>; + +// immU8: immediate, unsigned 8-bit quantity +def immU8 : PatLeaf<(imm), [{ + return (N->getValue() <= 0xff); +}]>; + +// i64ImmSExt10 predicate - True if the i64 immediate fits in a 10-bit sign +// extended field. Used by RI10Form instructions like 'ldq'. +def i64ImmSExt10 : PatLeaf<(imm), [{ + return isI64IntS10Immediate(N); +}]>; + +// i32ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign +// extended field. Used by RI10Form instructions like 'ldq'. +def i32ImmSExt10 : PatLeaf<(imm), [{ + return isI32IntS10Immediate(N); +}]>; + +// i16ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign +// extended field. Used by RI10Form instructions like 'ldq'. +def i16ImmSExt10 : PatLeaf<(imm), [{ + return isI16IntS10Immediate(N); +}]>; + +def immSExt16 : PatLeaf<(imm), [{ + // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended + // field. + short Ignored; + return isIntS16Immediate(N, Ignored); +}]>; + +def immZExt16 : PatLeaf<(imm), [{ + // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended + // field. + return (uint64_t)N->getValue() == (unsigned short)N->getValue(); +}], LO16>; + +def immU16 : PatLeaf<(imm), [{ + // immU16 predicate- True if the immediate fits into a 16-bit unsigned field. + return (uint64_t)N->getValue() == (N->getValue() & 0xffff); +}]>; + +def imm18 : PatLeaf<(imm), [{ + // imm18 predicate: True if the immediate fits into an 18-bit unsigned field. + int Value = (int) N->getValue(); + return ((Value & ((1 << 19) - 1)) == Value); +}]>; + +def hi16 : PatLeaf<(imm), [{ + // hi16 predicate - returns true if the immediate has all zeros in the + // low order bits and is a 32-bit constant: + if (N->getValueType(0) == MVT::i32) { + uint32_t val = N->getValue(); + return ((val & 0xffff0000) == val); + } + + return false; +}], HI16>; + +//===----------------------------------------------------------------------===// +// Floating point operands: +//===----------------------------------------------------------------------===// + +// Transform a float, returning the high 16 bits shifted down, as if +// the float was really an unsigned integer: +def HI16_f32 : SDNodeXFormgetValueAPF(); + float fval = apf.convertToFloat(); + unsigned val = *((unsigned *) &fval); + return getI32Imm(val >> 16); +}]>; + +// Transformation function on floats: get the low 16 bits as if the float was +// an unsigned integer. +def LO16_f32 : SDNodeXFormgetValueAPF(); + float fval = apf.convertToFloat(); + unsigned val = *((unsigned *) &fval); + return getI32Imm(val & 0xffff); +}]>; + +def FPimm_sext16 : SDNodeXFormgetValueAPF(); + float fval = apf.convertToFloat(); + unsigned val = *((unsigned *) &fval); + return getI32Imm((int) ((val << 16) >> 16)); +}]>; + +def FPimm_u18 : SDNodeXFormgetValueAPF(); + float fval = apf.convertToFloat(); + unsigned val = *((unsigned *) &fval); + return getI32Imm(val & ((1 << 19) - 1)); +}]>; + +def fpimmSExt16 : PatLeaf<(fpimm), [{ + short Ignored; + return isFPS16Immediate(N, Ignored); +}], FPimm_sext16>; + +// Does the SFP constant only have upp 16 bits set? +def hi16_f32 : PatLeaf<(fpimm), [{ + if (N->getValueType(0) == MVT::f32) { + const APFloat &apf = N->getValueAPF(); + float fval = apf.convertToFloat(); + uint32_t val = *((unsigned *) &fval); + return ((val & 0xffff0000) == val); + } + + return false; +}], HI16_f32>; + +// Does the SFP constant fit into 18 bits? +def fpimm18 : PatLeaf<(fpimm), [{ + if (N->getValueType(0) == MVT::f32) { + const APFloat &apf = N->getValueAPF(); + float fval = apf.convertToFloat(); + uint32_t Value = *((uint32_t *) &fval); + return ((Value & ((1 << 19) - 1)) == Value); + } + + return false; +}], FPimm_u18>; + +//===----------------------------------------------------------------------===// +// 64-bit operands: +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// build_vector operands: +//===----------------------------------------------------------------------===// + +// v16i8SExt8Imm_xform function: convert build_vector to 8-bit sign extended +// immediate constant load for v16i8 vectors. N.B.: The incoming constant has +// to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a). +def v16i8SExt8Imm_xform: SDNodeXForm; + +// v16i8SExt8Imm: Predicate test for 8-bit sign extended immediate constant +// load, works in conjunction with its transform function. N.B.: This relies the +// incoming constant being a 16-bit quantity, where the upper and lower bytes +// are EXACTLY the same (e.g., 0x2a2a) +def v16i8SExt8Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).Val != 0; +}], v16i8SExt8Imm_xform>; + +// v16i8U8Imm_xform function: convert build_vector to unsigned 8-bit +// immediate constant load for v16i8 vectors. N.B.: The incoming constant has +// to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a). +def v16i8U8Imm_xform: SDNodeXForm; + +// v16i8U8Imm: Predicate test for unsigned 8-bit immediate constant +// load, works in conjunction with its transform function. N.B.: This relies the +// incoming constant being a 16-bit quantity, where the upper and lower bytes +// are EXACTLY the same (e.g., 0x2a2a) +def v16i8U8Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).Val != 0; +}], v16i8U8Imm_xform>; + +// v8i16SExt8Imm_xform function: convert build_vector to 8-bit sign extended +// immediate constant load for v8i16 vectors. +def v8i16SExt8Imm_xform: SDNodeXForm; + +// v8i16SExt8Imm: Predicate test for 8-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v8i16SExt8Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16).Val != 0; +}], v8i16SExt8Imm_xform>; + +// v8i16SExt10Imm_xform function: convert build_vector to 16-bit sign extended +// immediate constant load for v8i16 vectors. +def v8i16SExt10Imm_xform: SDNodeXForm; + +// v8i16SExt10Imm: Predicate test for 16-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v8i16SExt10Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).Val != 0; +}], v8i16SExt10Imm_xform>; + +// v8i16SExt16Imm_xform function: convert build_vector to 16-bit sign extended +// immediate constant load for v8i16 vectors. +def v8i16SExt16Imm_xform: SDNodeXForm; + +// v8i16SExt16Imm: Predicate test for 16-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v8i16SExt16Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16).Val != 0; +}], v8i16SExt16Imm_xform>; + +// v4i32SExt10Imm_xform function: convert build_vector to 10-bit sign extended +// immediate constant load for v4i32 vectors. +def v4i32SExt10Imm_xform: SDNodeXForm; + +// v4i32SExt10Imm: Predicate test for 10-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v4i32SExt10Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).Val != 0; +}], v4i32SExt10Imm_xform>; + +// v4i32SExt16Imm_xform function: convert build_vector to 16-bit sign extended +// immediate constant load for v4i32 vectors. +def v4i32SExt16Imm_xform: SDNodeXForm; + +// v4i32SExt16Imm: Predicate test for 16-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v4i32SExt16Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32).Val != 0; +}], v4i32SExt16Imm_xform>; + +// v4i32Uns18Imm_xform function: convert build_vector to 18-bit unsigned +// immediate constant load for v4i32 vectors. +def v4i32Uns18Imm_xform: SDNodeXForm; + +// v4i32Uns18Imm: Predicate test for 18-bit unsigned immediate constant load, +// works in conjunction with its transform function. +def v4i32Uns18Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32).Val != 0; +}], v4i32Uns18Imm_xform>; + +// ILHUvec_get_imm xform function: convert build_vector to ILHUvec imm constant +// load. +def ILHUvec_get_imm: SDNodeXForm; + +/// immILHUvec: Predicate test for a ILHU constant vector. +def immILHUvec: PatLeaf<(build_vector), [{ + return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32).Val != 0; +}], ILHUvec_get_imm>; + +// Catch-all for any other i32 vector constants +def v4i32_get_imm: SDNodeXForm; + +def v4i32Imm: PatLeaf<(build_vector), [{ + return SPU::get_v4i32_imm(N, *CurDAG).Val != 0; +}], v4i32_get_imm>; + +// v2i64SExt10Imm_xform function: convert build_vector to 10-bit sign extended +// immediate constant load for v2i64 vectors. +def v2i64SExt10Imm_xform: SDNodeXForm; + +// v2i64SExt10Imm: Predicate test for 10-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v2i64SExt10Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64).Val != 0; +}], v2i64SExt10Imm_xform>; + +// v2i64SExt16Imm_xform function: convert build_vector to 16-bit sign extended +// immediate constant load for v2i64 vectors. +def v2i64SExt16Imm_xform: SDNodeXForm; + +// v2i64SExt16Imm: Predicate test for 16-bit sign extended immediate constant +// load, works in conjunction with its transform function. +def v2i64SExt16Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64).Val != 0; +}], v2i64SExt16Imm_xform>; + +// v2i64Uns18Imm_xform function: convert build_vector to 18-bit unsigned +// immediate constant load for v2i64 vectors. +def v2i64Uns18Imm_xform: SDNodeXForm; + +// v2i64Uns18Imm: Predicate test for 18-bit unsigned immediate constant load, +// works in conjunction with its transform function. +def v2i64Uns18Imm: PatLeaf<(build_vector), [{ + return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64).Val != 0; +}], v2i64Uns18Imm_xform>; + +/// immILHUvec: Predicate test for a ILHU constant vector. +def immILHUvec_i64: PatLeaf<(build_vector), [{ + return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i64).Val != 0; +}], ILHUvec_get_imm>; + +// Catch-all for any other i32 vector constants +def v2i64_get_imm: SDNodeXForm; + +def v2i64Imm: PatLeaf<(build_vector), [{ + return SPU::get_v2i64_imm(N, *CurDAG).Val != 0; +}], v2i64_get_imm>; + +//===----------------------------------------------------------------------===// +// Operand Definitions. + +def s7imm: Operand { + let PrintMethod = "printS7ImmOperand"; +} + +def u7imm: Operand { + let PrintMethod = "printU7ImmOperand"; +} + +def u7imm_i32: Operand { + let PrintMethod = "printU7ImmOperand"; +} + +// Halfword, signed 10-bit constant +def s10imm : Operand { + let PrintMethod = "printS10ImmOperand"; +} + +def s10imm_i32: Operand { + let PrintMethod = "printS10ImmOperand"; +} + +def s10imm_i64: Operand { + let PrintMethod = "printS10ImmOperand"; +} + +// Unsigned 10-bit integers: +def u10imm: Operand { + let PrintMethod = "printU10ImmOperand"; +} + +def u10imm_i32: Operand { + let PrintMethod = "printU10ImmOperand"; +} + +def s16imm : Operand { + let PrintMethod = "printS16ImmOperand"; +} + +def s16imm_i32: Operand { + let PrintMethod = "printS16ImmOperand"; +} + +def s16imm_i64: Operand { + let PrintMethod = "printS16ImmOperand"; +} + +def s16imm_f32: Operand { + let PrintMethod = "printS16ImmOperand"; +} + +def s16imm_f64: Operand { + let PrintMethod = "printS16ImmOperand"; +} + +def u16imm : Operand { + let PrintMethod = "printU16ImmOperand"; +} + +def f16imm : Operand { + let PrintMethod = "printU16ImmOperand"; +} + +def s18imm : Operand { + let PrintMethod = "printS18ImmOperand"; +} + +def u18imm : Operand { + let PrintMethod = "printU18ImmOperand"; +} + +def u18imm_i64 : Operand { + let PrintMethod = "printU18ImmOperand"; +} + +def f18imm : Operand { + let PrintMethod = "printU18ImmOperand"; +} + +def f18imm_f64 : Operand { + let PrintMethod = "printU18ImmOperand"; +} + +// Negated 7-bit halfword rotate immediate operands +def rothNeg7imm : Operand { + let PrintMethod = "printROTHNeg7Imm"; +} + +def rothNeg7imm_i16 : Operand { + let PrintMethod = "printROTHNeg7Imm"; +} + +// Negated 7-bit word rotate immediate operands +def rotNeg7imm : Operand { + let PrintMethod = "printROTNeg7Imm"; +} + +def rotNeg7imm_i16 : Operand { + let PrintMethod = "printROTNeg7Imm"; +} + +// Floating point immediate operands +def f32imm : Operand; + +def target : Operand { + let PrintMethod = "printBranchOperand"; +} + +// Absolute address call target +def calltarget : Operand { + let PrintMethod = "printCallOperand"; + let MIOperandInfo = (ops u18imm:$calldest); +} + +// Relative call target +def relcalltarget : Operand { + let PrintMethod = "printPCRelativeOperand"; + let MIOperandInfo = (ops s16imm:$calldest); +} + +// Branch targets: +def brtarget : Operand { + let PrintMethod = "printPCRelativeOperand"; +} + +// Indirect call target +def indcalltarget : Operand { + let PrintMethod = "printCallOperand"; + let MIOperandInfo = (ops ptr_rc:$calldest); +} + +def symbolHi: Operand { + let PrintMethod = "printSymbolHi"; +} + +def symbolLo: Operand { + let PrintMethod = "printSymbolLo"; +} + +def symbolLSA: Operand { + let PrintMethod = "printSymbolLSA"; +} + +// memory s7imm(reg) operaand +def memri7 : Operand { + let PrintMethod = "printMemRegImmS7"; + let MIOperandInfo = (ops s7imm:$imm, ptr_rc:$reg); +} + +// memory s10imm(reg) operand +def memri10 : Operand { + let PrintMethod = "printMemRegImmS10"; + let MIOperandInfo = (ops s10imm:$imm, ptr_rc:$reg); +} + +// 256K local store address +// N.B.: The tblgen code generator expects to have two operands, an offset +// and a pointer. Of these, only the immediate is actually used. +def addr256k : Operand { + let PrintMethod = "printAddr256K"; + let MIOperandInfo = (ops s16imm:$imm, ptr_rc:$reg); +} + +// memory s18imm(reg) operand +def memri18 : Operand { + let PrintMethod = "printMemRegImmS18"; + let MIOperandInfo = (ops s18imm:$imm, ptr_rc:$reg); +} + +// memory register + register operand +def memrr : Operand { + let PrintMethod = "printMemRegReg"; + let MIOperandInfo = (ops ptr_rc:$reg_a, ptr_rc:$reg_b); +} + +// Define SPU-specific addressing modes: These come in three basic +// flavors: +// +// D-form : [r+I10] (10-bit signed offset + reg) +// X-form : [r+r] (reg+reg) +// A-form : abs (256K LSA offset) +// D-form(2): [r+I7] (7-bit signed offset + reg) + +def dform_addr : ComplexPattern; +def xform_addr : ComplexPattern; +def aform_addr : ComplexPattern; +def dform2_addr : ComplexPattern; Added: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp Tue Dec 4 19:24:05 2007 @@ -0,0 +1,863 @@ +//===- SPURegisterInfo.cpp - Cell SPU Register Information ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the PowerPC implementation of the MRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "reginfo" +#include "SPU.h" +#include "SPURegisterInfo.h" +#include "SPURegisterNames.h" +#include "SPUInstrBuilder.h" +#include "SPUSubtarget.h" +#include "SPUMachineFunction.h" +#include "SPUFrameInfo.h" +#include "llvm/Constants.h" +#include "llvm/Type.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/STLExtras.h" +#include +#include + +using namespace llvm; + +/// getRegisterNumbering - Given the enum value for some register, e.g. +/// PPC::F14, return the number that it corresponds to (e.g. 14). +unsigned SPURegisterInfo::getRegisterNumbering(unsigned RegEnum) { + using namespace SPU; + switch (RegEnum) { + case SPU::R0: return 0; + case SPU::R1: return 1; + case SPU::R2: return 2; + case SPU::R3: return 3; + case SPU::R4: return 4; + case SPU::R5: return 5; + case SPU::R6: return 6; + case SPU::R7: return 7; + case SPU::R8: return 8; + case SPU::R9: return 9; + case SPU::R10: return 10; + case SPU::R11: return 11; + case SPU::R12: return 12; + case SPU::R13: return 13; + case SPU::R14: return 14; + case SPU::R15: return 15; + case SPU::R16: return 16; + case SPU::R17: return 17; + case SPU::R18: return 18; + case SPU::R19: return 19; + case SPU::R20: return 20; + case SPU::R21: return 21; + case SPU::R22: return 22; + case SPU::R23: return 23; + case SPU::R24: return 24; + case SPU::R25: return 25; + case SPU::R26: return 26; + case SPU::R27: return 27; + case SPU::R28: return 28; + case SPU::R29: return 29; + case SPU::R30: return 30; + case SPU::R31: return 31; + case SPU::R32: return 32; + case SPU::R33: return 33; + case SPU::R34: return 34; + case SPU::R35: return 35; + case SPU::R36: return 36; + case SPU::R37: return 37; + case SPU::R38: return 38; + case SPU::R39: return 39; + case SPU::R40: return 40; + case SPU::R41: return 41; + case SPU::R42: return 42; + case SPU::R43: return 43; + case SPU::R44: return 44; + case SPU::R45: return 45; + case SPU::R46: return 46; + case SPU::R47: return 47; + case SPU::R48: return 48; + case SPU::R49: return 49; + case SPU::R50: return 50; + case SPU::R51: return 51; + case SPU::R52: return 52; + case SPU::R53: return 53; + case SPU::R54: return 54; + case SPU::R55: return 55; + case SPU::R56: return 56; + case SPU::R57: return 57; + case SPU::R58: return 58; + case SPU::R59: return 59; + case SPU::R60: return 60; + case SPU::R61: return 61; + case SPU::R62: return 62; + case SPU::R63: return 63; + case SPU::R64: return 64; + case SPU::R65: return 65; + case SPU::R66: return 66; + case SPU::R67: return 67; + case SPU::R68: return 68; + case SPU::R69: return 69; + case SPU::R70: return 70; + case SPU::R71: return 71; + case SPU::R72: return 72; + case SPU::R73: return 73; + case SPU::R74: return 74; + case SPU::R75: return 75; + case SPU::R76: return 76; + case SPU::R77: return 77; + case SPU::R78: return 78; + case SPU::R79: return 79; + case SPU::R80: return 80; + case SPU::R81: return 81; + case SPU::R82: return 82; + case SPU::R83: return 83; + case SPU::R84: return 84; + case SPU::R85: return 85; + case SPU::R86: return 86; + case SPU::R87: return 87; + case SPU::R88: return 88; + case SPU::R89: return 89; + case SPU::R90: return 90; + case SPU::R91: return 91; + case SPU::R92: return 92; + case SPU::R93: return 93; + case SPU::R94: return 94; + case SPU::R95: return 95; + case SPU::R96: return 96; + case SPU::R97: return 97; + case SPU::R98: return 98; + case SPU::R99: return 99; + case SPU::R100: return 100; + case SPU::R101: return 101; + case SPU::R102: return 102; + case SPU::R103: return 103; + case SPU::R104: return 104; + case SPU::R105: return 105; + case SPU::R106: return 106; + case SPU::R107: return 107; + case SPU::R108: return 108; + case SPU::R109: return 109; + case SPU::R110: return 110; + case SPU::R111: return 111; + case SPU::R112: return 112; + case SPU::R113: return 113; + case SPU::R114: return 114; + case SPU::R115: return 115; + case SPU::R116: return 116; + case SPU::R117: return 117; + case SPU::R118: return 118; + case SPU::R119: return 119; + case SPU::R120: return 120; + case SPU::R121: return 121; + case SPU::R122: return 122; + case SPU::R123: return 123; + case SPU::R124: return 124; + case SPU::R125: return 125; + case SPU::R126: return 126; + case SPU::R127: return 127; + default: + std::cerr << "Unhandled reg in SPURegisterInfo::getRegisterNumbering!\n"; + abort(); + } +} + +SPURegisterInfo::SPURegisterInfo(const SPUSubtarget &subtarget, + const TargetInstrInfo &tii) : + SPUGenRegisterInfo(SPU::ADJCALLSTACKDOWN, SPU::ADJCALLSTACKUP), + Subtarget(subtarget), + TII(tii) +{ +} + +void +SPURegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const +{ + MachineOpCode opc; + if (RC == SPU::GPRCRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::STQDr128 + : SPU::STQXr128; + } else if (RC == SPU::R64CRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::STQDr64 + : SPU::STQXr64; + } else if (RC == SPU::R64FPRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::STQDr64 + : SPU::STQXr64; + } else if (RC == SPU::R32CRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::STQDr32 + : SPU::STQXr32; + } else if (RC == SPU::R32FPRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::STQDr32 + : SPU::STQXr32; + } else if (RC == SPU::R16CRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) ? + SPU::STQDr16 + : SPU::STQXr16; + } else { + assert(0 && "Unknown regclass!"); + abort(); + } + + addFrameReference(BuildMI(MBB, MI, TII.get(opc)).addReg(SrcReg), FrameIdx); +} + +void SPURegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const { + cerr << "storeRegToAddr() invoked!\n"; + abort(); + + if (Addr[0].isFrameIndex()) { + /* do what storeRegToStackSlot does here */ + } else { + unsigned Opc = 0; + if (RC == SPU::GPRCRegisterClass) { + /* Opc = PPC::STW; */ + } else if (RC == SPU::R16CRegisterClass) { + /* Opc = PPC::STD; */ + } else if (RC == SPU::R32CRegisterClass) { + /* Opc = PPC::STFD; */ + } else if (RC == SPU::R32FPRegisterClass) { + /* Opc = PPC::STFD; */ + } else if (RC == SPU::R64FPRegisterClass) { + /* Opc = PPC::STFS; */ + } else if (RC == SPU::VECREGRegisterClass) { + /* Opc = PPC::STVX; */ + } else { + assert(0 && "Unknown regclass!"); + abort(); + } + MachineInstrBuilder MIB = BuildMI(TII.get(Opc)) + .addReg(SrcReg, false, false, true); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + } +} + +void +SPURegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const +{ + MachineOpCode opc; + if (RC == SPU::GPRCRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::LQDr128 + : SPU::LQXr128; + } else if (RC == SPU::R64CRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::LQDr64 + : SPU::LQXr64; + } else if (RC == SPU::R64FPRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::LQDr64 + : SPU::LQXr64; + } else if (RC == SPU::R32CRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::LQDr32 + : SPU::LQXr32; + } else if (RC == SPU::R32FPRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::LQDr32 + : SPU::LQXr32; + } else if (RC == SPU::R16CRegisterClass) { + opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) + ? SPU::LQDr16 + : SPU::LQXr16; + } else { + assert(0 && "Unknown regclass in loadRegFromStackSlot!"); + abort(); + } + + addFrameReference(BuildMI(MBB, MI, TII.get(opc)).addReg(DestReg), FrameIdx); +} + +/*! + \note We are really pessimistic here about what kind of a load we're doing. + */ +void SPURegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) + const { + cerr << "loadRegToAddr() invoked!\n"; + abort(); + + if (Addr[0].isFrameIndex()) { + /* do what loadRegFromStackSlot does here... */ + } else { + unsigned Opc = 0; + if (RC == SPU::R16CRegisterClass) { + /* Opc = PPC::LWZ; */ + } else if (RC == SPU::R32CRegisterClass) { + /* Opc = PPC::LD; */ + } else if (RC == SPU::R32FPRegisterClass) { + /* Opc = PPC::LFD; */ + } else if (RC == SPU::R64FPRegisterClass) { + /* Opc = PPC::LFS; */ + } else if (RC == SPU::VECREGRegisterClass) { + /* Opc = PPC::LVX; */ + } else if (RC == SPU::GPRCRegisterClass) { + /* Opc = something else! */ + } else { + assert(0 && "Unknown regclass!"); + abort(); + } + MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + } +} + +void SPURegisterInfo::copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const +{ + if (DestRC != SrcRC) { + cerr << "SPURegisterInfo::copyRegToReg(): DestRC != SrcRC not supported!\n"; + abort(); + } + + /* if (DestRC == SPU::R8CRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORBIr8), DestReg).addReg(SrcReg).addImm(0); + } else */ + if (DestRC == SPU::R16CRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORHIr16), DestReg).addReg(SrcReg).addImm(0); + } else if (DestRC == SPU::R32CRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORIr32), DestReg).addReg(SrcReg).addImm(0); + } else if (DestRC == SPU::R32FPRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORIf32), DestReg).addReg(SrcReg).addImm(0); + } else if (DestRC == SPU::R64CRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORIr64), DestReg).addReg(SrcReg).addImm(0); + } else if (DestRC == SPU::R64FPRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORIf64), DestReg).addReg(SrcReg).addImm(0); + } else if (DestRC == SPU::GPRCRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORgprc), DestReg).addReg(SrcReg) + .addReg(SrcReg); + } else if (DestRC == SPU::VECREGRegisterClass) { + BuildMI(MBB, MI, TII.get(SPU::ORv4i32), DestReg).addReg(SrcReg) + .addReg(SrcReg); + } else { + std::cerr << "Attempt to copy unknown/unsupported register class!\n"; + abort(); + } +} + +void SPURegisterInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { + MachineInstr *MI = Orig->clone(); + MI->getOperand(0).setReg(DestReg); + MBB.insert(I, MI); +} + +// SPU's 128-bit registers used for argument passing: +static const unsigned SPU_ArgRegs[] = { + SPU::R3, SPU::R4, SPU::R5, SPU::R6, SPU::R7, SPU::R8, SPU::R9, + SPU::R10, SPU::R11, SPU::R12, SPU::R13, SPU::R14, SPU::R15, SPU::R16, + SPU::R17, SPU::R18, SPU::R19, SPU::R20, SPU::R21, SPU::R22, SPU::R23, + SPU::R24, SPU::R25, SPU::R26, SPU::R27, SPU::R28, SPU::R29, SPU::R30, + SPU::R31, SPU::R32, SPU::R33, SPU::R34, SPU::R35, SPU::R36, SPU::R37, + SPU::R38, SPU::R39, SPU::R40, SPU::R41, SPU::R42, SPU::R43, SPU::R44, + SPU::R45, SPU::R46, SPU::R47, SPU::R48, SPU::R49, SPU::R50, SPU::R51, + SPU::R52, SPU::R53, SPU::R54, SPU::R55, SPU::R56, SPU::R57, SPU::R58, + SPU::R59, SPU::R60, SPU::R61, SPU::R62, SPU::R63, SPU::R64, SPU::R65, + SPU::R66, SPU::R67, SPU::R68, SPU::R69, SPU::R70, SPU::R71, SPU::R72, + SPU::R73, SPU::R74, SPU::R75, SPU::R76, SPU::R77, SPU::R78, SPU::R79 +}; + +const unsigned * +SPURegisterInfo::getArgRegs() +{ + return SPU_ArgRegs; +} + +const unsigned +SPURegisterInfo::getNumArgRegs() +{ + return sizeof(SPU_ArgRegs) / sizeof(SPU_ArgRegs[0]); +} + +const unsigned * +SPURegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const +{ + // Cell ABI calling convention + static const unsigned SPU_CalleeSaveRegs[] = { + SPU::R80, SPU::R81, SPU::R82, SPU::R83, + SPU::R84, SPU::R85, SPU::R86, SPU::R87, + SPU::R88, SPU::R89, SPU::R90, SPU::R91, + SPU::R92, SPU::R93, SPU::R94, SPU::R95, + SPU::R96, SPU::R97, SPU::R98, SPU::R99, + SPU::R100, SPU::R101, SPU::R102, SPU::R103, + SPU::R104, SPU::R105, SPU::R106, SPU::R107, + SPU::R108, SPU::R109, SPU::R110, SPU::R111, + SPU::R112, SPU::R113, SPU::R114, SPU::R115, + SPU::R116, SPU::R117, SPU::R118, SPU::R119, + SPU::R120, SPU::R121, SPU::R122, SPU::R123, + SPU::R124, SPU::R125, SPU::R126, SPU::R127, + SPU::R2, /* environment pointer */ + SPU::R1, /* stack pointer */ + SPU::R0, /* link register */ + 0 /* end */ + }; + + return SPU_CalleeSaveRegs; +} + +const TargetRegisterClass* const* +SPURegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const +{ + // Cell ABI Calling Convention + static const TargetRegisterClass * const SPU_CalleeSaveRegClasses[] = { + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass, + &SPU::GPRCRegClass, /* environment pointer */ + &SPU::GPRCRegClass, /* stack pointer */ + &SPU::GPRCRegClass, /* link register */ + 0 /* end */ + }; + + return SPU_CalleeSaveRegClasses; +} + +/*! + R0 (link register), R1 (stack pointer) and R2 (environment pointer -- this is + generally unused) are the Cell's reserved registers + */ +BitVector SPURegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(SPU::R0); // LR + Reserved.set(SPU::R1); // SP + Reserved.set(SPU::R2); // environment pointer + return Reserved; +} + +/// foldMemoryOperand - SPU, like PPC, can only fold spills into +/// copy instructions, turning them into load/store instructions. +MachineInstr * +SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, + int FrameIndex) const +{ +#if SOMEDAY_SCOTT_LOOKS_AT_ME_AGAIN + unsigned Opc = MI->getOpcode(); + MachineInstr *NewMI = 0; + + if ((Opc == SPU::ORr32 + || Opc == SPU::ORv4i32) + && MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + if (FrameIndex < SPUFrameInfo::maxFrameOffset()) { + NewMI = addFrameReference(BuildMI(TII.get(SPU::STQDr32)).addReg(InReg), + FrameIndex); + } + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + Opc = (FrameIndex < SPUFrameInfo::maxFrameOffset()) ? SPU::STQDr32 : SPU::STQXr32; + NewMI = addFrameReference(BuildMI(TII.get(Opc), OutReg), FrameIndex); + } + } + + if (NewMI) + NewMI->copyKillDeadInfo(MI); + + return NewMI; +#else + return 0; +#endif +} + +/// General-purpose load/store fold to operand code +MachineInstr * +SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, + MachineInstr *LoadMI) const +{ + return 0; +} + +//===----------------------------------------------------------------------===// +// Stack Frame Processing methods +//===----------------------------------------------------------------------===// + +// needsFP - Return true if the specified function should have a dedicated frame +// pointer register. This is true if the function has variable sized allocas or +// if frame pointer elimination is disabled. +// +static bool needsFP(const MachineFunction &MF) { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return NoFramePointerElim || MFI->hasVarSizedObjects(); +} + +//-------------------------------------------------------------------------- +// hasFP - Return true if the specified function actually has a dedicated frame +// pointer register. This is true if the function needs a frame pointer and has +// a non-zero stack size. +bool +SPURegisterInfo::hasFP(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return MFI->getStackSize() && needsFP(MF); +} + +//-------------------------------------------------------------------------- +void +SPURegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) + const +{ + // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. + MBB.erase(I); +} + +void +SPURegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, + RegScavenger *RS) const +{ + assert(SPAdj == 0 && "Unexpected SP adjacency == 0"); + + unsigned i = 0; + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + while (!MI.getOperand(i).isFrameIndex()) { + ++i; + assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); + } + + MachineOperand &SPOp = MI.getOperand(i); + int FrameIndex = SPOp.getFrameIndex(); + + // Now add the frame object offset to the offset from r1. + int Offset = MFI->getObjectOffset(FrameIndex); + + // Most instructions, except for generated FrameIndex additions using AIr32, + // have the immediate in operand 1. AIr32, in this case, has the immediate + // in operand 2. + unsigned OpNo = (MI.getOpcode() != SPU::AIr32 ? 1 : 2); + MachineOperand &MO = MI.getOperand(OpNo); + + // Offset is biased by $lr's slot at the bottom. + Offset += MO.getImmedValue() + MFI->getStackSize() + + SPUFrameInfo::minStackSize(); + assert((Offset & 0xf) == 0 + && "16-byte alignment violated in SPURegisterInfo::eliminateFrameIndex"); + + // Replace the FrameIndex with base register with $sp (aka $r1) + SPOp.ChangeToRegister(SPU::R1, false); + if (Offset > SPUFrameInfo::maxFrameOffset() + || Offset < SPUFrameInfo::minFrameOffset()) { + cerr << "Large stack adjustment (" + << Offset + << ") in SPURegisterInfo::eliminateFrameIndex."; + } else { + MO.ChangeToImmediate(Offset); + } +} + +/// determineFrameLayout - Determine the size of the frame and maximum call +/// frame size. +void +SPURegisterInfo::determineFrameLayout(MachineFunction &MF) const +{ + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Get the number of bytes to allocate from the FrameInfo + unsigned FrameSize = MFI->getStackSize(); + + // Get the alignments provided by the target, and the maximum alignment + // (if any) of the fixed frame objects. + unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned Align = std::max(TargetAlign, MFI->getMaxAlignment()); + assert(isPowerOf2_32(Align) && "Alignment is not power of 2"); + unsigned AlignMask = Align - 1; + + // Get the maximum call frame size of all the calls. + unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); + + // If we have dynamic alloca then maxCallFrameSize needs to be aligned so + // that allocations will be aligned. + if (MFI->hasVarSizedObjects()) + maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; + + // Update maximum call frame size. + MFI->setMaxCallFrameSize(maxCallFrameSize); + + // Include call frame size in total. + FrameSize += maxCallFrameSize; + + // Make sure the frame is aligned. + FrameSize = (FrameSize + AlignMask) & ~AlignMask; + + // Update frame info. + MFI->setStackSize(FrameSize); +} + +void SPURegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) + const { +#if 0 + // Save and clear the LR state. + SPUFunctionInfo *FI = MF.getInfo(); + FI->setUsesLR(MF.isPhysRegUsed(LR)); +#endif + // Mark LR and SP unused, since the prolog spills them to stack and + // we don't want anyone else to spill them for us. + // + // Also, unless R2 is really used someday, don't spill it automatically. + MF.setPhysRegUnused(SPU::R0); + MF.setPhysRegUnused(SPU::R1); + MF.setPhysRegUnused(SPU::R2); +} + +void SPURegisterInfo::emitPrologue(MachineFunction &MF) const +{ + MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB + MachineBasicBlock::iterator MBBI = MBB.begin(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); + + // Prepare for debug frame info. + bool hasDebugInfo = MMI && MMI->hasDebugInfo(); + unsigned FrameLabelId = 0; + + // Move MBBI back to the beginning of the function. + MBBI = MBB.begin(); + + // Work out frame sizes. + determineFrameLayout(MF); + int FrameSize = MFI->getStackSize(); + + assert((FrameSize & 0xf) == 0 + && "SPURegisterInfo::emitPrologue: FrameSize not aligned"); + + if (FrameSize > 0) { + FrameSize = -(FrameSize + SPUFrameInfo::minStackSize()); + if (hasDebugInfo) { + // Mark effective beginning of when frame pointer becomes valid. + FrameLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, TII.get(ISD::LABEL)).addImm(FrameLabelId); + } + + // Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp) + // for the ABI + BuildMI(MBB, MBBI, TII.get(SPU::STQDr32), SPU::R0).addImm(16) + .addReg(SPU::R1); + if (isS10Constant(FrameSize)) { + // Spill $sp to adjusted $sp + BuildMI(MBB, MBBI, TII.get(SPU::STQDr32), SPU::R1).addImm(FrameSize) + .addReg(SPU::R1); + // Adjust $sp by required amout + BuildMI(MBB, MBBI, TII.get(SPU::AIr32), SPU::R1).addReg(SPU::R1) + .addImm(FrameSize); + } else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) { + // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use + // $r2 to adjust $sp: + BuildMI(MBB, MBBI, TII.get(SPU::STQDr128), SPU::R2) + .addImm(-16) + .addReg(SPU::R1); + BuildMI(MBB, MBBI, TII.get(SPU::ILr32), SPU::R2) + .addImm(FrameSize); + BuildMI(MBB, MBBI, TII.get(SPU::STQDr32), SPU::R1) + .addReg(SPU::R2) + .addReg(SPU::R1); + BuildMI(MBB, MBBI, TII.get(SPU::Ar32), SPU::R1) + .addReg(SPU::R1) + .addReg(SPU::R2); + BuildMI(MBB, MBBI, TII.get(SPU::SFIr32), SPU::R2) + .addReg(SPU::R2) + .addImm(16); + BuildMI(MBB, MBBI, TII.get(SPU::LQXr128), SPU::R2) + .addReg(SPU::R2) + .addReg(SPU::R1); + } else { + cerr << "Unhandled frame size: " << FrameSize << "\n"; + abort(); + } + + if (hasDebugInfo) { + std::vector &Moves = MMI->getFrameMoves(); + + // Show update of SP. + MachineLocation SPDst(MachineLocation::VirtualFP); + MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize); + Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); + + // Add callee saved registers to move list. + const std::vector &CSI = MFI->getCalleeSavedInfo(); + for (unsigned I = 0, E = CSI.size(); I != E; ++I) { + int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); + unsigned Reg = CSI[I].getReg(); + if (Reg == SPU::R0) continue; + MachineLocation CSDst(MachineLocation::VirtualFP, Offset); + MachineLocation CSSrc(Reg); + Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); + } + + // Mark effective beginning of when frame pointer is ready. + unsigned ReadyLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, TII.get(ISD::LABEL)).addImm(ReadyLabelId); + + MachineLocation FPDst(SPU::R1); + MachineLocation FPSrc(MachineLocation::VirtualFP); + Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); + } + } else { + // This is a leaf function -- insert a branch hint iff there are + // sufficient number instructions in the basic block. Note that + // this is just a best guess based on the basic block's size. + if (MBB.size() >= (unsigned) SPUFrameInfo::branchHintPenalty()) { + MachineBasicBlock::iterator MBBI = prior(MBB.end()); + // Insert terminator label + unsigned BranchLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, TII.get(SPU::LABEL)).addImm(BranchLabelId); + } + } +} + +void +SPURegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const +{ + MachineBasicBlock::iterator MBBI = prior(MBB.end()); + const MachineFrameInfo *MFI = MF.getFrameInfo(); + int FrameSize = MFI->getStackSize(); + int LinkSlotOffset = SPUFrameInfo::stackSlotSize(); + + assert(MBBI->getOpcode() == SPU::RET && + "Can only insert epilog into returning blocks"); + assert((FrameSize & 0xf) == 0 + && "SPURegisterInfo::emitEpilogue: FrameSize not aligned"); + if (FrameSize > 0) { + FrameSize = FrameSize + SPUFrameInfo::minStackSize(); + if (isS10Constant(FrameSize + LinkSlotOffset)) { + // Reload $lr, adjust $sp by required amount + // Note: We do this to slightly improve dual issue -- not by much, but it + // is an opportunity for dual issue. + BuildMI(MBB, MBBI, TII.get(SPU::LQDr128), SPU::R0) + .addImm(FrameSize + LinkSlotOffset) + .addReg(SPU::R1); + BuildMI(MBB, MBBI, TII.get(SPU::AIr32), SPU::R1) + .addReg(SPU::R1) + .addImm(FrameSize); + } else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) { + // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use + // $r2 to adjust $sp: + BuildMI(MBB, MBBI, TII.get(SPU::STQDr128), SPU::R2) + .addImm(16) + .addReg(SPU::R1); + BuildMI(MBB, MBBI, TII.get(SPU::ILr32), SPU::R2) + .addImm(FrameSize); + BuildMI(MBB, MBBI, TII.get(SPU::Ar32), SPU::R1) + .addReg(SPU::R1) + .addReg(SPU::R2); + BuildMI(MBB, MBBI, TII.get(SPU::LQDr128), SPU::R0) + .addImm(16) + .addReg(SPU::R2); + BuildMI(MBB, MBBI, TII.get(SPU::SFIr32), SPU::R2). + addReg(SPU::R2) + .addImm(16); + BuildMI(MBB, MBBI, TII.get(SPU::LQXr128), SPU::R2) + .addReg(SPU::R2) + .addReg(SPU::R1); + } else { + cerr << "Unhandled frame size: " << FrameSize << "\n"; + abort(); + } + } +} + +unsigned +SPURegisterInfo::getRARegister() const +{ + return SPU::R0; +} + +unsigned +SPURegisterInfo::getFrameRegister(MachineFunction &MF) const +{ + return SPU::R1; +} + +void +SPURegisterInfo::getInitialFrameState(std::vector &Moves) const +{ + // Initial state of the frame pointer is R1. + MachineLocation Dst(MachineLocation::VirtualFP); + MachineLocation Src(SPU::R1, 0); + Moves.push_back(MachineMove(0, Dst, Src)); +} + + +int +SPURegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { + // FIXME: Most probably dwarf numbers differs for Linux and Darwin + return SPUGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); +} + +#include "SPUGenRegisterInfo.inc" Added: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h Tue Dec 4 19:24:05 2007 @@ -0,0 +1,137 @@ +//===- SPURegisterInfo.h - Cell SPU Register Information Impl ----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by The Aerospace Corporation. +// +//===----------------------------------------------------------------------===// +// +// This file contains the Cell SPU implementation of the MRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef SPU_REGISTERINFO_H +#define SPU_REGISTERINFO_H + +#include "SPU.h" +#include "SPUGenRegisterInfo.h.inc" + +namespace llvm { + class SPUSubtarget; + class TargetInstrInfo; + class Type; + + class SPURegisterInfo : public SPUGenRegisterInfo { + private: + const SPUSubtarget &Subtarget; + const TargetInstrInfo &TII; + + //! Predicate: Does the machine function use the link register? + bool usesLR(MachineFunction &MF) const; + + public: + SPURegisterInfo(const SPUSubtarget &subtarget, const TargetInstrInfo &tii); + + //! Translate a register's enum value to a register number + /*! + This method translates a register's enum value to it's regiser number, + e.g. SPU::R14 -> 14. + */ + static unsigned getRegisterNumbering(unsigned RegEnum); + + //! Store a register to a stack slot, based on its register class. + void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned SrcReg, int FrameIndex, + const TargetRegisterClass *RC) const; + + //! Store a register to an address, based on its register class + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const; + + //! Load a register from a stack slot, based on its register class. + void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; + + //! Loqad a register from an address, based on its register class + virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const; + + //! Copy a register to another + void copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; + + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + + //! Fold spills into load/store instructions + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, + int FrameIndex) const; + + //! Fold any load/store to an operand + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, + MachineInstr* LoadMI) const; + + //! Return the array of callee-saved registers + virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF) const; + + //! Return the register class array of the callee-saved registers + virtual const TargetRegisterClass* const * + getCalleeSavedRegClasses(const MachineFunction *MF) const; + + //! Return the reserved registers + BitVector getReservedRegs(const MachineFunction &MF) const; + + //! Prediate: Target has dedicated frame pointer + bool hasFP(const MachineFunction &MF) const; + //! Eliminate the call frame setup pseudo-instructions + void eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const; + //! Convert frame indicies into machine operands + void eliminateFrameIndex(MachineBasicBlock::iterator II, int, + RegScavenger *RS) const; + //! Determine the frame's layour + void determineFrameLayout(MachineFunction &MF) const; + + void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS = NULL) const; + //! Emit the function prologue + void emitPrologue(MachineFunction &MF) const; + //! Emit the function epilogue + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + //! Get return address register (LR, aka R0) + unsigned getRARegister() const; + //! Get the stack frame register (SP, aka R1) + unsigned getFrameRegister(MachineFunction &MF) const; + //! Perform target-specific stack frame setup. + void getInitialFrameState(std::vector &Moves) const; + + //------------------------------------------------------------------------ + // New methods added: + //------------------------------------------------------------------------ + + //! Return the array of argument passing registers + /*! + \note The size of this array is returned by getArgRegsSize(). + */ + static const unsigned *getArgRegs(); + + //! Return the size of the argument passing register array + static const unsigned getNumArgRegs(); + + //! Get DWARF debugging register number + int getDwarfRegNum(unsigned RegNum, bool isEH) const; + }; +} // end namespace llvm + +#endif Added: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td Tue Dec 4 19:24:05 2007 @@ -0,0 +1,393 @@ +//===- SPURegisterInfo.td - The Cell SPU Register File -----*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by The Aerospace Corporation. No distribution rights +// yet determined... +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +class SPUReg : Register { + let Namespace = "SPU"; +} + +// The SPU's register are all 128-bits wide, which makes specifying the +// registers relatively easy, if relatively mundane: + +class SPUVecReg num, string n> : SPUReg { + field bits<7> Num = num; +} + +def R0 : SPUVecReg<0, "$lr">, DwarfRegNum<[0]>; +def R1 : SPUVecReg<1, "$sp">, DwarfRegNum<[1]>; +def R2 : SPUVecReg<2, "$2">, DwarfRegNum<[2]>; +def R3 : SPUVecReg<3, "$3">, DwarfRegNum<[3]>; +def R4 : SPUVecReg<4, "$4">, DwarfRegNum<[4]>; +def R5 : SPUVecReg<5, "$5">, DwarfRegNum<[5]>; +def R6 : SPUVecReg<6, "$6">, DwarfRegNum<[6]>; +def R7 : SPUVecReg<7, "$7">, DwarfRegNum<[7]>; +def R8 : SPUVecReg<8, "$8">, DwarfRegNum<[8]>; +def R9 : SPUVecReg<9, "$9">, DwarfRegNum<[9]>; +def R10 : SPUVecReg<10, "$10">, DwarfRegNum<[10]>; +def R11 : SPUVecReg<11, "$11">, DwarfRegNum<[11]>; +def R12 : SPUVecReg<12, "$12">, DwarfRegNum<[12]>; +def R13 : SPUVecReg<13, "$13">, DwarfRegNum<[13]>; +def R14 : SPUVecReg<14, "$14">, DwarfRegNum<[14]>; +def R15 : SPUVecReg<15, "$15">, DwarfRegNum<[15]>; +def R16 : SPUVecReg<16, "$16">, DwarfRegNum<[16]>; +def R17 : SPUVecReg<17, "$17">, DwarfRegNum<[17]>; +def R18 : SPUVecReg<18, "$18">, DwarfRegNum<[18]>; +def R19 : SPUVecReg<19, "$19">, DwarfRegNum<[19]>; +def R20 : SPUVecReg<20, "$20">, DwarfRegNum<[20]>; +def R21 : SPUVecReg<21, "$21">, DwarfRegNum<[21]>; +def R22 : SPUVecReg<22, "$22">, DwarfRegNum<[22]>; +def R23 : SPUVecReg<23, "$23">, DwarfRegNum<[23]>; +def R24 : SPUVecReg<24, "$24">, DwarfRegNum<[24]>; +def R25 : SPUVecReg<25, "$25">, DwarfRegNum<[25]>; +def R26 : SPUVecReg<26, "$26">, DwarfRegNum<[26]>; +def R27 : SPUVecReg<27, "$27">, DwarfRegNum<[27]>; +def R28 : SPUVecReg<28, "$28">, DwarfRegNum<[28]>; +def R29 : SPUVecReg<29, "$29">, DwarfRegNum<[29]>; +def R30 : SPUVecReg<30, "$30">, DwarfRegNum<[30]>; +def R31 : SPUVecReg<31, "$31">, DwarfRegNum<[31]>; +def R32 : SPUVecReg<32, "$32">, DwarfRegNum<[32]>; +def R33 : SPUVecReg<33, "$33">, DwarfRegNum<[33]>; +def R34 : SPUVecReg<34, "$34">, DwarfRegNum<[34]>; +def R35 : SPUVecReg<35, "$35">, DwarfRegNum<[35]>; +def R36 : SPUVecReg<36, "$36">, DwarfRegNum<[36]>; +def R37 : SPUVecReg<37, "$37">, DwarfRegNum<[37]>; +def R38 : SPUVecReg<38, "$38">, DwarfRegNum<[38]>; +def R39 : SPUVecReg<39, "$39">, DwarfRegNum<[39]>; +def R40 : SPUVecReg<40, "$40">, DwarfRegNum<[40]>; +def R41 : SPUVecReg<41, "$41">, DwarfRegNum<[41]>; +def R42 : SPUVecReg<42, "$42">, DwarfRegNum<[42]>; +def R43 : SPUVecReg<43, "$43">, DwarfRegNum<[43]>; +def R44 : SPUVecReg<44, "$44">, DwarfRegNum<[44]>; +def R45 : SPUVecReg<45, "$45">, DwarfRegNum<[45]>; +def R46 : SPUVecReg<46, "$46">, DwarfRegNum<[46]>; +def R47 : SPUVecReg<47, "$47">, DwarfRegNum<[47]>; +def R48 : SPUVecReg<48, "$48">, DwarfRegNum<[48]>; +def R49 : SPUVecReg<49, "$49">, DwarfRegNum<[49]>; +def R50 : SPUVecReg<50, "$50">, DwarfRegNum<[50]>; +def R51 : SPUVecReg<51, "$51">, DwarfRegNum<[51]>; +def R52 : SPUVecReg<52, "$52">, DwarfRegNum<[52]>; +def R53 : SPUVecReg<53, "$53">, DwarfRegNum<[53]>; +def R54 : SPUVecReg<54, "$54">, DwarfRegNum<[54]>; +def R55 : SPUVecReg<55, "$55">, DwarfRegNum<[55]>; +def R56 : SPUVecReg<56, "$56">, DwarfRegNum<[56]>; +def R57 : SPUVecReg<57, "$57">, DwarfRegNum<[57]>; +def R58 : SPUVecReg<58, "$58">, DwarfRegNum<[58]>; +def R59 : SPUVecReg<59, "$59">, DwarfRegNum<[59]>; +def R60 : SPUVecReg<60, "$60">, DwarfRegNum<[60]>; +def R61 : SPUVecReg<61, "$61">, DwarfRegNum<[61]>; +def R62 : SPUVecReg<62, "$62">, DwarfRegNum<[62]>; +def R63 : SPUVecReg<63, "$63">, DwarfRegNum<[63]>; +def R64 : SPUVecReg<64, "$64">, DwarfRegNum<[64]>; +def R65 : SPUVecReg<65, "$65">, DwarfRegNum<[65]>; +def R66 : SPUVecReg<66, "$66">, DwarfRegNum<[66]>; +def R67 : SPUVecReg<67, "$67">, DwarfRegNum<[67]>; +def R68 : SPUVecReg<68, "$68">, DwarfRegNum<[68]>; +def R69 : SPUVecReg<69, "$69">, DwarfRegNum<[69]>; +def R70 : SPUVecReg<70, "$70">, DwarfRegNum<[70]>; +def R71 : SPUVecReg<71, "$71">, DwarfRegNum<[71]>; +def R72 : SPUVecReg<72, "$72">, DwarfRegNum<[72]>; +def R73 : SPUVecReg<73, "$73">, DwarfRegNum<[73]>; +def R74 : SPUVecReg<74, "$74">, DwarfRegNum<[74]>; +def R75 : SPUVecReg<75, "$75">, DwarfRegNum<[75]>; +def R76 : SPUVecReg<76, "$76">, DwarfRegNum<[76]>; +def R77 : SPUVecReg<77, "$77">, DwarfRegNum<[77]>; +def R78 : SPUVecReg<78, "$78">, DwarfRegNum<[78]>; +def R79 : SPUVecReg<79, "$79">, DwarfRegNum<[79]>; +def R80 : SPUVecReg<80, "$80">, DwarfRegNum<[80]>; +def R81 : SPUVecReg<81, "$81">, DwarfRegNum<[81]>; +def R82 : SPUVecReg<82, "$82">, DwarfRegNum<[82]>; +def R83 : SPUVecReg<83, "$83">, DwarfRegNum<[83]>; +def R84 : SPUVecReg<84, "$84">, DwarfRegNum<[84]>; +def R85 : SPUVecReg<85, "$85">, DwarfRegNum<[85]>; +def R86 : SPUVecReg<86, "$86">, DwarfRegNum<[86]>; +def R87 : SPUVecReg<87, "$87">, DwarfRegNum<[87]>; +def R88 : SPUVecReg<88, "$88">, DwarfRegNum<[88]>; +def R89 : SPUVecReg<89, "$89">, DwarfRegNum<[89]>; +def R90 : SPUVecReg<90, "$90">, DwarfRegNum<[90]>; +def R91 : SPUVecReg<91, "$91">, DwarfRegNum<[91]>; +def R92 : SPUVecReg<92, "$92">, DwarfRegNum<[92]>; +def R93 : SPUVecReg<93, "$93">, DwarfRegNum<[93]>; +def R94 : SPUVecReg<94, "$94">, DwarfRegNum<[94]>; +def R95 : SPUVecReg<95, "$95">, DwarfRegNum<[95]>; +def R96 : SPUVecReg<96, "$96">, DwarfRegNum<[96]>; +def R97 : SPUVecReg<97, "$97">, DwarfRegNum<[97]>; +def R98 : SPUVecReg<98, "$98">, DwarfRegNum<[98]>; +def R99 : SPUVecReg<99, "$99">, DwarfRegNum<[99]>; +def R100 : SPUVecReg<100, "$100">, DwarfRegNum<[100]>; +def R101 : SPUVecReg<101, "$101">, DwarfRegNum<[101]>; +def R102 : SPUVecReg<102, "$102">, DwarfRegNum<[102]>; +def R103 : SPUVecReg<103, "$103">, DwarfRegNum<[103]>; +def R104 : SPUVecReg<104, "$104">, DwarfRegNum<[104]>; +def R105 : SPUVecReg<105, "$105">, DwarfRegNum<[105]>; +def R106 : SPUVecReg<106, "$106">, DwarfRegNum<[106]>; +def R107 : SPUVecReg<107, "$107">, DwarfRegNum<[107]>; +def R108 : SPUVecReg<108, "$108">, DwarfRegNum<[108]>; +def R109 : SPUVecReg<109, "$109">, DwarfRegNum<[109]>; +def R110 : SPUVecReg<110, "$110">, DwarfRegNum<[110]>; +def R111 : SPUVecReg<111, "$111">, DwarfRegNum<[111]>; +def R112 : SPUVecReg<112, "$112">, DwarfRegNum<[112]>; +def R113 : SPUVecReg<113, "$113">, DwarfRegNum<[113]>; +def R114 : SPUVecReg<114, "$114">, DwarfRegNum<[114]>; +def R115 : SPUVecReg<115, "$115">, DwarfRegNum<[115]>; +def R116 : SPUVecReg<116, "$116">, DwarfRegNum<[116]>; +def R117 : SPUVecReg<117, "$117">, DwarfRegNum<[117]>; +def R118 : SPUVecReg<118, "$118">, DwarfRegNum<[118]>; +def R119 : SPUVecReg<119, "$119">, DwarfRegNum<[119]>; +def R120 : SPUVecReg<120, "$120">, DwarfRegNum<[120]>; +def R121 : SPUVecReg<121, "$121">, DwarfRegNum<[121]>; +def R122 : SPUVecReg<122, "$122">, DwarfRegNum<[122]>; +def R123 : SPUVecReg<123, "$123">, DwarfRegNum<[123]>; +def R124 : SPUVecReg<124, "$124">, DwarfRegNum<[124]>; +def R125 : SPUVecReg<125, "$125">, DwarfRegNum<[125]>; +def R126 : SPUVecReg<126, "$126">, DwarfRegNum<[126]>; +def R127 : SPUVecReg<127, "$127">, DwarfRegNum<[127]>; + +/* Need floating point status register here: */ +/* def FPCSR : ... */ + +// The SPU's registers as 128-bit wide entities, and can function as general +// purpose registers, where the operands are in the "preferred slot": +def GPRC : RegisterClass<"SPU", [i128], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + GPRCClass::iterator + GPRCClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + GPRCClass::iterator + GPRCClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} + +// The SPU's registers as 64-bit wide (double word integer) "preferred slot": +def R64C : RegisterClass<"SPU", [i64], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + R64CClass::iterator + R64CClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + R64CClass::iterator + R64CClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} + +// The SPU's registers as 64-bit wide (double word) FP "preferred slot": +def R64FP : RegisterClass<"SPU", [f64], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + R64FPClass::iterator + R64FPClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + R64FPClass::iterator + R64FPClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} + +// The SPU's registers as 32-bit wide (word) "preferred slot": +def R32C : RegisterClass<"SPU", [i32], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + R32CClass::iterator + R32CClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + R32CClass::iterator + R32CClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} + +// The SPU's registers as single precision floating point "preferred slot": +def R32FP : RegisterClass<"SPU", [f32], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + R32FPClass::iterator + R32FPClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + R32FPClass::iterator + R32FPClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} + +// The SPU's registers as 16-bit wide (halfword) "preferred slot": +def R16C : RegisterClass<"SPU", [i16], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + R16CClass::iterator + R16CClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + R16CClass::iterator + R16CClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} + +// The SPU's registers as vector registers: +def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128, + [ + /* volatile register */ + R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, + R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, + R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, + R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61, + R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, + R77, R78, R79, + /* non-volatile register: take hint from PPC and allocate in reverse order */ + R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115, + R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102, + R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, + R86, R85, R84, R83, R82, R81, R80, + /* environment ptr, SP, LR */ + R2, R1, R0 ]> +{ + let MethodProtos = [{ + iterator allocation_order_begin(const MachineFunction &MF) const; + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + VECREGClass::iterator + VECREGClass::allocation_order_begin(const MachineFunction &MF) const { + return begin(); + } + VECREGClass::iterator + VECREGClass::allocation_order_end(const MachineFunction &MF) const { + return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr) + } + }]; +} Added: llvm/trunk/lib/Target/CellSPU/SPUSchedule.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUSchedule.td?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUSchedule.td (added) +++ llvm/trunk/lib/Target/CellSPU/SPUSchedule.td Tue Dec 4 19:24:05 2007 @@ -0,0 +1,59 @@ +//===- SPUSchedule.td - Cell Scheduling Definitions --------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Even pipeline: + +def EVEN_UNIT : FuncUnit; // Even execution unit: (PC & 0x7 == 000) +def ODD_UNIT : FuncUnit; // Odd execution unit: (PC & 0x7 == 100) + +//===----------------------------------------------------------------------===// +// Instruction Itinerary classes used for Cell SPU +//===----------------------------------------------------------------------===// + +def LoadStore : InstrItinClass; // ODD_UNIT +def BranchHints : InstrItinClass; // ODD_UNIT +def BranchResolv : InstrItinClass; // ODD_UNIT +def ChanOpSPR : InstrItinClass; // ODD_UNIT +def ShuffleOp : InstrItinClass; // ODD_UNIT +def SelectOp : InstrItinClass; // ODD_UNIT +def GatherOp : InstrItinClass; // ODD_UNIT +def LoadNOP : InstrItinClass; // ODD_UNIT +def ExecNOP : InstrItinClass; // EVEN_UNIT +def SPrecFP : InstrItinClass; // EVEN_UNIT +def DPrecFP : InstrItinClass; // EVEN_UNIT +def FPInt : InstrItinClass; // EVEN_UNIT (FP<->integer) +def ByteOp : InstrItinClass; // EVEN_UNIT +def IntegerOp : InstrItinClass; // EVEN_UNIT +def IntegerMulDiv: InstrItinClass; // EVEN_UNIT +def RotateShift : InstrItinClass; // EVEN_UNIT +def ImmLoad : InstrItinClass; // EVEN_UNIT + +/* Note: The itinerary for the Cell SPU is somewhat contrived... */ +def SPUItineraries : ProcessorItineraries<[ + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]>, + InstrItinData]> + ]>; Added: llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp Tue Dec 4 19:24:05 2007 @@ -0,0 +1,42 @@ +//===- SPUSubtarget.cpp - STI Cell SPU Subtarget Information --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CellSPU-specific subclass of TargetSubtarget. +// +//===----------------------------------------------------------------------===// + +#include "SPUSubtarget.h" +#include "SPU.h" +#include "llvm/Module.h" +#include "llvm/Target/TargetMachine.h" +#include "SPUGenSubtarget.inc" + +using namespace llvm; + +SPUSubtarget::SPUSubtarget(const TargetMachine &tm, const Module &M, + const std::string &FS) : + TM(tm), + StackAlignment(16), + ProcDirective(SPU::DEFAULT_PROC), + UseLargeMem(false) +{ + // Should be the target SPU processor type. For now, since there's only + // one, simply default to the current "v0" default: + std::string default_cpu("v0"); + + // Parse features string. + ParseSubtargetFeatures(FS, default_cpu); +} + +/// SetJITMode - This is called to inform the subtarget info that we are +/// producing code for the JIT. +void SPUSubtarget::SetJITMode() { +} Added: llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h Tue Dec 4 19:24:05 2007 @@ -0,0 +1,95 @@ +//=====-- SPUSubtarget.h - Define Subtarget for the Cell SPU -----*- C++ -*--=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the Cell SPU-specific subclass of TargetSubtarget. +// +//===----------------------------------------------------------------------===// + +#ifndef POWERPCSUBTARGET_H +#define POWERPCSUBTARGET_H + +#include "llvm/Target/TargetInstrItineraries.h" +#include "llvm/Target/TargetSubtarget.h" + +#include + +namespace llvm { + class Module; + class GlobalValue; + class TargetMachine; + + namespace SPU { + enum { + DEFAULT_PROC + }; + } + + class SPUSubtarget : public TargetSubtarget { + protected: + const TargetMachine &TM; + + /// stackAlignment - The minimum alignment known to hold of the stack frame + /// on entry to the function and which must be maintained by every function. + unsigned StackAlignment; + + /// Selected instruction itineraries (one entry per itinerary class.) + InstrItineraryData InstrItins; + + /// Which SPU processor (this isn't really used, but it's there to keep + /// the C compiler happy) + unsigned ProcDirective; + + /// Use (assume) large memory -- effectively disables the LQA/STQA + /// instructions that assume 259K local store. + bool UseLargeMem; + + public: + /// This constructor initializes the data members to match that + /// of the specified module. + /// + SPUSubtarget(const TargetMachine &TM, const Module &M, + const std::string &FS); + + /// ParseSubtargetFeatures - Parses features string setting specified + /// subtarget options. Definition of function is auto generated by tblgen. + void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); + + /// SetJITMode - This is called to inform the subtarget info that we are + /// producing code for the JIT. + void SetJITMode(); + + /// getStackAlignment - Returns the minimum alignment known to hold of the + /// stack frame on entry to the function and which must be maintained by + /// every function for this subtarget. + unsigned getStackAlignment() const { return StackAlignment; } + + /// getInstrItins - Return the instruction itineraies based on subtarget + /// selection. + const InstrItineraryData &getInstrItineraryData() const { + return InstrItins; + } + + /// Use large memory addressing predicate + bool usingLargeMem() const { + return UseLargeMem; + } + + /// getTargetDataString - Return the pointer size and type alignment + /// properties of this subtarget. + const char *getTargetDataString() const { + return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128" + "-i16:16:128-i8:8:128-i1:8:128-a:0:128-v128:128:128" + "-s:128:128"; + } + }; +} // End llvm namespace + +#endif Added: llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp Tue Dec 4 19:24:05 2007 @@ -0,0 +1,56 @@ +//===-- SPUTargetAsmInfo.cpp - Cell SPU asm properties ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the SPUTargetAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "SPUTargetAsmInfo.h" +#include "SPUTargetMachine.h" +#include "llvm/Function.h" +using namespace llvm; + +SPUTargetAsmInfo::SPUTargetAsmInfo(const SPUTargetMachine &TM) { + CommentString = "#"; + GlobalPrefix = ""; + PrivateGlobalPrefix = ".L"; + ZeroDirective = "\t.space\t"; + SetDirective = "\t.set"; + Data64bitsDirective = "\t.quad\t"; + AlignmentIsInBytes = false; + SwitchToSectionDirective = "\t.section\t"; + ConstantPoolSection = "\t.const\t"; + JumpTableDataSection = ".const"; + CStringSection = "\t.cstring"; + LCOMMDirective = "\t.lcomm\t"; + StaticCtorsSection = ".mod_init_func"; + StaticDtorsSection = ".mod_term_func"; + FourByteConstantSection = ".const"; + SixteenByteConstantSection = "\t.section\t.rodata.cst16,\"aM\", at progbits,16"; + UsedDirective = "\t.no_dead_strip\t"; + WeakRefDirective = "\t.weak_reference\t"; + InlineAsmStart = "# InlineAsm Start"; + InlineAsmEnd = "# InlineAsm End"; + + NeedsSet = true; + /* FIXME: Need actual assembler syntax for DWARF info: */ + DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; + DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; + DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; + DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; + DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; + DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; + DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; + DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; + DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; + DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; + DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; +} Added: llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h Tue Dec 4 19:24:05 2007 @@ -0,0 +1,32 @@ +//=====-- SPUTargetAsmInfo.h - Cell SPU asm properties --------*- C++ -*--====// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the SPUTargetAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef PPCTARGETASMINFO_H +#define PPCTARGETASMINFO_H + +#include "llvm/Target/TargetAsmInfo.h" + +namespace llvm { + + // Forward declaration. + class SPUTargetMachine; + + struct SPUTargetAsmInfo : public TargetAsmInfo { + SPUTargetAsmInfo(const SPUTargetMachine &TM); + }; + +} // namespace llvm + +#endif Added: llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp (added) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp Tue Dec 4 19:24:05 2007 @@ -0,0 +1,87 @@ +//===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// Top-level implementation for the Cell SPU target. +// +//===----------------------------------------------------------------------===// + +#include "SPU.h" +#include "SPURegisterNames.h" +#include "SPUTargetAsmInfo.h" +#include "SPUTargetMachine.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/Target/TargetMachineRegistry.h" + +using namespace llvm; + +namespace { + // Register the targets + RegisterTarget + CELLSPU("cellspu", " STI CBEA Cell SPU"); +} + +const std::pair * +SPUFrameInfo::getCalleeSaveSpillSlots(unsigned &NumEntries) const { + NumEntries = 1; + return &LR[0]; +} + +const TargetAsmInfo * +SPUTargetMachine::createTargetAsmInfo() const +{ + return new SPUTargetAsmInfo(*this); +} + +unsigned +SPUTargetMachine::getModuleMatchQuality(const Module &M) +{ + // We strongly match "spu-*" or "cellspu-*". + std::string TT = M.getTargetTriple(); + if ((TT.size() == 3 && std::string(TT.begin(), TT.begin()+3) == "spu") + || (TT.size() == 7 && std::string(TT.begin(), TT.begin()+7) == "cellspu") + || (TT.size() >= 4 && std::string(TT.begin(), TT.begin()+4) == "spu-") + || (TT.size() >= 8 && std::string(TT.begin(), TT.begin()+8) == "cellspu-")) + return 20; + + return 0; // No match at all... +} + +SPUTargetMachine::SPUTargetMachine(const Module &M, const std::string &FS) + : Subtarget(*this, M, FS), + DataLayout(Subtarget.getTargetDataString()), + InstrInfo(*this), + FrameInfo(*this), + TLInfo(*this), + InstrItins(Subtarget.getInstrItineraryData()) +{ + // For the time being, use static relocations, since there's really no + // support for PIC yet. + setRelocationModel(Reloc::Static); +} + +//===----------------------------------------------------------------------===// +// Pass Pipeline Configuration +//===----------------------------------------------------------------------===// + +bool +SPUTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) +{ + // Install an instruction selector. + PM.add(createSPUISelDag(*this)); + return false; +} + +bool SPUTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast, + std::ostream &Out) { + PM.add(createSPUAsmPrinterPass(Out, *this)); + return false; +} Added: llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h?rev=44595&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h Tue Dec 4 19:24:05 2007 @@ -0,0 +1,95 @@ +//===-- SPUTargetMachine.h - Define TargetMachine for Cell SPU ----*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the CellSPU-specific subclass of TargetMachine. +// +//===----------------------------------------------------------------------===// + +#ifndef SPU_TARGETMACHINE_H +#define SPU_TARGETMACHINE_H + +#include "SPUSubtarget.h" +#include "SPUInstrInfo.h" +#include "SPUISelLowering.h" +#include "SPUFrameInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" + +namespace llvm { +class PassManager; +class GlobalValue; +class TargetFrameInfo; + +/// SPUTargetMachine +/// +class SPUTargetMachine : public LLVMTargetMachine { + SPUSubtarget Subtarget; + const TargetData DataLayout; + SPUInstrInfo InstrInfo; + SPUFrameInfo FrameInfo; + SPUTargetLowering TLInfo; + InstrItineraryData InstrItins; + +protected: + virtual const TargetAsmInfo *createTargetAsmInfo() const; + +public: + SPUTargetMachine(const Module &M, const std::string &FS); + + /// Return the subtarget implementation object + virtual const SPUSubtarget *getSubtargetImpl() const { + return &Subtarget; + } + virtual const SPUInstrInfo *getInstrInfo() const { + return &InstrInfo; + } + virtual const TargetFrameInfo *getFrameInfo() const { + return &FrameInfo; + } + /*! + \note Cell SPU does not support JIT today. It could support JIT at some + point. + */ + virtual TargetJITInfo *getJITInfo() { + return NULL; + } + + //! Module match function + /*! + Module matching function called by TargetMachineRegistry(). + */ + static unsigned getModuleMatchQuality(const Module &M); + + virtual SPUTargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } + + virtual const MRegisterInfo *getRegisterInfo() const { + return &InstrInfo.getRegisterInfo(); + } + + virtual const TargetData *getTargetData() const { + return &DataLayout; + } + + virtual const InstrItineraryData getInstrItineraryData() const { + return InstrItins; + } + + // Pass Pipeline Configuration + virtual bool addInstSelector(FunctionPassManager &PM, bool Fast); + virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast, + std::ostream &Out); +}; + +} // end namespace llvm + +#endif From scottm at aero.org Tue Dec 4 19:31:18 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 01:31:18 -0000 Subject: [llvm-commits] [llvm] r44596 - in /llvm/trunk/lib/Target/CellSPU: CellSDKIntrinsics.td SPURegisterNames.h Message-ID: <200712050131.lB51VIDX009351@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 19:31:18 2007 New Revision: 44596 URL: http://llvm.org/viewvc/llvm-project?rev=44596&view=rev Log: Two missing files. Added: llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h Added: llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td?rev=44596&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td (added) +++ llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td Tue Dec 4 19:31:18 2007 @@ -0,0 +1,449 @@ +//===-- CellSDKIntrinsics.td - Cell SDK Intrinsics ---------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +//===----------------------------------------------------------------------===// + +///--==-- Arithmetic ops intrinsics --==-- +def CellSDKah: + RR_Int_v8i16<0b00010011000, "ah", IntegerOp, int_spu_si_ah>; +def CellSDKahi: + RI10_Int_v8i16<0b00010011000, "ahi", IntegerOp, int_spu_si_ahi>; +def CellSDKa: + RR_Int_v4i32<0b00000011000, "a", IntegerOp, int_spu_si_a>; +def CellSDKai: + RI10_Int_v4i32<0b00111000, "ai", IntegerOp, int_spu_si_ai>; +def CellSDKsfh: + RR_Int_v8i16<0b00010010000, "sfh", IntegerOp, int_spu_si_sfh>; +def CellSDKsfhi: + RI10_Int_v8i16<0b10110000, "sfhi", IntegerOp, int_spu_si_sfhi>; +def CellSDKsf: + RR_Int_v4i32<0b00000010000, "sf", IntegerOp, int_spu_si_sf>; +def CellSDKsfi: + RI10_Int_v4i32<0b00110000, "sfi", IntegerOp, int_spu_si_sfi>; +def CellSDKaddx: + RR_Int_v4i32<0b00000010110, "addx", IntegerOp, int_spu_si_addx>; +def CellSDKcg: + RR_Int_v4i32<0b0100001100, "cg", IntegerOp, int_spu_si_cg>; +def CellSDKcgx: + RR_Int_v4i32<0b01000010110, "cgx", IntegerOp, int_spu_si_cgx>; +def CellSDKsfx: + RR_Int_v4i32<0b10000010110, "sfx", IntegerOp, int_spu_si_sfx>; +def CellSDKbg: + RR_Int_v4i32<0b01000010000, "bg", IntegerOp, int_spu_si_bg>; +def CellSDKbgx: + RR_Int_v4i32<0b11000010110, "bgx", IntegerOp, int_spu_si_bgx>; + +def CellSDKmpy: + RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpy $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpy (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def CellSDKmpyu: + RRForm<0b00110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyu $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyu (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))] >; + +def CellSDKmpyi: + RI10Form<0b00101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "mpyi $rT, $rA, $val", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyi (v8i16 VECREG:$rA), + i16ImmSExt10:$val))]>; + +def CellSDKmpyui: + RI10Form<0b10101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "mpyui $rT, $rA, $val", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyui (v8i16 VECREG:$rA), + i16ImmSExt10:$val))]>; + +def CellSDKmpya: + RRRForm<0b0011, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "mpya $rT, $rA, $rB, $rC", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpya (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB), + (v8i16 VECREG:$rC)))]>; + +def CellSDKmpyh: + RRForm<0b10100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyh $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyh (v4i32 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def CellSDKmpys: + RRForm<0b11100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpys $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpys (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def CellSDKmpyhh: + RRForm<0b01100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhh $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyhh (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def CellSDKmpyhha: + RRForm<0b01100010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhha $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyhha (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +// Not sure how to match a (set $rT, (add $rT (mpyhh $rA, $rB)))... so leave +// as an intrinsic for the time being +def CellSDKmpyhhu: + RRForm<0b01110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhhu $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyhhu (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def CellSDKmpyhhau: + RRForm<0b01110010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "mpyhhau $rT, $rA, $rB", IntegerMulDiv, + [(set (v4i32 VECREG:$rT), (int_spu_si_mpyhhau (v8i16 VECREG:$rA), + (v8i16 VECREG:$rB)))]>; + +def CellSDKand: + RRForm<0b1000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "add\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKandc: + RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "addc\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_andc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKandbi: + RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "andbi\t $rT, $rA, $val", BranchResolv, + [(set (v16i8 VECREG:$rT), + (int_spu_si_andbi (v16i8 VECREG:$rA), immU8:$val))]>; + +def CellSDKandhi: + RI10Form<0b10101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "andhi\t $rT, $rA, $val", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_andhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>; + +def CellSDKandi: + RI10Form<0b00101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "andi\t $rT, $rA, $val", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_andi (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>; + +def CellSDKor: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "or\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKorc: + RRForm<0b10010011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "addc\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_orc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKorbi: + RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "orbi\t $rT, $rA, $val", BranchResolv, + [(set (v16i8 VECREG:$rT), + (int_spu_si_orbi (v16i8 VECREG:$rA), immU8:$val))]>; + +def CellSDKorhi: + RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "orhi\t $rT, $rA, $val", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_orhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>; + +def CellSDKori: + RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ori\t $rT, $rA, $val", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_ori (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>; + +def CellSDKxor: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "xor\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKxorbi: + RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "xorbi\t $rT, $rA, $val", BranchResolv, + [(set (v16i8 VECREG:$rT), (int_spu_si_xorbi (v16i8 VECREG:$rA), immU8:$val))]>; + +def CellSDKxorhi: + RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "xorhi\t $rT, $rA, $val", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_xorhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>; + +def CellSDKxori: + RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "xori\t $rT, $rA, $val", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_xori (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>; + +def CellSDKnor: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nor\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_nor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKnand: + RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "nand\t $rT, $rA, $rB", IntegerOp, + [(set (v4i32 VECREG:$rT), + (int_spu_si_nand (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +//===----------------------------------------------------------------------===// +// Shift/rotate intrinsics: +//===----------------------------------------------------------------------===// + +def CellSDKshli: + Pat<(int_spu_si_shli (v4i32 VECREG:$rA), uimm7:$val), + (SHLIv4i32 VECREG:$rA, uimm7:$val)>; + +def CellSDKshlqbi: + Pat<(int_spu_si_shlqbi VECREG:$rA, VECREG:$rB), + (SHLQBIvec VECREG:$rA, VECREG:$rB)>; + +def CellSDKshlqii: + Pat<(int_spu_si_shlqbii VECREG:$rA, uimm7:$val), + (SHLQBIIvec VECREG:$rA, uimm7:$val)>; + +def CellSDKshlqby: + Pat<(int_spu_si_shlqby VECREG:$rA, VECREG:$rB), + (SHLQBYvec VECREG:$rA, VECREG:$rB)>; + +def CellSDKshlqbyi: + Pat<(int_spu_si_shlqbyi VECREG:$rA, uimm7:$val), + (SHLQBYIvec VECREG:$rA, uimm7:$val)>; + +//===----------------------------------------------------------------------===// +// Branch/compare intrinsics: +//===----------------------------------------------------------------------===// + +def CellSDKceq: + RRForm<0b00000011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ceq\t $rT, $rA, $rB", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_ceq (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKceqi: + RI10Form<0b00111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ceqi\t $rT, $rA, $val", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_ceqi (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>; + +def CellSDKceqb: + RRForm<0b00001011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ceqb\t $rT, $rA, $rB", BranchResolv, + [(set (v16i8 VECREG:$rT), + (int_spu_si_ceqb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; + +def CellSDKceqbi: + RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "ceqbi\t $rT, $rA, $val", BranchResolv, + [(set (v16i8 VECREG:$rT), (int_spu_si_ceqbi (v16i8 VECREG:$rA), immU8:$val))]>; + +def CellSDKceqh: + RRForm<0b00010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "ceqh\t $rT, $rA, $rB", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_ceqh (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def CellSDKceqhi: + RI10Form<0b10111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "ceqhi\t $rT, $rA, $val", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_ceqhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>; +def CellSDKcgth: + RRForm<0b00010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "cgth\t $rT, $rA, $rB", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_cgth (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def CellSDKcgthi: + RI10Form<0b10111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "cgthi\t $rT, $rA, $val", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_cgthi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>; + +def CellSDKcgt: + RRForm<0b00000010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "cgt\t $rT, $rA, $rB", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_cgt (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKcgti: + RI10Form<0b00110010, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "cgti\t $rT, $rA, $val", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_cgti (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>; + +def CellSDKcgtb: + RRForm<0b00001010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "cgtb\t $rT, $rA, $rB", BranchResolv, + [(set (v16i8 VECREG:$rT), + (int_spu_si_cgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; + +def CellSDKcgtbi: + RI10Form<0b01110010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "cgtbi\t $rT, $rA, $val", BranchResolv, + [(set (v16i8 VECREG:$rT), (int_spu_si_cgtbi (v16i8 VECREG:$rA), immU8:$val))]>; + +def CellSDKclgth: + RRForm<0b00010011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "clgth\t $rT, $rA, $rB", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_clgth (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; + +def CellSDKclgthi: + RI10Form<0b10111010, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "clgthi\t $rT, $rA, $val", BranchResolv, + [(set (v8i16 VECREG:$rT), + (int_spu_si_clgthi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>; + +def CellSDKclgt: + RRForm<0b00000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "clgt\t $rT, $rA, $rB", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_clgt (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; + +def CellSDKclgti: + RI10Form<0b00111010, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), + "clgti\t $rT, $rA, $val", BranchResolv, + [(set (v4i32 VECREG:$rT), + (int_spu_si_clgti (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>; + +def CellSDKclgtb: + RRForm<0b00001011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "clgtb\t $rT, $rA, $rB", BranchResolv, + [(set (v16i8 VECREG:$rT), + (int_spu_si_clgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; + +def CellSDKclgtbi: + RI10Form<0b01111010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), + "clgtbi\t $rT, $rA, $val", BranchResolv, + [(set (v16i8 VECREG:$rT), + (int_spu_si_clgtbi (v16i8 VECREG:$rA), immU8:$val))]>; + +//===----------------------------------------------------------------------===// +// Floating-point intrinsics: +//===----------------------------------------------------------------------===// + +def CellSDKfa: + RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fa\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fa (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfs: + RRForm<0b10100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fs\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fs (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfm: + RRForm<0b01100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fm\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fm (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfceq: + RRForm<0b01000011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fceq\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fceq (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfcgt: + RRForm<0b01000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fcgt\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fcgt (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfcmeq: + RRForm<0b01010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fcmeq\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fcmeq (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfcmgt: + RRForm<0b01010011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "fcmgt\t $rT, $rA, $rB", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fcmgt (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB)))]>; + +def CellSDKfma: + RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "fma\t $rT, $rA, $rB, $rC", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fma (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB), + (v4f32 VECREG:$rC)))]>; + +def CellSDKfnms: + RRRForm<0b1011, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "fnms\t $rT, $rA, $rB, $rC", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fnms (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB), + (v4f32 VECREG:$rC)))]>; + +def CellSDKfms: + RRRForm<0b1111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + "fms\t $rT, $rA, $rB, $rC", SPrecFP, + [(set (v4f32 VECREG:$rT), (int_spu_si_fms (v4f32 VECREG:$rA), + (v4f32 VECREG:$rB), + (v4f32 VECREG:$rC)))]>; + +//===----------------------------------------------------------------------===// +// Double precision floating-point intrinsics: +//===----------------------------------------------------------------------===// + +def CellSDKdfa: + RRForm<0b00110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfa\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfa (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; + +def CellSDKdfs: + RRForm<0b10110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfs\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfs (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; + +def CellSDKdfm: + RRForm<0b01110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfm\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfm (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; + +def CellSDKdfma: + RRForm<0b00111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfma\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfma (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; + +def CellSDKdfnma: + RRForm<0b11111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfnma\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfnma (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; + +def CellSDKdfnms: + RRForm<0b01111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfnms\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfnms (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; + +def CellSDKdfms: + RRForm<0b10111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + "dfms\t $rT, $rA, $rB", DPrecFP, + [(set (v2f64 VECREG:$rT), (int_spu_si_dfms (v2f64 VECREG:$rA), + (v2f64 VECREG:$rB)))]>; Added: llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h?rev=44596&view=auto ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h (added) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h Tue Dec 4 19:31:18 2007 @@ -0,0 +1,20 @@ +//==-- SPURegisterNames.h - Wrapper header for SPU register names -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation. +// +// See README.txt for details. +// +//===----------------------------------------------------------------------===// + +#if !defined(SPU_REGISTER_NAMES_H) + +// Define symbolic names for Cell registers. This defines a mapping from +// register name to register number. +// +#include "SPUGenRegisterNames.inc" + +#define SPU_REGISTER_NAMES_H 1 +#endif From scottm at aero.org Tue Dec 4 19:40:26 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 01:40:26 -0000 Subject: [llvm-commits] [llvm] r44597 - in /llvm/trunk: ./ lib/Target/CellSPU/ Message-ID: <200712050140.lB51eRnU009762@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 19:40:25 2007 New Revision: 44597 URL: http://llvm.org/viewvc/llvm-project?rev=44597&view=rev Log: Updated source file headers to llvm coding standard. Modified: llvm/trunk/LICENSE.TXT llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td llvm/trunk/lib/Target/CellSPU/Makefile llvm/trunk/lib/Target/CellSPU/SPU.h llvm/trunk/lib/Target/CellSPU/SPU.td llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h llvm/trunk/lib/Target/CellSPU/SPUNodes.td llvm/trunk/lib/Target/CellSPU/SPUOperands.td llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h llvm/trunk/lib/Target/CellSPU/SPUSchedule.td llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h Modified: llvm/trunk/LICENSE.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/LICENSE.TXT?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/LICENSE.TXT (original) +++ llvm/trunk/LICENSE.TXT Tue Dec 4 19:40:25 2007 @@ -67,5 +67,6 @@ llvm/projects/ModuleMaker/autoconf llvm/projects/sample/autoconf Boost C++ Libraries llvm/include : docs/BOOST_LICENSE_1_0.txt +CellSPU backend llvm/lib/Target/CellSPU/README.txt Modified: llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td (original) +++ llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. //===----------------------------------------------------------------------===// ///--==-- Arithmetic ops intrinsics --==-- Modified: llvm/trunk/lib/Target/CellSPU/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/Makefile?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/Makefile (original) +++ llvm/trunk/lib/Target/CellSPU/Makefile Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ # The LLVM Compiler Infrastructure # # This file was developed by a team from the Computer Systems Research -# Department at The Aerospace Corporation. -# -# See README.txt for details. +# Department at The Aerospace Corporation and is distributed under the +# University of Illinois Open Source License. See LICENSE.TXT for details. ##===----------------------------------------------------------------------===## LEVEL = ../../.. LIBRARYNAME = LLVMCellSPU Modified: llvm/trunk/lib/Target/CellSPU/SPU.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPU.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPU.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPU.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPU.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPU.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPU.td Tue Dec 4 19:40:25 2007 @@ -2,11 +2,10 @@ // // The LLVM Compiler Infrastructure // -// // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // -// See README.txt for details. //===----------------------------------------------------------------------===// // // This is the top level entry point for the STI Cell SPU target machine. Modified: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUFrameInfo.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrBuilder.h Tue Dec 4 19:40:25 2007 @@ -2,6 +2,10 @@ // // The LLVM Compiler Infrastructure // +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// //===----------------------------------------------------------------------===// // // This file exposes functions that may be used with BuildMI from the Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrFormats.td Tue Dec 4 19:40:25 2007 @@ -2,7 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by The Aerospace Corporation.... +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h Tue Dec 4 19:40:25 2007 @@ -3,13 +3,12 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file contains the PowerPC implementation of the TargetInstrInfo class. +// This file contains the CellSPU implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Tue Dec 4 19:40:25 2007 @@ -2,7 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by The Aerospace Corporation. +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Cell SPU Instructions: Modified: llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Tue Dec 4 19:40:25 2007 @@ -1,9 +1,10 @@ //=- SPUNodes.h - Specialized SelectionDAG nodes used for CellSPU -*- C++ -*-=// // -// This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. +// The LLVM Compiler Infrastructure // -// See README.txt for details. +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. //===----------------------------------------------------------------------===// // // Type profiles and SelectionDAG nodes used by CellSPU Modified: llvm/trunk/lib/Target/CellSPU/SPUOperands.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUOperands.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUOperands.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUOperands.td Tue Dec 4 19:40:25 2007 @@ -2,7 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by The Aerospace Corporation. +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Cell SPU Instruction Operands: Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h Tue Dec 4 19:40:25 2007 @@ -2,7 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by The Aerospace Corporation. +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td Tue Dec 4 19:40:25 2007 @@ -2,8 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by The Aerospace Corporation. No distribution rights -// yet determined... +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterNames.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/CellSPU/SPUSchedule.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUSchedule.td?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUSchedule.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUSchedule.td Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Modified: llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h?rev=44597&r1=44596&r2=44597&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h Tue Dec 4 19:40:25 2007 @@ -3,9 +3,8 @@ // The LLVM Compiler Infrastructure // // This file was developed by a team from the Computer Systems Research -// Department at The Aerospace Corporation. -// -// See README.txt for details. +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // From scottm at aero.org Tue Dec 4 20:01:41 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 02:01:41 -0000 Subject: [llvm-commits] [llvm] r44598 - in /llvm/trunk: autoconf/configure.ac include/llvm/Intrinsics.td include/llvm/IntrinsicsCellSPU.td lib/Target/CellSPU/README.txt Message-ID: <200712050201.lB521gui010821@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 20:01:41 2007 New Revision: 44598 URL: http://llvm.org/viewvc/llvm-project?rev=44598&view=rev Log: More stuff for CellSPU -- this should be enough to get an error-free compilation (no files missing). Test cases remain to be checked in. Added: llvm/trunk/include/llvm/IntrinsicsCellSPU.td Modified: llvm/trunk/autoconf/configure.ac llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/Target/CellSPU/README.txt Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=44598&r1=44597&r2=44598&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Tue Dec 4 20:01:41 2007 @@ -363,6 +363,7 @@ [Build specific host targets: all,host-only,{target-name} (default=all)]),, enableval=all) case "$enableval" in + # Note: Add "CellSPU" to all when fully functional. all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips" ;; host-only) case "$llvm_cv_target_arch" in @@ -374,6 +375,7 @@ IA64) TARGETS_TO_BUILD="IA64" ;; ARM) TARGETS_TO_BUILD="ARM" ;; Mips) TARGETS_TO_BUILD="Mips" ;; + CellSPU|SPU) TARGETS_TO_BUILD="CellSPU" ;; *) AC_MSG_ERROR([Can not set target to build]) ;; esac ;; @@ -387,6 +389,7 @@ ia64) TARGETS_TO_BUILD="IA64 $TARGETS_TO_BUILD" ;; arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;; mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;; + spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;; *) AC_MSG_ERROR([Unrecognized target $a_target]) ;; esac done Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=44598&r1=44597&r2=44598&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Tue Dec 4 20:01:41 2007 @@ -274,3 +274,4 @@ include "llvm/IntrinsicsPowerPC.td" include "llvm/IntrinsicsX86.td" include "llvm/IntrinsicsARM.td" +include "llvm/IntrinsicsCellSPU.td" Added: llvm/trunk/include/llvm/IntrinsicsCellSPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsCellSPU.td?rev=44598&view=auto ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsCellSPU.td (added) +++ llvm/trunk/include/llvm/IntrinsicsCellSPU.td Tue Dec 4 20:01:41 2007 @@ -0,0 +1,230 @@ +//==- IntrinsicsCellSPU.td - Cell SDK intrinsics -*- tablegen -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by The Aerospace Corporation. +// +//===----------------------------------------------------------------------===// +// Cell SPU Instructions: +//===----------------------------------------------------------------------===// +// TODO Items (not urgent today, but would be nice, low priority) +// +// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by +// concatenating the byte argument b as "bbbb". Could recognize this bit pattern +// in 16-bit and 32-bit constants and reduce instruction count. +//===----------------------------------------------------------------------===// + +// 7-bit integer type, used as an immediate: +def cell_i7_ty: LLVMType; // Note: This was i8 +def cell_i8_ty: LLVMType; // Note: This was i8 + +class v16i8_u7imm : + GCCBuiltin, + Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, cell_i7_ty], + [IntrNoMem]>; + +class v16i8_u8imm : + GCCBuiltin, + Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v16i8_s10imm : + GCCBuiltin, + Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v16i8_u16imm : + GCCBuiltin, + Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v16i8_rr : + GCCBuiltin, + Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], + [IntrNoMem]>; + +class v8i16_s10imm : + GCCBuiltin, + Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v8i16_u16imm : + GCCBuiltin, + Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v8i16_rr : + GCCBuiltin, + Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + +class v4i32_rr : + GCCBuiltin, + Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], + [IntrNoMem]>; + +class v4i32_u7imm : + GCCBuiltin, + Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, cell_i7_ty], + [IntrNoMem]>; + +class v4i32_s10imm : + GCCBuiltin, + Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v4i32_u16imm : + GCCBuiltin, + Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_i16_ty], + [IntrNoMem]>; + +class v4f32_rr : + GCCBuiltin, + Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], + [IntrNoMem]>; + +class v4f32_rrr : + GCCBuiltin, + Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], + [IntrNoMem]>; + +class v2f64_rr : + GCCBuiltin, + Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], + [IntrNoMem]>; + +// All Cell SPU intrinsics start with "llvm.spu.". +let TargetPrefix = "spu" in { + def int_spu_si_fsmbi : v8i16_u16imm<"fsmbi">; + def int_spu_si_ah : v8i16_rr<"ah">; + def int_spu_si_ahi : v8i16_s10imm<"ahi">; + def int_spu_si_a : v4i32_rr<"a">; + def int_spu_si_ai : v4i32_s10imm<"ai">; + def int_spu_si_sfh : v8i16_rr<"sfh">; + def int_spu_si_sfhi : v8i16_s10imm<"sfhi">; + def int_spu_si_sf : v4i32_rr<"sf">; + def int_spu_si_sfi : v4i32_s10imm<"sfi">; + def int_spu_si_addx : v4i32_rr<"addx">; + def int_spu_si_cg : v4i32_rr<"cg">; + def int_spu_si_cgx : v4i32_rr<"cgx">; + def int_spu_si_sfx : v4i32_rr<"sfx">; + def int_spu_si_bg : v4i32_rr<"bg">; + def int_spu_si_bgx : v4i32_rr<"bgx">; + def int_spu_si_mpy : // This is special: + GCCBuiltin<"__builtin_si_mpy">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyu : // This is special: + GCCBuiltin<"__builtin_si_mpyu">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyi : // This is special: + GCCBuiltin<"__builtin_si_mpyi">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyui : // This is special: + GCCBuiltin<"__builtin_si_mpyui">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_i16_ty], + [IntrNoMem]>; + def int_spu_si_mpya : // This is special: + GCCBuiltin<"__builtin_si_mpya">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyh : // This is special: + GCCBuiltin<"__builtin_si_mpyh">, + Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpys : // This is special: + GCCBuiltin<"__builtin_si_mpys">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyhh : // This is special: + GCCBuiltin<"__builtin_si_mpyhh">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyhha : // This is special: + GCCBuiltin<"__builtin_si_mpyhha">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyhhu : // This is special: + GCCBuiltin<"__builtin_si_mpyhhu">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + def int_spu_si_mpyhhau : // This is special: + GCCBuiltin<"__builtin_si_mpyhhau">, + Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], + [IntrNoMem]>; + + def int_spu_si_shli: v4i32_u7imm<"shli">; + def int_spu_si_shlqbi: v16i8_rr<"shlqbi">; + def int_spu_si_shlqbii: v16i8_u7imm<"shlqbii">; + def int_spu_si_shlqby: v16i8_rr<"shlqby">; + def int_spu_si_shlqbyi: v16i8_u7imm<"shlqbyi">; + + def int_spu_si_ceq: v4i32_rr<"ceq">; + def int_spu_si_ceqi: v4i32_s10imm<"ceqi">; + def int_spu_si_ceqb: v16i8_rr<"ceqb">; + def int_spu_si_ceqbi: v16i8_u8imm<"ceqbi">; + def int_spu_si_ceqh: v8i16_rr<"ceqh">; + def int_spu_si_ceqhi: v8i16_s10imm<"ceqhi">; + def int_spu_si_cgt: v4i32_rr<"cgt">; + def int_spu_si_cgti: v4i32_s10imm<"cgti">; + def int_spu_si_cgtb: v16i8_rr<"cgtb">; + def int_spu_si_cgtbi: v16i8_u8imm<"cgtbi">; + def int_spu_si_cgth: v8i16_rr<"cgth">; + def int_spu_si_cgthi: v8i16_s10imm<"cgthi">; + def int_spu_si_clgtb: v16i8_rr<"clgtb">; + def int_spu_si_clgtbi: v16i8_u8imm<"clgtbi">; + def int_spu_si_clgth: v8i16_rr<"clgth">; + def int_spu_si_clgthi: v8i16_s10imm<"clgthi">; + def int_spu_si_clgt: v4i32_rr<"clgt">; + def int_spu_si_clgti: v4i32_s10imm<"clgti">; + + def int_spu_si_and: v4i32_rr<"and">; + def int_spu_si_andbi: v16i8_u8imm<"andbi">; + def int_spu_si_andc: v4i32_rr<"andc">; + def int_spu_si_andhi: v8i16_s10imm<"andhi">; + def int_spu_si_andi: v4i32_s10imm<"andi">; + + def int_spu_si_or: v4i32_rr<"or">; + def int_spu_si_orbi: v16i8_u8imm<"orbi">; + def int_spu_si_orc: v4i32_rr<"orc">; + def int_spu_si_orhi: v8i16_s10imm<"orhi">; + def int_spu_si_ori: v4i32_s10imm<"ori">; + + def int_spu_si_xor: v4i32_rr<"xor">; + def int_spu_si_xorbi: v16i8_u8imm<"xorbi">; + def int_spu_si_xorhi: v8i16_s10imm<"xorhi">; + def int_spu_si_xori: v4i32_s10imm<"xori">; + + def int_spu_si_nor: v4i32_rr<"nor">; + def int_spu_si_nand: v4i32_rr<"nand">; + + def int_spu_si_fa: v4f32_rr<"fa">; + def int_spu_si_fs: v4f32_rr<"fs">; + def int_spu_si_fm: v4f32_rr<"fm">; + + def int_spu_si_fceq: v4f32_rr<"fceq">; + def int_spu_si_fcmeq: v4f32_rr<"fcmeq">; + def int_spu_si_fcgt: v4f32_rr<"fcgt">; + def int_spu_si_fcmgt: v4f32_rr<"fcmgt">; + + def int_spu_si_fma: v4f32_rrr<"fma">; + def int_spu_si_fnms: v4f32_rrr<"fnms">; + def int_spu_si_fms: v4f32_rrr<"fms">; + + def int_spu_si_dfa: v2f64_rr<"dfa">; + def int_spu_si_dfs: v2f64_rr<"dfs">; + def int_spu_si_dfm: v2f64_rr<"dfm">; + +//def int_spu_si_dfceq: v2f64_rr<"dfceq">; +//def int_spu_si_dfcmeq: v2f64_rr<"dfcmeq">; +//def int_spu_si_dfcgt: v2f64_rr<"dfcgt">; +//def int_spu_si_dfcmgt: v2f64_rr<"dfcmgt">; + + def int_spu_si_dfnma: v2f64_rr<"dfnma">; + def int_spu_si_dfma: v2f64_rr<"dfma">; + def int_spu_si_dfnms: v2f64_rr<"dfnms">; + def int_spu_si_dfms: v2f64_rr<"dfms">; + +} Modified: llvm/trunk/lib/Target/CellSPU/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/README.txt?rev=44598&r1=44597&r2=44598&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/README.txt (original) +++ llvm/trunk/lib/Target/CellSPU/README.txt Tue Dec 4 20:01:41 2007 @@ -21,7 +21,16 @@ SUCH DAMAGES ARE FORESEEABLE. --------------------------------------------------------------------------- +--WARNING--: --WARNING--: The CellSPU work is work-in-progress and "alpha" quality code. +--WARNING--: + +If you are brave enough to try this code or help to hack on it, be sure +to add 'spu' to configure's --enable-targets option, e.g.: + + ./configure \ + --enable-targets=x86,x86_64,powerpc,spu + --------------------------------------------------------------------------- TODO: From scottm at aero.org Tue Dec 4 20:08:02 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 02:08:02 -0000 Subject: [llvm-commits] [llvm] r44599 - /llvm/trunk/include/llvm/IntrinsicsCellSPU.td Message-ID: <200712050208.lB5282q8011142@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 4 20:08:01 2007 New Revision: 44599 URL: http://llvm.org/viewvc/llvm-project?rev=44599&view=rev Log: fixed header attribution Modified: llvm/trunk/include/llvm/IntrinsicsCellSPU.td Modified: llvm/trunk/include/llvm/IntrinsicsCellSPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsCellSPU.td?rev=44599&r1=44598&r2=44599&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsCellSPU.td (original) +++ llvm/trunk/include/llvm/IntrinsicsCellSPU.td Tue Dec 4 20:08:01 2007 @@ -2,7 +2,9 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by The Aerospace Corporation. +// This file was developed by a team from the Computer Systems Research +// Department at The Aerospace Corporation and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // Cell SPU Instructions: From evan.cheng at apple.com Tue Dec 4 21:14:34 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 03:14:34 -0000 Subject: [llvm-commits] [llvm] r44600 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ Message-ID: <200712050314.lB53EYkS014542@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 4 21:14:33 2007 New Revision: 44600 URL: http://llvm.org/viewvc/llvm-project?rev=44600&view=rev Log: Add a argument to storeRegToStackSlot and storeRegToAddr to specify whether the stored register is killed. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/include/llvm/Target/MRegisterInfo.h llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp llvm/trunk/lib/CodeGen/RegAllocLocal.cpp llvm/trunk/lib/CodeGen/RegAllocSimple.cpp llvm/trunk/lib/CodeGen/RegisterScavenging.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.h Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Tue Dec 4 21:14:33 2007 @@ -278,6 +278,9 @@ SmallVector &Ops, bool isSS, int Slot, unsigned Reg); + bool canFoldMemoryOperand(MachineInstr *MI, + SmallVector &Ops) const; + /// anyKillInMBBAfterIdx - Returns true if there is a kill of the specified /// VNInfo that's after the specified index but is within the basic block. bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI, @@ -304,7 +307,7 @@ /// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper functions /// for addIntervalsForSpills to rewrite uses / defs for the given live range. - void rewriteInstructionForSpills(const LiveInterval &li, bool TrySplit, + bool rewriteInstructionForSpills(const LiveInterval &li, bool TrySplit, unsigned id, unsigned index, unsigned end, MachineInstr *MI, MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot, bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete, Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/MRegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -493,10 +493,10 @@ virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const = 0; - virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const = 0; @@ -553,12 +553,12 @@ return 0; } - /// getOpcodeAfterMemoryFold - Returns the opcode of the would be new - /// instruction after load / store is folded into an instruction of the - /// specified opcode. It returns zero if the specified unfolding is not - /// possible. - virtual unsigned getOpcodeAfterMemoryFold(unsigned Opc, unsigned OpNum) const{ - return 0; + /// canFoldMemoryOperand - Returns true if the specified load / store is + /// folding is possible. + virtual + bool canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const{ + return false; } /// unfoldMemoryOperand - Separate a single instruction which folded a load or Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Tue Dec 4 21:14:33 2007 @@ -253,7 +253,7 @@ MBB->addLiveIn(CSI[i].getReg()); // Insert the spill to the stack frame. - RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), + RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), true, CSI[i].getFrameIdx(), CSI[i].getRegClass()); } } Modified: llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp Tue Dec 4 21:14:33 2007 @@ -329,7 +329,7 @@ const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DOUT << " to stack slot #" << FrameIndex; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIndex, RC); ++NumStores; // Update statistics } Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Tue Dec 4 21:14:33 2007 @@ -286,7 +286,7 @@ const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DOUT << " to stack slot #" << FrameIndex; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIndex, RC); ++NumStores; // Update statistics } Modified: llvm/trunk/lib/CodeGen/RegAllocSimple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocSimple.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocSimple.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocSimple.cpp Tue Dec 4 21:14:33 2007 @@ -156,7 +156,7 @@ // Add move instruction(s) ++NumStores; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIdx, RC); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIdx, RC); } Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Tue Dec 4 21:14:33 2007 @@ -282,7 +282,7 @@ RegInfo->eliminateFrameIndex(II, SPAdj, this); } - RegInfo->storeRegToStackSlot(*MBB, I, SReg, ScavengingFrameIndex, RC); + RegInfo->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC); MachineBasicBlock::iterator II = prior(I); RegInfo->eliminateFrameIndex(II, SPAdj, this); ScavengedReg = SReg; Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Tue Dec 4 21:14:33 2007 @@ -208,7 +208,8 @@ } if (MO.isDef()) { - MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); + MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, true, + StackSlot, RC); ++NumStores; } } @@ -861,7 +862,7 @@ BitVector &RegKills, std::vector &KillOps, VirtRegMap &VRM) { - MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); + MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC); DOUT << "Store:\t" << *next(MII); // If there is a dead store to this stack slot, nuke it now. @@ -984,9 +985,10 @@ const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); - MRI->storeRegToStackSlot(MBB, next(MII), Phys, StackSlot, RC); - DOUT << "Store:\t" << *next(MII); - VRM.virtFolded(VirtReg, next(MII), VirtRegMap::isMod); + MRI->storeRegToStackSlot(MBB, next(MII), Phys, false, StackSlot, RC); + MachineInstr *StoreMI = next(MII); + DOUT << "Store:\t" << StoreMI; + VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod); } NextMII = next(MII); } @@ -1011,12 +1013,6 @@ assert(MRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual or a physical register?"); - // Assumes this is the last use of a split interval. IsKill will be unset - // if reg is use later unless it's a two-address operand. - if (MO.isUse() && VRM.getPreSplitReg(VirtReg) && - TID->getOperandConstraint(i, TOI::TIED_TO) == -1) - MI.getOperand(i).setIsKill(); - unsigned SubIdx = MO.getSubReg(); if (VRM.isAssignedReg(VirtReg)) { // This virtual register was assigned a physreg! Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -158,31 +158,32 @@ void ARMRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, + unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC) const { if (RC == ARM::GPRRegisterClass) { MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); if (AFI->isThumbFunction()) - BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg, false, false, true) + BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addImm(0); else AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::STR)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addReg(0).addImm(0)); } else if (RC == ARM::DPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FSTD)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addImm(0)); } else { assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FSTS)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addImm(0)); } } void ARMRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -192,7 +193,7 @@ if (AFI->isThumbFunction()) { Opc = Addr[0].isFrameIndex() ? ARM::tSpill : ARM::tSTR; MachineInstrBuilder MIB = - BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) MIB = ARMInstrAddOperand(MIB, Addr[i]); NewMIs.push_back(MIB); @@ -207,7 +208,7 @@ } MachineInstrBuilder MIB = - BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) MIB = ARMInstrAddOperand(MIB, Addr[i]); AddDefaultPred(MIB); @@ -426,6 +427,39 @@ return NewMI; } +bool ARMRegisterInfo::canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const { + if (Ops.size() != 1) return NULL; + + unsigned OpNum = Ops[0]; + unsigned Opc = MI->getOpcode(); + switch (Opc) { + default: break; + case ARM::MOVr: + // If it is updating CPSR, then it cannot be foled. + return MI->getOperand(4).getReg() != ARM::CPSR; + case ARM::tMOVr: { + if (OpNum == 0) { // move -> store + unsigned SrcReg = MI->getOperand(1).getReg(); + if (isPhysicalRegister(SrcReg) && !isLowRegister(SrcReg)) + // tSpill cannot take a high register operand. + return false; + } else { // move -> load + unsigned DstReg = MI->getOperand(0).getReg(); + if (isPhysicalRegister(DstReg) && !isLowRegister(DstReg)) + // tRestore cannot target a high register operand. + return false; + } + return true; + } + case ARM::FCPYS: + case ARM::FCPYD: + return true; + } + + return false; +} + const unsigned* ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { static const unsigned CalleeSavedRegs[] = { Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -48,10 +48,10 @@ void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; @@ -84,6 +84,9 @@ return 0; } + bool canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const; + const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const; const TargetRegisterClass* const* Modified: llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -61,28 +61,29 @@ void AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, - const TargetRegisterClass *RC) const { + unsigned SrcReg, bool isKill, int FrameIdx, + const TargetRegisterClass *RC) const { //cerr << "Trying to store " << getPrettyName(SrcReg) << " to " // << FrameIdx << "\n"; //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); if (RC == Alpha::F4RCRegisterClass) BuildMI(MBB, MI, TII.get(Alpha::STS)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else if (RC == Alpha::F8RCRegisterClass) BuildMI(MBB, MI, TII.get(Alpha::STT)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else if (RC == Alpha::GPRCRegisterClass) BuildMI(MBB, MI, TII.get(Alpha::STQ)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else abort(); } void AlphaRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -96,7 +97,7 @@ else abort(); MachineInstrBuilder MIB = - BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) Modified: llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -30,10 +30,10 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -194,7 +194,7 @@ void SPURegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { MachineOpCode opc; @@ -227,10 +227,12 @@ abort(); } - addFrameReference(BuildMI(MBB, MI, TII.get(opc)).addReg(SrcReg), FrameIdx); + addFrameReference(BuildMI(MBB, MI, TII.get(opc)) + .addReg(SrcReg, false, false, isKill), FrameIdx); } void SPURegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -258,7 +260,7 @@ abort(); } MachineInstrBuilder MIB = BuildMI(TII.get(Opc)) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -44,11 +44,11 @@ //! Store a register to a stack slot, based on its register class. void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; //! Store a register to an address, based on its register class - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; Modified: llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -38,22 +38,23 @@ void IA64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, + int FrameIdx, const TargetRegisterClass *RC) const{ if (RC == IA64::FPRegisterClass) { BuildMI(MBB, MI, TII.get(IA64::STF_SPILL)).addFrameIndex(FrameIdx) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); } else if (RC == IA64::GRRegisterClass) { BuildMI(MBB, MI, TII.get(IA64::ST8)).addFrameIndex(FrameIdx) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); } else if (RC == IA64::PRRegisterClass) { /* we use IA64::r2 as a temporary register for doing this hackery. */ // first we load 0: BuildMI(MBB, MI, TII.get(IA64::MOV), IA64::r2).addReg(IA64::r0); // then conditionally add 1: BuildMI(MBB, MI, TII.get(IA64::CADDIMM22), IA64::r2).addReg(IA64::r2) - .addImm(1).addReg(SrcReg, false, false, true); + .addImm(1).addReg(SrcReg, false, false, isKill); // and then store it to the stack BuildMI(MBB, MI, TII.get(IA64::ST8)).addFrameIndex(FrameIdx).addReg(IA64::r2); } else assert(0 && @@ -61,6 +62,7 @@ } void IA64RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -86,7 +88,7 @@ else MIB.addFrameIndex(MO.getFrameIndex()); } - MIB.addReg(SrcReg, false, false, true); + MIB.addReg(SrcReg, false, false, isKill); NewMIs.push_back(MIB); return; Modified: llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h (original) +++ llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -31,10 +31,10 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -85,24 +85,25 @@ void MipsRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, + unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC) const { if (RC == Mips::CPURegsRegisterClass) - BuildMI(MBB, I, TII.get(Mips::SW)).addReg(SrcReg, false, false, true) + BuildMI(MBB, I, TII.get(Mips::SW)).addReg(SrcReg, false, false, isKill) .addImm(0).addFrameIndex(FI); else assert(0 && "Can't store this register to stack slot"); } void MipsRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { if (RC != Mips::CPURegsRegisterClass) assert(0 && "Can't store this register"); MachineInstrBuilder MIB = BuildMI(TII.get(Mips::SW)) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -34,10 +34,10 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -104,39 +104,39 @@ } static void StoreRegToStackSlot(const TargetInstrInfo &TII, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) { if (RC == PPC::GPRCRegisterClass) { if (SrcReg != PPC::LR) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else { // FIXME: this spills LR immediately to memory in one step. To do this, // we use R11, which we know cannot be used in the prolog/epilog. This is // a hack. NewMIs.push_back(BuildMI(TII.get(PPC::MFLR), PPC::R11)); NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) - .addReg(PPC::R11, false, false, true), FrameIdx)); + .addReg(PPC::R11, false, false, isKill), FrameIdx)); } } else if (RC == PPC::G8RCRegisterClass) { if (SrcReg != PPC::LR8) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STD)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else { // FIXME: this spills LR immediately to memory in one step. To do this, // we use R11, which we know cannot be used in the prolog/epilog. This is // a hack. NewMIs.push_back(BuildMI(TII.get(PPC::MFLR8), PPC::X11)); NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STD)) - .addReg(PPC::X11, false, false, true), FrameIdx)); + .addReg(PPC::X11, false, false, isKill), FrameIdx)); } } else if (RC == PPC::F8RCRegisterClass) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STFD)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else if (RC == PPC::F4RCRegisterClass) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STFS)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else if (RC == PPC::CRRCRegisterClass) { // FIXME: We use R0 here, because it isn't available for RA. // We need to store the CR in the low 4-bits of the saved value. First, @@ -153,7 +153,7 @@ } NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) - .addReg(PPC::R0, false, false, true), FrameIdx)); + .addReg(PPC::R0, false, false, isKill), FrameIdx)); } else if (RC == PPC::VRRCRegisterClass) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# @@ -163,7 +163,7 @@ NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::ADDI), PPC::R0), FrameIdx, 0, 0)); NewMIs.push_back(BuildMI(TII.get(PPC::STVX)) - .addReg(SrcReg, false, false, true).addReg(PPC::R0).addReg(PPC::R0)); + .addReg(SrcReg, false, false, isKill).addReg(PPC::R0).addReg(PPC::R0)); } else { assert(0 && "Unknown regclass!"); abort(); @@ -173,20 +173,22 @@ void PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { SmallVector NewMIs; - StoreRegToStackSlot(TII, SrcReg, FrameIdx, RC, NewMIs); + StoreRegToStackSlot(TII, SrcReg, isKill, FrameIdx, RC, NewMIs); for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) MBB.insert(MI, NewMIs[i]); } void PPCRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { if (Addr[0].isFrameIndex()) { - StoreRegToStackSlot(TII, SrcReg, Addr[0].getFrameIndex(), RC, NewMIs); + StoreRegToStackSlot(TII, SrcReg, isKill, Addr[0].getFrameIndex(), RC, + NewMIs); return; } @@ -206,7 +208,7 @@ abort(); } MachineInstrBuilder MIB = BuildMI(TII.get(Opc)) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -37,10 +37,10 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -32,23 +32,24 @@ void SparcRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, + unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC) const { // On the order of operands here: think "[FrameIdx + 0] = SrcReg". if (RC == SP::IntRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::STri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); else if (RC == SP::FPRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::STFri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); else if (RC == SP::DFPRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::STDFri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); else assert(0 && "Can't store this register to stack slot"); } void SparcRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -71,7 +72,7 @@ else MIB.addFrameIndex(MO.getFrameIndex()); } - MIB.addReg(SrcReg, false, false, true); + MIB.addReg(SrcReg, false, false, isKill); NewMIs.push_back(MIB); return; } Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -32,10 +32,10 @@ /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Tue Dec 4 21:14:33 2007 @@ -834,14 +834,15 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { unsigned Opc = getStoreRegOpcode(RC, StackAlign); addFrameReference(BuildMI(MBB, MI, TII.get(Opc)), FrameIdx) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); } void X86RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -849,7 +850,7 @@ MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); for (unsigned i = 0, e = Addr.size(); i != e; ++i) MIB = X86InstrAddOperand(MIB, Addr[i]); - MIB.addReg(SrcReg, false, false, true); + MIB.addReg(SrcReg, false, false, isKill); NewMIs.push_back(MIB); } @@ -1195,11 +1196,27 @@ } -unsigned X86RegisterInfo::getOpcodeAfterMemoryFold(unsigned Opc, - unsigned OpNum) const { +bool X86RegisterInfo::canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const { // Check switch flag if (NoFusing) return 0; - const DenseMap *OpcodeTablePtr = NULL; + + if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { + switch (MI->getOpcode()) { + default: return false; + case X86::TEST8rr: + case X86::TEST16rr: + case X86::TEST32rr: + case X86::TEST64rr: + return true; + } + } + + if (Ops.size() != 1) + return false; + + unsigned OpNum = Ops[0]; + unsigned Opc = MI->getOpcode(); unsigned NumOps = TII.getNumOperands(Opc); bool isTwoAddr = NumOps > 1 && TII.getOperandConstraint(Opc, 1, TOI::TIED_TO) != -1; @@ -1207,18 +1224,16 @@ // Folding a memory location into the two-address part of a two-address // instruction is different than folding it other places. It requires // replacing the *two* registers with the memory location. + const DenseMap *OpcodeTablePtr = NULL; if (isTwoAddr && NumOps >= 2 && OpNum < 2) { OpcodeTablePtr = &RegOp2MemOpTable2Addr; } else if (OpNum == 0) { // If operand 0 switch (Opc) { case X86::MOV16r0: - return X86::MOV16mi; case X86::MOV32r0: - return X86::MOV32mi; case X86::MOV64r0: - return X86::MOV64mi32; case X86::MOV8r0: - return X86::MOV8mi; + return true; default: break; } OpcodeTablePtr = &RegOp2MemOpTable0; @@ -1233,9 +1248,9 @@ DenseMap::iterator I = OpcodeTablePtr->find((unsigned*)Opc); if (I != OpcodeTablePtr->end()) - return I->second; + return true; } - return 0; + return false; } bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, @@ -1335,7 +1350,7 @@ const TargetOperandInfo &DstTOI = TID.OpInfo[0]; const TargetRegisterClass *DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS) ? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass); - storeRegToAddr(MF, Reg, AddrOps, DstRC, NewMIs); + storeRegToAddr(MF, Reg, true, AddrOps, DstRC, NewMIs); } return true; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=44600&r1=44599&r2=44600&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Tue Dec 4 21:14:33 2007 @@ -101,10 +101,10 @@ void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; @@ -148,11 +148,9 @@ SmallVectorImpl &Ops, MachineInstr* LoadMI) const; - /// getOpcodeAfterMemoryFold - Returns the opcode of the would be new - /// instruction after load / store is folded into an instruction of the - /// specified opcode. It returns zero if the specified unfolding is not - /// possible. - unsigned getOpcodeAfterMemoryFold(unsigned Opc, unsigned OpNum) const; + /// canFoldMemoryOperand - Returns true if the specified load / store is + /// folding is possible. + bool canFoldMemoryOperand(MachineInstr*, SmallVectorImpl &) const; /// unfoldMemoryOperand - Separate a single instruction which folded a load or /// a store or a load and a store into two or more instruction. If this is From evan.cheng at apple.com Tue Dec 4 21:22:34 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 03:22:34 -0000 Subject: [llvm-commits] [llvm] r44601 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/VirtRegMap.cpp Message-ID: <200712050322.lB53MYmP014953@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 4 21:22:34 2007 New Revision: 44601 URL: http://llvm.org/viewvc/llvm-project?rev=44601&view=rev Log: - Mark last use of a split interval as kill instead of letting spiller track it. This allows an important optimization to be re-enabled. - If all uses / defs of a split interval can be folded, give the interval a low spill weight so it would not be picked in case spilling is needed (avoid pushing other intervals in the same BB to be spilled). Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=44601&r1=44600&r2=44601&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Tue Dec 4 21:22:34 2007 @@ -278,6 +278,8 @@ SmallVector &Ops, bool isSS, int Slot, unsigned Reg); + /// canFoldMemoryOperand - Returns true if the specified load / store + /// folding is possible. bool canFoldMemoryOperand(MachineInstr *MI, SmallVector &Ops) const; Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44601&r1=44600&r2=44601&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Tue Dec 4 21:22:34 2007 @@ -691,6 +691,22 @@ return false; } +/// canFoldMemoryOperand - Returns true if the specified load / store +/// folding is possible. +bool LiveIntervals::canFoldMemoryOperand(MachineInstr *MI, + SmallVector &Ops) const { + SmallVector FoldOps; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + unsigned OpIdx = Ops[i]; + // FIXME: fold subreg use. + if (MI->getOperand(OpIdx).getSubReg()) + return false; + FoldOps.push_back(OpIdx); + } + + return mri_->canFoldMemoryOperand(MI, FoldOps); +} + bool LiveIntervals::intervalIsInOneMBB(const LiveInterval &li) const { SmallPtrSet MBBs; for (LiveInterval::Ranges::const_iterator @@ -710,7 +726,7 @@ /// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper functions /// for addIntervalsForSpills to rewrite uses / defs for the given live range. -void LiveIntervals:: +bool LiveIntervals:: rewriteInstructionForSpills(const LiveInterval &li, bool TrySplit, unsigned id, unsigned index, unsigned end, MachineInstr *MI, MachineInstr *ReMatOrigDefMI, MachineInstr *ReMatDefMI, @@ -723,6 +739,7 @@ const LoopInfo *loopInfo, std::map &MBBVRegsMap, std::vector &NewLIs) { + bool CanFold = false; RestartInstruction: for (unsigned i = 0; i != MI->getNumOperands(); ++i) { MachineOperand& mop = MI->getOperand(i); @@ -760,11 +777,6 @@ } } - // Do not fold load / store here if we are splitting. We'll find an - // optimal point to insert a load / store later. - if (TryFold) - TryFold = !TrySplit && NewVReg == 0; - // Scan all of the operands of this instruction rewriting operands // to use NewVReg instead of li.reg as appropriate. We do this for // two reasons: @@ -795,15 +807,23 @@ } } - if (TryFold && - tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index, - Ops, FoldSS, FoldSlot, Reg)) { - // Folding the load/store can completely change the instruction in - // unpredictable ways, rescan it from the beginning. - HasUse = false; - HasDef = false; - goto RestartInstruction; - } + if (TryFold) { + // Do not fold load / store here if we are splitting. We'll find an + // optimal point to insert a load / store later. + if (!TrySplit) { + if (tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index, + Ops, FoldSS, FoldSlot, Reg)) { + // Folding the load/store can completely change the instruction in + // unpredictable ways, rescan it from the beginning. + HasUse = false; + HasDef = false; + CanFold = false; + goto RestartInstruction; + } + } else { + CanFold = canFoldMemoryOperand(MI, Ops); + } + } else CanFold = false; // Create a new virtual register for the spill interval. bool CreatedNewVReg = false; @@ -879,8 +899,8 @@ nI.print(DOUT, mri_); DOUT << '\n'; } + return CanFold; } - bool LiveIntervals::anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI, MachineBasicBlock *MBB, unsigned Idx) const { @@ -920,6 +940,7 @@ std::map > &RestoreIdxes, std::map &MBBVRegsMap, std::vector &NewLIs) { + bool AllCanFold = true; unsigned NewVReg = 0; unsigned index = getBaseIndex(I->start); unsigned end = getBaseIndex(I->end-1) + InstrSlots::NUM; @@ -931,12 +952,12 @@ MachineInstr *MI = getInstructionFromIndex(index); MachineBasicBlock *MBB = MI->getParent(); - NewVReg = 0; + unsigned ThisVReg = 0; if (TrySplit) { std::map::const_iterator NVI = MBBVRegsMap.find(MBB->getNumber()); if (NVI != MBBVRegsMap.end()) { - NewVReg = NVI->second; + ThisVReg = NVI->second; // One common case: // x = use // ... @@ -959,21 +980,35 @@ } if (MIHasDef && !MIHasUse) { MBBVRegsMap.erase(MBB->getNumber()); - NewVReg = 0; + ThisVReg = 0; } } } - bool IsNew = NewVReg == 0; + + bool IsNew = ThisVReg == 0; + if (IsNew) { + // This ends the previous live interval. If all of its def / use + // can be folded, give it a low spill weight. + if (NewVReg && TrySplit && AllCanFold) { + LiveInterval &nI = getOrCreateInterval(NewVReg); + nI.weight /= 10.0F; + } + AllCanFold = true; + } + NewVReg = ThisVReg; + bool HasDef = false; bool HasUse = false; - rewriteInstructionForSpills(li, TrySplit, I->valno->id, index, end, - MI, ReMatOrigDefMI, ReMatDefMI, Slot, LdSlot, - isLoad, isLoadSS, DefIsReMat, CanDelete, vrm, - RegMap, rc, ReMatIds, NewVReg, HasDef, HasUse, - loopInfo, MBBVRegsMap, NewLIs); + bool CanFold = rewriteInstructionForSpills(li, TrySplit, I->valno->id, + index, end, MI, ReMatOrigDefMI, ReMatDefMI, + Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, + CanDelete, vrm, RegMap, rc, ReMatIds, NewVReg, + HasDef, HasUse, loopInfo, MBBVRegsMap, NewLIs); if (!HasDef && !HasUse) continue; + AllCanFold &= CanFold; + // Update weight of spill interval. LiveInterval &nI = getOrCreateInterval(NewVReg); if (!TrySplit) { @@ -1058,6 +1093,12 @@ unsigned loopDepth = loopInfo->getLoopDepth(MBB->getBasicBlock()); nI.weight += getSpillWeight(HasDef, HasUse, loopDepth); } + + if (NewVReg && TrySplit && AllCanFold) { + // If all of its def / use can be folded, give it a low spill weight. + LiveInterval &nI = getOrCreateInterval(NewVReg); + nI.weight /= 10.0F; + } } bool LiveIntervals::alsoFoldARestore(int Id, int index, unsigned vr, @@ -1331,8 +1372,14 @@ // load / rematerialization for us. if (Folded) nI.removeRange(getLoadIndex(index), getUseIndex(index)+1); - else + else { vrm.addRestorePoint(VReg, MI); + LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; + MachineInstr *LastUse = getInstructionFromIndex(getBaseIndex(LR->end)); + int UseIdx = LastUse->findRegisterUseOperandIdx(VReg); + assert(UseIdx != -1); + LastUse->getOperand(UseIdx).setIsKill(); + } } Id = RestoreMBBs.find_next(Id); } Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44601&r1=44600&r2=44601&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Tue Dec 4 21:22:34 2007 @@ -1295,8 +1295,6 @@ // the value and there isn't an earlier def that has already clobbered the // physreg. if (PhysReg && - Spills.canClobberPhysReg(SS) && - !ReusedOperands.isClobbered(PhysReg) && DeadStore->findRegisterUseOperandIdx(PhysReg, true) != -1 && MRI->unfoldMemoryOperand(MF, &MI, PhysReg, false, true, NewMIs)) { MBB.insert(MII, NewMIs[0]); From evan.cheng at apple.com Tue Dec 4 21:29:15 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 4 Dec 2007 19:29:15 -0800 Subject: [llvm-commits] [llvm] r44595 - in /llvm/trunk/lib/Target/CellSPU: SPUMachineFunction.h SPUNodes.td SPUOperands.td SPURegisterInfo.cpp SPURegisterInfo.h SPURegisterInfo.td SPUSchedule.td SPUSubtarget.cpp SPUSubtarget.h SPUTargetAsmInfo.cpp SPUTargetAsmInfo.h SPUTargetMachine.cpp SPUTargetMachine.h In-Reply-To: <200712050124.lB51O73h009068@zion.cs.uiuc.edu> References: <200712050124.lB51O73h009068@zion.cs.uiuc.edu> Message-ID: That's a lot of code. :-) On Dec 4, 2007, at 5:24 PM, Scott Michel wrote: > Author: pingbak > Date: Tue Dec 4 19:24:05 2007 > New Revision: 44595 > > URL: http://llvm.org/viewvc/llvm-project?rev=44595&view=rev > Log: > Main CellSPU backend files checked in. Intrinsics and autoconf files > remain. > > Added: > llvm/trunk/lib/Target/CellSPU/SPUMachineFunction.h > llvm/trunk/lib/Target/CellSPU/SPUNodes.td > llvm/trunk/lib/Target/CellSPU/SPUOperands.td > llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp > llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h > llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.td > llvm/trunk/lib/Target/CellSPU/SPUSchedule.td > llvm/trunk/lib/Target/CellSPU/SPUSubtarget.cpp > llvm/trunk/lib/Target/CellSPU/SPUSubtarget.h > llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.cpp > llvm/trunk/lib/Target/CellSPU/SPUTargetAsmInfo.h > llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.cpp > llvm/trunk/lib/Target/CellSPU/SPUTargetMachine.h > > ... > +/// getRegisterNumbering - Given the enum value for some register, > e.g. > +/// PPC::F14, return the number that it corresponds to (e.g. 14). > +unsigned SPURegisterInfo::getRegisterNumbering(unsigned RegEnum) { > + using namespace SPU; > + switch (RegEnum) { > + case SPU::R0: return 0; > + case SPU::R1: return 1; > + case SPU::R2: return 2; > + case SPU::R3: return 3; > + case SPU::R4: return 4; > + case SPU::R5: return 5; > + case SPU::R6: return 6; > + case SPU::R7: return 7; > + case SPU::R8: return 8; > + case SPU::R9: return 9; > > + case SPU::R125: return 125; > + case SPU::R126: return 126; > + case SPU::R127: return 127; > + default: > + std::cerr << "Unhandled reg in > SPURegisterInfo::getRegisterNumbering!\n"; > + abort(); > + } > +} > + This doesn't seem to be used / needed? Evan From isanbard at gmail.com Wed Dec 5 00:05:26 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 4 Dec 2007 22:05:26 -0800 Subject: [llvm-commits] [llvm] r44487 - in /llvm/trunk: include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp lib/Analysis/AliasAnalysisCounter.cpp lib/Analysis/AliasSetTracker.cpp lib/Analysis/BasicAliasAnalysis.cpp lib/Analysis/IPA/Global Message-ID: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> Hi Duncan, This patch seems to be causing a bootstrap failure on my system. I try to compile llvm-gcc-4.2 and it gives me errors like this during stage2 of the bootstrapping build: /Users/admin/LLVM/llvm-gcc-4.2.obj/./gcc/xgcc -B/Users/admin/LLVM/llvm-gcc-4.2.obj/./gcc/ -B/Users/admin/LLVM/llvm-gcc-4.2.install/i386-apple-darwin9.1.0/bin/ -B/Users/admin/LLVM/llvm-gcc-4.2.install/i386-apple-darwin9.1.0/lib/ -isystem /Users/admin/LLVM/llvm-gcc-4.2.install/i386-apple-darwin9.1.0/include -isystem /Users/admin/LLVM/llvm-gcc-4.2.install/i386-apple-darwin9.1.0/sys-include -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -I. -I. -I../../llvm-gcc-4.2.src/gcc -I../../llvm-gcc-4.2.src/gcc/. -I../../llvm-gcc-4.2.src/gcc/../include -I./../intl -I../../llvm-gcc-4.2.src/gcc/../libcpp/include -I../../llvm-gcc-4.2.src/gcc/../libdecnumber -I../libdecnumber -I/Users/admin/LLVM/llvm.src/include -I/Users/admin/LLVM/llvm.obj/include -mlongcall \ -fno-tree-dominator-opts \ \ -c ../../llvm-gcc-4.2.src/gcc/config/darwin-crt3.c -o crt3.o :0: internal compiler error: in tree_low_cst, at tree.c:4646 Please submit a full bug report, with preprocessed source if appropriate. See for instructions. make[5]: *** [crt3.o] Error 1 make[4]: *** [extra] Error 2 make[3]: *** [stmp-multilib] Error 2 make[3]: *** Waiting for unfinished jobs.... rm gcov.pod gpl.pod fsf-funding.pod gfdl.pod cpp.pod gcc.pod make[2]: *** [all-stage2-gcc] Error 2 make[1]: *** [stage2-bubble] Error 2 make: *** [all] Error 2 I did a binary search and it landed at this patch. I know that this is scant information, but is there anything about this patch that you think could cause a miscompilation? (I'm compiling this on an x86 iMac running Leopard.) Thanks! -bw On Nov 30, 2007 11:51 PM, Duncan Sands wrote: > Author: baldrick > Date: Sat Dec 1 01:51:45 2007 > New Revision: 44487 > > URL: http://llvm.org/viewvc/llvm-project?rev=44487&view=rev > Log: > Integrate the readonly/readnone logic more deeply > into alias analysis. This meant updating the API > which now has versions of the getModRefBehavior, > doesNotAccessMemory and onlyReadsMemory methods > which take a callsite parameter. These should be > used unless the callsite is not known, since in > general they can do a better job than the versions > that take a function. Also, users should no longer > call the version of getModRefBehavior that takes > both a function and a callsite. To reduce the > chance of misuse it is now protected. > > Modified: > llvm/trunk/include/llvm/Analysis/AliasAnalysis.h > llvm/trunk/lib/Analysis/AliasAnalysis.cpp > llvm/trunk/lib/Analysis/AliasAnalysisCounter.cpp > llvm/trunk/lib/Analysis/AliasSetTracker.cpp > llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp > llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp > llvm/trunk/lib/Analysis/LoadValueNumbering.cpp > llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp > llvm/trunk/lib/Transforms/Scalar/ADCE.cpp > llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > llvm/trunk/lib/Transforms/Scalar/GVN.cpp > llvm/trunk/lib/Transforms/Scalar/LICM.cpp > > Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original) > +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Sat Dec 1 01:51:45 2007 > @@ -186,40 +186,57 @@ > }; > }; > > - /// getModRefBehavior - Return the behavior of the specified function if > - /// called from the specified call site. The call site may be null in which > - /// case the most generic behavior of this function should be returned. > - virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS, > - std::vector *Info = 0); > - > - /// doesNotAccessMemory - If the specified function is known to never read or > - /// write memory, return true. If the function only reads from known-constant > - /// memory, it is also legal to return true. Functions that unwind the stack > - /// are not legal for this predicate. > - /// > - /// Many optimizations (such as CSE and LICM) can be performed on calls to it, > - /// without worrying about aliasing properties, and many functions have this > - /// property (e.g. 'sin' and 'cos'). > + /// getModRefBehavior - Return the behavior when calling the given call site. > + ModRefBehavior getModRefBehavior(CallSite CS, > + std::vector *Info = 0); > + > + /// getModRefBehavior - Return the behavior when calling the given function. > + /// For use when the call site is not known. > + ModRefBehavior getModRefBehavior(Function *F, > + std::vector *Info = 0); > + > + /// doesNotAccessMemory - If the specified call is known to never read or > + /// write memory, return true. If the call only reads from known-constant > + /// memory, it is also legal to return true. Calls that unwind the stack > + /// are legal for this predicate. > + /// > + /// Many optimizations (such as CSE and LICM) can be performed on such calls > + /// without worrying about aliasing properties, and many calls have this > + /// property (e.g. calls to 'sin' and 'cos'). > /// > /// This property corresponds to the GCC 'const' attribute. > /// > + bool doesNotAccessMemory(CallSite CS) { > + return getModRefBehavior(CS) == DoesNotAccessMemory; > + } > + > + /// doesNotAccessMemory - If the specified function is known to never read or > + /// write memory, return true. For use when the call site is not known. > + /// > bool doesNotAccessMemory(Function *F) { > - return getModRefBehavior(F, CallSite()) == DoesNotAccessMemory; > + return getModRefBehavior(F) == DoesNotAccessMemory; > } > > - /// onlyReadsMemory - If the specified function is known to only read from > - /// non-volatile memory (or not access memory at all), return true. Functions > - /// that unwind the stack are not legal for this predicate. > + /// onlyReadsMemory - If the specified call is known to only read from > + /// non-volatile memory (or not access memory at all), return true. Calls > + /// that unwind the stack are legal for this predicate. > /// > /// This property allows many common optimizations to be performed in the > /// absence of interfering store instructions, such as CSE of strlen calls. > /// > /// This property corresponds to the GCC 'pure' attribute. > /// > + bool onlyReadsMemory(CallSite CS) { > + ModRefBehavior MRB = getModRefBehavior(CS); > + return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory; > + } > + > + /// onlyReadsMemory - If the specified function is known to only read from > + /// non-volatile memory (or not access memory at all), return true. For use > + /// when the call site is not known. > + /// > bool onlyReadsMemory(Function *F) { > - /// FIXME: If the analysis returns more precise info, we can reduce it to > - /// this. > - ModRefBehavior MRB = getModRefBehavior(F, CallSite()); > + ModRefBehavior MRB = getModRefBehavior(F); > return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory; > } > > @@ -250,6 +267,14 @@ > /// > virtual bool hasNoModRefInfoForCalls() const; > > +protected: > + /// getModRefBehavior - Return the behavior of the specified function if > + /// called from the specified call site. The call site may be null in which > + /// case the most generic behavior of this function should be returned. > + virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS, > + std::vector *Info = 0); > + > +public: > /// Convenience functions... > ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size); > ModRefResult getModRefInfo(StoreInst *S, Value *P, unsigned Size); > > Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original) > +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Sat Dec 1 01:51:45 2007 > @@ -27,6 +27,7 @@ > #include "llvm/Analysis/AliasAnalysis.h" > #include "llvm/Pass.h" > #include "llvm/BasicBlock.h" > +#include "llvm/Function.h" > #include "llvm/Instructions.h" > #include "llvm/Type.h" > #include "llvm/Target/TargetData.h" > @@ -112,16 +113,40 @@ > return pointsToConstantMemory(P) ? NoModRef : Mod; > } > > +AliasAnalysis::ModRefBehavior > +AliasAnalysis::getModRefBehavior(CallSite CS, > + std::vector *Info) { > + if (CS.paramHasAttr(0, ParamAttr::ReadNone)) > + // Can't do better than this. > + return DoesNotAccessMemory; > + ModRefBehavior MRB = UnknownModRefBehavior; > + if (Function *F = CS.getCalledFunction()) > + MRB = getModRefBehavior(F, CS, Info); > + if (MRB != DoesNotAccessMemory && CS.paramHasAttr(0, ParamAttr::ReadOnly)) > + return OnlyReadsMemory; > + return MRB; > +} > + > +AliasAnalysis::ModRefBehavior > +AliasAnalysis::getModRefBehavior(Function *F, > + std::vector *Info) { > + if (F->paramHasAttr(0, ParamAttr::ReadNone)) > + // Can't do better than this. > + return DoesNotAccessMemory; > + ModRefBehavior MRB = getModRefBehavior(F, CallSite(), Info); > + if (MRB != DoesNotAccessMemory && F->paramHasAttr(0, ParamAttr::ReadOnly)) > + return OnlyReadsMemory; > + return MRB; > +} > + > AliasAnalysis::ModRefResult > AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { > ModRefResult Mask = ModRef; > - if (Function *F = CS.getCalledFunction()) { > - ModRefBehavior MRB = getModRefBehavior(F, CallSite()); > - if (MRB == OnlyReadsMemory) > - Mask = Ref; > - else if (MRB == DoesNotAccessMemory) > - return NoModRef; > - } > + ModRefBehavior MRB = getModRefBehavior(CS); > + if (MRB == OnlyReadsMemory) > + Mask = Ref; > + else if (MRB == DoesNotAccessMemory) > + return NoModRef; > > if (!AA) return Mask; > > > Modified: llvm/trunk/lib/Analysis/AliasAnalysisCounter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysisCounter.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/AliasAnalysisCounter.cpp (original) > +++ llvm/trunk/lib/Analysis/AliasAnalysisCounter.cpp Sat Dec 1 01:51:45 2007 > @@ -89,9 +89,15 @@ > bool pointsToConstantMemory(const Value *P) { > return getAnalysis().pointsToConstantMemory(P); > } > + bool doesNotAccessMemory(CallSite CS) { > + return getAnalysis().doesNotAccessMemory(CS); > + } > bool doesNotAccessMemory(Function *F) { > return getAnalysis().doesNotAccessMemory(F); > } > + bool onlyReadsMemory(CallSite CS) { > + return getAnalysis().onlyReadsMemory(CS); > + } > bool onlyReadsMemory(Function *F) { > return getAnalysis().onlyReadsMemory(F); > } > > Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/AliasSetTracker.cpp (original) > +++ llvm/trunk/lib/Analysis/AliasSetTracker.cpp Sat Dec 1 01:51:45 2007 > @@ -114,15 +114,13 @@ > void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) { > CallSites.push_back(CS); > > - if (Function *F = CS.getCalledFunction()) { > - AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(F, CS); > - if (Behavior == AliasAnalysis::DoesNotAccessMemory) > - return; > - else if (Behavior == AliasAnalysis::OnlyReadsMemory) { > - AliasTy = MayAlias; > - AccessTy |= Refs; > - return; > - } > + AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS); > + if (Behavior == AliasAnalysis::DoesNotAccessMemory) > + return; > + else if (Behavior == AliasAnalysis::OnlyReadsMemory) { > + AliasTy = MayAlias; > + AccessTy |= Refs; > + return; > } > > // FIXME: This should use mod/ref information to make this not suck so bad > @@ -166,9 +164,8 @@ > } > > bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { > - if (Function *F = CS.getCalledFunction()) > - if (AA.doesNotAccessMemory(F)) > - return false; > + if (AA.doesNotAccessMemory(CS)) > + return false; > > if (AA.hasNoModRefInfoForCalls()) > return true; > @@ -297,9 +294,8 @@ > > > bool AliasSetTracker::add(CallSite CS) { > - if (Function *F = CS.getCalledFunction()) > - if (AA.doesNotAccessMemory(F)) > - return true; // doesn't alias anything > + if (AA.doesNotAccessMemory(CS)) > + return true; // doesn't alias anything > > AliasSet *AS = findAliasSetForCallSite(CS); > if (!AS) { > @@ -419,9 +415,8 @@ > } > > bool AliasSetTracker::remove(CallSite CS) { > - if (Function *F = CS.getCalledFunction()) > - if (AA.doesNotAccessMemory(F)) > - return false; // doesn't alias anything > + if (AA.doesNotAccessMemory(CS)) > + return false; // doesn't alias anything > > AliasSet *AS = findAliasSetForCallSite(CS); > if (!AS) return false; > @@ -455,13 +450,10 @@ > // If this is a call instruction, remove the callsite from the appropriate > // AliasSet. > CallSite CS = CallSite::get(PtrVal); > - if (CS.getInstruction()) { > - Function *F = CS.getCalledFunction(); > - if (!F || !AA.doesNotAccessMemory(F)) { > + if (CS.getInstruction()) > + if (!AA.doesNotAccessMemory(CS)) > if (AliasSet *AS = findAliasSetForCallSite(CS)) > AS->removeCallSite(CS); > - } > - } > > // First, look up the PointerRec for this pointer. > hash_map::iterator I = PointerMap.find(PtrVal); > > Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) > +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Sat Dec 1 01:51:45 2007 > @@ -839,11 +839,6 @@ > return UnknownModRefBehavior; > } > > - if (F->paramHasAttr(0, ParamAttr::ReadNone)) > - return DoesNotAccessMemory; > - if (F->paramHasAttr(0, ParamAttr::ReadOnly)) > - return OnlyReadsMemory; > - > return UnknownModRefBehavior; > } > > > Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original) > +++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Sat Dec 1 01:51:45 2007 > @@ -394,7 +394,7 @@ > // Okay, if we can't say anything about it, maybe some other alias > // analysis can. > ModRefBehavior MRB = > - AliasAnalysis::getModRefBehavior(Callee, CallSite()); > + AliasAnalysis::getModRefBehavior(Callee); > if (MRB != DoesNotAccessMemory) { > // FIXME: could make this more aggressive for functions that just > // read memory. We should just say they read all globals. > > Modified: llvm/trunk/lib/Analysis/LoadValueNumbering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoadValueNumbering.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/LoadValueNumbering.cpp (original) > +++ llvm/trunk/lib/Analysis/LoadValueNumbering.cpp Sat Dec 1 01:51:45 2007 > @@ -148,7 +148,7 @@ > Function *CF = CI->getCalledFunction(); > if (CF == 0) return; // Indirect call. > AliasAnalysis &AA = getAnalysis(); > - AliasAnalysis::ModRefBehavior MRB = AA.getModRefBehavior(CF, CI); > + AliasAnalysis::ModRefBehavior MRB = AA.getModRefBehavior(CI); > if (MRB != AliasAnalysis::DoesNotAccessMemory && > MRB != AliasAnalysis::OnlyReadsMemory) > return; // Nothing we can do for now. > @@ -227,8 +227,7 @@ > CantEqual = true; > break; > } else if (CallInst *CI = dyn_cast(I)) { > - if (CI->getCalledFunction() == 0 || > - !AA.onlyReadsMemory(CI->getCalledFunction())) { > + if (!AA.onlyReadsMemory(CI)) { > CantEqual = true; > break; > } > > Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) > +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 1 01:51:45 2007 > @@ -94,11 +94,9 @@ > > // FreeInsts erase the entire structure > pointerSize = ~0UL; > - } else if (CallSite::get(QI).getInstruction() != 0 && > - cast(QI)->getCalledFunction()) { > + } else if (isa(QI)) { > AliasAnalysis::ModRefBehavior result = > - AA.getModRefBehavior(cast(QI)->getCalledFunction(), > - CallSite::get(QI)); > + AA.getModRefBehavior(CallSite::get(QI)); > if (result != AliasAnalysis::DoesNotAccessMemory && > result != AliasAnalysis::OnlyReadsMemory) { > if (!start && !block) { > > Modified: llvm/trunk/lib/Transforms/Scalar/ADCE.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ADCE.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/ADCE.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/ADCE.cpp Sat Dec 1 01:51:45 2007 > @@ -198,8 +198,7 @@ > for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) { > Instruction *I = II++; > if (CallInst *CI = dyn_cast(I)) { > - Function *F = CI->getCalledFunction(); > - if (F && AA.onlyReadsMemory(F)) { > + if (AA.onlyReadsMemory(CI)) { > if (CI->use_empty()) { > BB->getInstList().erase(CI); > ++NumCallRemoved; > > Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Sat Dec 1 01:51:45 2007 > @@ -306,8 +306,7 @@ > // If this call does not access memory, it can't > // be undeadifying any of our pointers. > CallSite CS = CallSite::get(BBI); > - if (CS.getCalledFunction() && > - AA.doesNotAccessMemory(CS.getCalledFunction())) > + if (AA.doesNotAccessMemory(CS)) > continue; > > unsigned modRef = 0; > > Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sat Dec 1 01:51:45 2007 > @@ -341,8 +341,7 @@ > > uint32_t ValueTable::hash_operand(Value* v) { > if (CallInst* CI = dyn_cast(v)) > - if (CI->getCalledFunction() && > - !AA->doesNotAccessMemory(CI->getCalledFunction())) > + if (!AA->doesNotAccessMemory(CI)) > return nextValueNumber++; > > return lookup_or_add(v); > @@ -485,9 +484,7 @@ > return VI->second; > > if (CallInst* C = dyn_cast(V)) { > - if (C->getCalledFunction() && > - (AA->doesNotAccessMemory(C->getCalledFunction()) || > - AA->onlyReadsMemory(C->getCalledFunction()))) { > + if (AA->onlyReadsMemory(C)) { // includes doesNotAccessMemory > Expression e = create_expression(C); > > DenseMap::iterator EI = expressionNumbering.find(e); > @@ -1051,8 +1048,7 @@ > > if (CallInst* CI = dyn_cast(I)) { > AliasAnalysis& AA = getAnalysis(); > - if (CI->getCalledFunction() && > - !AA.doesNotAccessMemory(CI->getCalledFunction())) { > + if (!AA.doesNotAccessMemory(CI)) { > MemoryDependenceAnalysis& MD = getAnalysis(); > if (cast(repl)->getParent() != CI->getParent() || > MD.getDependency(CI) != MD.getDependency(cast(repl))) { > > Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=44487&r1=44486&r2=44487&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Sat Dec 1 01:51:45 2007 > @@ -375,24 +375,22 @@ > return !pointerInvalidatedByLoop(LI->getOperand(0), Size); > } else if (CallInst *CI = dyn_cast(&I)) { > // Handle obvious cases efficiently. > - if (Function *Callee = CI->getCalledFunction()) { > - AliasAnalysis::ModRefBehavior Behavior =AA->getModRefBehavior(Callee, CI); > - if (Behavior == AliasAnalysis::DoesNotAccessMemory) > - return true; > - else if (Behavior == AliasAnalysis::OnlyReadsMemory) { > - // If this call only reads from memory and there are no writes to memory > - // in the loop, we can hoist or sink the call as appropriate. > - bool FoundMod = false; > - for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); > - I != E; ++I) { > - AliasSet &AS = *I; > - if (!AS.isForwardingAliasSet() && AS.isMod()) { > - FoundMod = true; > - break; > - } > + AliasAnalysis::ModRefBehavior Behavior = AA->getModRefBehavior(CI); > + if (Behavior == AliasAnalysis::DoesNotAccessMemory) > + return true; > + else if (Behavior == AliasAnalysis::OnlyReadsMemory) { > + // If this call only reads from memory and there are no writes to memory > + // in the loop, we can hoist or sink the call as appropriate. > + bool FoundMod = false; > + for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); > + I != E; ++I) { > + AliasSet &AS = *I; > + if (!AS.isForwardingAliasSet() && AS.isMod()) { > + FoundMod = true; > + break; > } > - if (!FoundMod) return true; > } > + if (!FoundMod) return true; > } > > // FIXME: This should use mod/ref information to see if we can hoist or sink > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Wed Dec 5 01:36:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 07:36:58 -0000 Subject: [llvm-commits] [llvm] r44607 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200712050736.lB57awtl029024@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 01:36:58 2007 New Revision: 44607 URL: http://llvm.org/viewvc/llvm-project?rev=44607&view=rev Log: scalarize vector binops Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44607&r1=44606&r2=44607&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Wed Dec 5 01:36:58 2007 @@ -206,6 +206,7 @@ void ScalarizeResult(SDNode *N, unsigned OpNo); SDOperand ScalarizeRes_UNDEF(SDNode *N); SDOperand ScalarizeRes_LOAD(LoadSDNode *N); + SDOperand ScalarizeRes_BinOp(SDNode *N); // Operand Promotion. bool PromoteOperand(SDNode *N, unsigned OperandNo); @@ -1625,11 +1626,27 @@ cerr << "ScalarizeResult #" << ResNo << ": "; N->dump(&DAG); cerr << "\n"; #endif - assert(0 && "Do not know how to expand the result of this operator!"); + assert(0 && "Do not know how to scalarize the result of this operator!"); abort(); case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; + case ISD::ADD: + case ISD::FADD: + case ISD::SUB: + case ISD::FSUB: + case ISD::MUL: + case ISD::FMUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::FDIV: + case ISD::SREM: + case ISD::UREM: + case ISD::FREM: + case ISD::FPOW: + case ISD::AND: + case ISD::OR: + case ISD::XOR: R = ScalarizeRes_BinOp(N); break; } // If R is null, the sub-method took care of registering the resul. @@ -1653,6 +1670,12 @@ return Result; } +SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) { + SDOperand LHS = GetScalarizedOp(N->getOperand(0)); + SDOperand RHS = GetScalarizedOp(N->getOperand(1)); + return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); +} + //===----------------------------------------------------------------------===// // Operand Promotion From sabre at nondot.org Wed Dec 5 01:45:02 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 07:45:02 -0000 Subject: [llvm-commits] [llvm] r44608 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200712050745.lB57j2UP029528@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 01:45:02 2007 New Revision: 44608 URL: http://llvm.org/viewvc/llvm-project?rev=44608&view=rev Log: more scalarization Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44608&r1=44607&r2=44608&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Wed Dec 5 01:45:02 2007 @@ -207,6 +207,10 @@ SDOperand ScalarizeRes_UNDEF(SDNode *N); SDOperand ScalarizeRes_LOAD(LoadSDNode *N); SDOperand ScalarizeRes_BinOp(SDNode *N); + SDOperand ScalarizeRes_UnaryOp(SDNode *N); + SDOperand ScalarizeRes_FPOWI(SDNode *N); + SDOperand ScalarizeRes_BUILD_VECTOR(SDNode *N); + SDOperand ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N); // Operand Promotion. bool PromoteOperand(SDNode *N, unsigned OperandNo); @@ -1647,6 +1651,14 @@ case ISD::AND: case ISD::OR: case ISD::XOR: R = ScalarizeRes_BinOp(N); break; + case ISD::FNEG: + case ISD::FABS: + case ISD::FSQRT: + case ISD::FSIN: + case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; + case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; + case ISD::BUILD_VECTOR: R = ScalarizeRes_BUILD_VECTOR(N); break; + case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break; } // If R is null, the sub-method took care of registering the resul. @@ -1676,6 +1688,24 @@ return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); } +SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) { + SDOperand Op = GetScalarizedOp(N->getOperand(0)); + return DAG.getNode(N->getOpcode(), Op.getValueType(), Op); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) { + SDOperand Op = GetScalarizedOp(N->getOperand(0)); + return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_BUILD_VECTOR(SDNode *N) { + return N->getOperand(0); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) { + return N->getOperand(1); // Returning the inserted scalar element. +} + //===----------------------------------------------------------------------===// // Operand Promotion From evan.cheng at apple.com Wed Dec 5 02:16:32 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 08:16:32 -0000 Subject: [llvm-commits] [llvm] r44609 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp VirtRegMap.cpp VirtRegMap.h Message-ID: <200712050816.lB58GXgV031376@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 02:16:32 2007 New Revision: 44609 URL: http://llvm.org/viewvc/llvm-project?rev=44609&view=rev Log: Fix kill info for split intervals. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/CodeGen/VirtRegMap.h Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44609&r1=44608&r2=44609&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Dec 5 02:16:32 2007 @@ -1267,6 +1267,7 @@ if (!TrySplit) return NewLIs; + SmallPtrSet AddedKill; SmallVector Ops; if (NeedStackSlot) { int Id = SpillMBBs.find_first(); @@ -1316,8 +1317,13 @@ } // Else tell the spiller to issue a spill. - if (!Folded) - vrm.addSpillPoint(VReg, MI); + if (!Folded) { + LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; + bool isKill = LR->end == getStoreIndex(index); + vrm.addSpillPoint(VReg, isKill, MI); + if (isKill) + AddedKill.insert(&nI); + } } Id = SpillMBBs.find_next(Id); } @@ -1372,24 +1378,28 @@ // load / rematerialization for us. if (Folded) nI.removeRange(getLoadIndex(index), getUseIndex(index)+1); - else { + else vrm.addRestorePoint(VReg, MI); - LiveRange *LR = &nI.ranges[nI.ranges.size()-1]; - MachineInstr *LastUse = getInstructionFromIndex(getBaseIndex(LR->end)); - int UseIdx = LastUse->findRegisterUseOperandIdx(VReg); - assert(UseIdx != -1); - LastUse->getOperand(UseIdx).setIsKill(); - } } Id = RestoreMBBs.find_next(Id); } - // Finalize spill weights and filter out dead intervals. + // Finalize intervals: add kills, finalize spill weights, and filter out + // dead intervals. std::vector RetNewLIs; for (unsigned i = 0, e = NewLIs.size(); i != e; ++i) { LiveInterval *LI = NewLIs[i]; if (!LI->empty()) { LI->weight /= LI->getSize(); + if (!AddedKill.count(LI)) { + LiveRange *LR = &LI->ranges[LI->ranges.size()-1]; + MachineInstr *LastUse = getInstructionFromIndex(getBaseIndex(LR->end)); + int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg); + assert(UseIdx != -1); + if (LastUse->getInstrDescriptor()-> + getOperandConstraint(UseIdx, TOI::TIED_TO) == -1) + LastUse->getOperand(UseIdx).setIsKill(); + } RetNewLIs.push_back(LI); } } Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44609&r1=44608&r2=44609&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Wed Dec 5 02:16:32 2007 @@ -977,15 +977,17 @@ // Insert spills here if asked to. if (VRM.isSpillPt(&MI)) { - std::vector &SpillRegs = VRM.getSpillPtSpills(&MI); + std::vector > &SpillRegs = + VRM.getSpillPtSpills(&MI); for (unsigned i = 0, e = SpillRegs.size(); i != e; ++i) { - unsigned VirtReg = SpillRegs[i]; + unsigned VirtReg = SpillRegs[i].first; + bool isKill = SpillRegs[i].second; if (!VRM.getPreSplitReg(VirtReg)) continue; // Split interval spilled again. const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); - MRI->storeRegToStackSlot(MBB, next(MII), Phys, false, StackSlot, RC); + MRI->storeRegToStackSlot(MBB, next(MII), Phys, isKill, StackSlot, RC); MachineInstr *StoreMI = next(MII); DOUT << "Store:\t" << StoreMI; VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod); Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=44609&r1=44608&r2=44609&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.h (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.h Wed Dec 5 02:16:32 2007 @@ -80,7 +80,8 @@ /// SpillPt2VirtMap - This records the virtual registers which should /// be spilled right after the MachineInstr due to live interval /// splitting. - std::map > SpillPt2VirtMap; + std::map > > + SpillPt2VirtMap; /// RestorePt2VirtMap - This records the virtual registers which should /// be restored right before the MachineInstr due to live interval @@ -216,30 +217,31 @@ /// @brief returns the virtual registers that should be spilled due to /// splitting right after the specified MachineInstr. - std::vector &getSpillPtSpills(MachineInstr *Pt) { + std::vector > &getSpillPtSpills(MachineInstr *Pt) { return SpillPt2VirtMap[Pt]; } /// @brief records the specified MachineInstr as a spill point for virtReg. - void addSpillPoint(unsigned virtReg, MachineInstr *Pt) { + void addSpillPoint(unsigned virtReg, bool isKill, MachineInstr *Pt) { if (SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end()) - SpillPt2VirtMap[Pt].push_back(virtReg); + SpillPt2VirtMap[Pt].push_back(std::make_pair(virtReg, isKill)); else { - std::vector Virts; - Virts.push_back(virtReg); + std::vector > Virts; + Virts.push_back(std::make_pair(virtReg, isKill)); SpillPt2VirtMap.insert(std::make_pair(Pt, Virts)); } } void transferSpillPts(MachineInstr *Old, MachineInstr *New) { - std::map >::iterator I = - SpillPt2VirtMap.find(Old); + std::map > >::iterator + I = SpillPt2VirtMap.find(Old); if (I == SpillPt2VirtMap.end()) return; while (!I->second.empty()) { - unsigned virtReg = I->second.back(); + unsigned virtReg = I->second.back().first; + bool isKill = I->second.back().second; I->second.pop_back(); - addSpillPoint(virtReg, New); + addSpillPoint(virtReg, isKill, New); } SpillPt2VirtMap.erase(I); } From evan.cheng at apple.com Wed Dec 5 03:05:35 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 09:05:35 -0000 Subject: [llvm-commits] [llvm] r44610 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200712050905.lB595ZmA009037@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 03:05:34 2007 New Revision: 44610 URL: http://llvm.org/viewvc/llvm-project?rev=44610&view=rev Log: Clobber more bugs. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44610&r1=44609&r2=44610&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Dec 5 03:05:34 2007 @@ -1221,7 +1221,6 @@ // Original def may be modified so we have to make a copy here. vrm must // delete these! ReMatDefs[VN] = ReMatDefMI = ReMatDefMI->clone(); - vrm.setVirtIsReMaterialized(li.reg, ReMatDefMI); bool CanDelete = true; if (VNI->hasPHIKill) { @@ -1309,9 +1308,11 @@ if (CanFold && !Ops.empty()) { if (tryFoldMemoryOperand(MI, vrm, NULL, index, Ops, true, Slot,VReg)){ Folded = true; - if (FoundUse > 0) + if (FoundUse > 0) { // Also folded uses, do not issue a load. eraseRestoreInfo(Id, index, VReg, RestoreMBBs, RestoreIdxes); + nI.removeRange(getLoadIndex(index), getUseIndex(index)+1); + } nI.removeRange(getDefIndex(index), getStoreIndex(index)); } } From baldrick at free.fr Wed Dec 5 03:31:33 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 5 Dec 2007 10:31:33 +0100 Subject: [llvm-commits] [llvm] r44487 - in /llvm/trunk: include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp lib/Analysis/AliasAnalysisCounter.cpp lib/Analysis/AliasSetTracker.cpp lib/Analysis/BasicAliasAnalysis.cpp lib/Analysis/IPA/Global In-Reply-To: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> References: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> Message-ID: <200712051031.33944.baldrick@free.fr> Hi Bill, > This patch seems to be causing a bootstrap failure on my system. I try > to compile llvm-gcc-4.2 and it gives me errors like this during stage2 > of the bootstrapping build: I will look into it. Thanks for letting me know. Ciao, Duncan. From evan.cheng at apple.com Wed Dec 5 03:51:13 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 09:51:13 -0000 Subject: [llvm-commits] [llvm] r44611 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp VirtRegMap.cpp VirtRegMap.h Message-ID: <200712050951.lB59pFHx011500@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 03:51:10 2007 New Revision: 44611 URL: http://llvm.org/viewvc/llvm-project?rev=44611&view=rev Log: If a split live interval is spilled again, remove the kill marker on its last use. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/CodeGen/VirtRegMap.h Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44611&r1=44610&r2=44611&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Dec 5 03:51:10 2007 @@ -1165,6 +1165,7 @@ // it's also guaranteed to be a single val# / range interval. if (vrm.getPreSplitReg(li.reg)) { vrm.setIsSplitFromReg(li.reg, 0); + vrm.removeKillPoint(li.reg); bool DefIsReMat = vrm.isReMaterialized(li.reg); Slot = vrm.getStackSlot(li.reg); assert(Slot != VirtRegMap::MAX_STACK_SLOT); @@ -1398,8 +1399,10 @@ int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg); assert(UseIdx != -1); if (LastUse->getInstrDescriptor()-> - getOperandConstraint(UseIdx, TOI::TIED_TO) == -1) + getOperandConstraint(UseIdx, TOI::TIED_TO) == -1) { LastUse->getOperand(UseIdx).setIsKill(); + vrm.addKillPoint(LI->reg, &LastUse->getOperand(UseIdx)); + } } RetNewLIs.push_back(LI); } Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44611&r1=44610&r2=44611&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Wed Dec 5 03:51:10 2007 @@ -64,7 +64,7 @@ : TII(*mf.getTarget().getInstrInfo()), MF(mf), Virt2PhysMap(NO_PHYS_REG), Virt2StackSlotMap(NO_STACK_SLOT), Virt2ReMatIdMap(NO_STACK_SLOT), Virt2SplitMap(0), - ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1) { + Virt2SplitKillMap(NULL), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1) { grow(); } @@ -74,6 +74,7 @@ Virt2StackSlotMap.grow(LastVirtReg); Virt2ReMatIdMap.grow(LastVirtReg); Virt2SplitMap.grow(LastVirtReg); + Virt2SplitKillMap.grow(LastVirtReg); ReMatMap.grow(LastVirtReg); } Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=44611&r1=44610&r2=44611&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.h (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.h Wed Dec 5 03:51:10 2007 @@ -66,6 +66,10 @@ /// mapping. IndexedMap Virt2SplitMap; + /// Virt2SplitKillMap - This is splitted virtual register to its last use + /// (kill) mapping. + IndexedMap Virt2SplitKillMap; + /// ReMatMap - This is virtual register to re-materialized instruction /// mapping. Each virtual register whose definition is going to be /// re-materialized has an entry in it. @@ -210,6 +214,21 @@ ReMatMap[virtReg] = def; } + /// @brief record the last use (kill) of a split virtual register. + void addKillPoint(unsigned virtReg, MachineOperand *Op) { + Virt2SplitKillMap[virtReg] = Op; + } + + /// @brief reset and remove the last use (kill) of a split virtual register. + void removeKillPoint(unsigned virtReg) { + MachineOperand *MO = Virt2SplitKillMap[virtReg]; + if (MO) { + assert(MO->isKill() && "Split last use is not marked kill?"); + MO->unsetIsKill(); + Virt2SplitKillMap[virtReg] = NULL; + } + } + /// @brief returns true if the specified MachineInstr is a spill point. bool isSpillPt(MachineInstr *Pt) const { return SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end(); From evan.cheng at apple.com Wed Dec 5 04:24:44 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 10:24:44 -0000 Subject: [llvm-commits] [llvm] r44612 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp VirtRegMap.cpp VirtRegMap.h Message-ID: <200712051024.lB5AOugu013388@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 04:24:35 2007 New Revision: 44612 URL: http://llvm.org/viewvc/llvm-project?rev=44612&view=rev Log: MachineInstr can change. Store indexes instead. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/VirtRegMap.cpp llvm/trunk/lib/CodeGen/VirtRegMap.h Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44612&r1=44611&r2=44612&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Dec 5 04:24:35 2007 @@ -1165,6 +1165,15 @@ // it's also guaranteed to be a single val# / range interval. if (vrm.getPreSplitReg(li.reg)) { vrm.setIsSplitFromReg(li.reg, 0); + // Unset the split kill marker on the last use. + unsigned KillIdx = vrm.getKillPoint(li.reg); + if (KillIdx) { + MachineInstr *KillMI = getInstructionFromIndex(KillIdx); + assert(KillMI && "Last use disappeared?"); + int KillOp = KillMI->findRegisterUseOperandIdx(li.reg, true); + assert(KillOp != -1 && "Last use disappeared?"); + KillMI->getOperand(KillOp).unsetIsKill(); + } vrm.removeKillPoint(li.reg); bool DefIsReMat = vrm.isReMaterialized(li.reg); Slot = vrm.getStackSlot(li.reg); @@ -1395,13 +1404,14 @@ LI->weight /= LI->getSize(); if (!AddedKill.count(LI)) { LiveRange *LR = &LI->ranges[LI->ranges.size()-1]; - MachineInstr *LastUse = getInstructionFromIndex(getBaseIndex(LR->end)); + unsigned LastUseIdx = getBaseIndex(LR->end); + MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx); int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg); assert(UseIdx != -1); if (LastUse->getInstrDescriptor()-> getOperandConstraint(UseIdx, TOI::TIED_TO) == -1) { LastUse->getOperand(UseIdx).setIsKill(); - vrm.addKillPoint(LI->reg, &LastUse->getOperand(UseIdx)); + vrm.addKillPoint(LI->reg, LastUseIdx); } } RetNewLIs.push_back(LI); Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44612&r1=44611&r2=44612&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Wed Dec 5 04:24:35 2007 @@ -64,7 +64,7 @@ : TII(*mf.getTarget().getInstrInfo()), MF(mf), Virt2PhysMap(NO_PHYS_REG), Virt2StackSlotMap(NO_STACK_SLOT), Virt2ReMatIdMap(NO_STACK_SLOT), Virt2SplitMap(0), - Virt2SplitKillMap(NULL), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1) { + Virt2SplitKillMap(0), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1) { grow(); } Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=44612&r1=44611&r2=44612&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.h (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.h Wed Dec 5 04:24:35 2007 @@ -67,8 +67,8 @@ IndexedMap Virt2SplitMap; /// Virt2SplitKillMap - This is splitted virtual register to its last use - /// (kill) mapping. - IndexedMap Virt2SplitKillMap; + /// (kill) index mapping. + IndexedMap Virt2SplitKillMap; /// ReMatMap - This is virtual register to re-materialized instruction /// mapping. Each virtual register whose definition is going to be @@ -215,18 +215,17 @@ } /// @brief record the last use (kill) of a split virtual register. - void addKillPoint(unsigned virtReg, MachineOperand *Op) { - Virt2SplitKillMap[virtReg] = Op; + void addKillPoint(unsigned virtReg, unsigned index) { + Virt2SplitKillMap[virtReg] = index; } - /// @brief reset and remove the last use (kill) of a split virtual register. + unsigned getKillPoint(unsigned virtReg) const { + return Virt2SplitKillMap[virtReg]; + } + + /// @brief remove the last use (kill) of a split virtual register. void removeKillPoint(unsigned virtReg) { - MachineOperand *MO = Virt2SplitKillMap[virtReg]; - if (MO) { - assert(MO->isKill() && "Split last use is not marked kill?"); - MO->unsetIsKill(); - Virt2SplitKillMap[virtReg] = NULL; - } + Virt2SplitKillMap[virtReg] = 0; } /// @brief returns true if the specified MachineInstr is a spill point. From neil at daikokuya.co.uk Wed Dec 5 07:01:27 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Wed, 05 Dec 2007 13:01:27 -0000 Subject: [llvm-commits] [llvm] r44613 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200712051301.lB5D1SC0021810@zion.cs.uiuc.edu> Author: neil Date: Wed Dec 5 07:01:24 2007 New Revision: 44613 URL: http://llvm.org/viewvc/llvm-project?rev=44613&view=rev Log: Handle zero correctly. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=44613&r1=44612&r2=44613&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Wed Dec 5 07:01:24 2007 @@ -231,8 +231,8 @@ is taken to have the decimal point after a single leading non-zero digit. - If the value is zero, V->firstSigDigit points to a zero, and the - return exponent is zero. + If the value is zero, V->firstSigDigit points to a non-digit, and + the return exponent is zero. */ struct decimalInfo { const char *firstSigDigit; @@ -263,7 +263,7 @@ } /* If number is all zerooes accept any exponent. */ - if (p != D->firstSigDigit) { + if (decDigitValue(*p) >= 10U) { if (*p == 'e' || *p == 'E') D->exponent = readExponent(p + 1); From neil at daikokuya.co.uk Wed Dec 5 07:06:07 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Wed, 05 Dec 2007 13:06:07 -0000 Subject: [llvm-commits] [llvm] r44614 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200712051306.lB5D68fZ022099@zion.cs.uiuc.edu> Author: neil Date: Wed Dec 5 07:06:04 2007 New Revision: 44614 URL: http://llvm.org/viewvc/llvm-project?rev=44614&view=rev Log: Prior commit updated wrong if, apologies. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=44614&r1=44613&r2=44614&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Wed Dec 5 07:06:04 2007 @@ -263,7 +263,7 @@ } /* If number is all zerooes accept any exponent. */ - if (decDigitValue(*p) >= 10U) { + if (p != D->firstSigDigit) { if (*p == 'e' || *p == 'E') D->exponent = readExponent(p + 1); @@ -2145,7 +2145,7 @@ 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] */ - if (*D.firstSigDigit == 0) { + if (decDigitValue(*D.firstSigDigit) >= 10U) { category = fcZero; fs = opOK; } else if ((D.normalizedExponent + 1) * 28738 From sabre at nondot.org Wed Dec 5 12:30:11 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 18:30:11 -0000 Subject: [llvm-commits] [llvm] r44619 - /llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Message-ID: <200712051830.lB5IUBGH010476@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 12:30:11 2007 New Revision: 44619 URL: http://llvm.org/viewvc/llvm-project?rev=44619&view=rev Log: allow this to build Modified: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Modified: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td?rev=44619&r1=44618&r2=44619&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Wed Dec 5 12:30:11 2007 @@ -56,6 +56,6 @@ // Vectors get 16-byte stack slots that are 16-byte aligned. CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCAssignToStack<16, 16>>*/ + CCAssignToStack<16, 16>> ]>; */ From sabre at nondot.org Wed Dec 5 12:32:18 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 18:32:18 -0000 Subject: [llvm-commits] [llvm] r44620 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200712051832.lB5IWIVH010584@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 12:32:18 2007 New Revision: 44620 URL: http://llvm.org/viewvc/llvm-project?rev=44620&view=rev Log: fix warnings Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=44620&r1=44619&r2=44620&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Dec 5 12:32:18 2007 @@ -659,8 +659,8 @@ MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getStoredVT()); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); SDOperand the_chain = SN->getChain(); - unsigned alignment = SN->getAlignment(); - const valtype_map_s *vtm = getValueTypeMapEntry(VT); + //unsigned alignment = SN->getAlignment(); + //const valtype_map_s *vtm = getValueTypeMapEntry(VT); switch (SN->getAddressingMode()) { case ISD::UNINDEXED: { From clattner at apple.com Wed Dec 5 12:33:48 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 5 Dec 2007 10:33:48 -0800 Subject: [llvm-commits] [llvm] r44598 - in /llvm/trunk: autoconf/configure.ac include/llvm/Intrinsics.td include/llvm/IntrinsicsCellSPU.td lib/Target/CellSPU/README.txt In-Reply-To: <200712050201.lB521gui010821@zion.cs.uiuc.edu> References: <200712050201.lB521gui010821@zion.cs.uiuc.edu> Message-ID: On Dec 4, 2007, at 6:01 PM, Scott Michel wrote: > Author: pingbak > Date: Tue Dec 4 20:01:41 2007 > New Revision: 44598 > URL: http://llvm.org/viewvc/llvm-project?rev=44598&view=rev > Log: > More stuff for CellSPU -- this should be enough to get an error-free > compilation (no files missing). Test cases remain to be checked in. Nice Scott! You really need to update llvm/CREDITS.txt to take credit :) > +++ llvm/trunk/autoconf/configure.ac Tue Dec 4 20:01:41 2007 > @@ -363,6 +363,7 @@ > [Build specific host targets: all,host-only,{target-name} > (default=all)]),, > enableval=all) > case "$enableval" in > + # Note: Add "CellSPU" to all when fully functional. > all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips" ;; Please add CellSPU to all, even though it's not fully functional. A great example is mips, which is also still in development. Once this is in place, we can add SPU tests to llvm/test/Codegen/ CellSPU. Thanks! -Chris From evan.cheng at apple.com Wed Dec 5 12:36:38 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 18:36:38 -0000 Subject: [llvm-commits] [llvm] r44621 - in /llvm/trunk/lib/Target/CellSPU: SPURegisterInfo.cpp SPURegisterInfo.h Message-ID: <200712051836.lB5Iacun010801@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 12:36:37 2007 New Revision: 44621 URL: http://llvm.org/viewvc/llvm-project?rev=44621&view=rev Log: Update foldMemoryOperand. Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp?rev=44621&r1=44620&r2=44621&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.cpp Wed Dec 5 12:36:37 2007 @@ -501,10 +501,14 @@ /// foldMemoryOperand - SPU, like PPC, can only fold spills into /// copy instructions, turning them into load/store instructions. MachineInstr * -SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, +SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops, int FrameIndex) const { #if SOMEDAY_SCOTT_LOOKS_AT_ME_AGAIN + if (Ops.size() != 1) return NULL; + + unsigned OpNum = Ops[0]; unsigned Opc = MI->getOpcode(); MachineInstr *NewMI = 0; @@ -535,7 +539,8 @@ /// General-purpose load/store fold to operand code MachineInstr * -SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, +SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops, MachineInstr *LoadMI) const { return 0; Modified: llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h?rev=44621&r1=44620&r2=44621&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPURegisterInfo.h Wed Dec 5 12:36:37 2007 @@ -76,11 +76,13 @@ unsigned DestReg, const MachineInstr *Orig) const; //! Fold spills into load/store instructions - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + SmallVectorImpl &Ops, int FrameIndex) const; //! Fold any load/store to an operand - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + SmallVectorImpl &Ops, MachineInstr* LoadMI) const; //! Return the array of callee-saved registers From evan.cheng at apple.com Wed Dec 5 12:41:29 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 18:41:29 -0000 Subject: [llvm-commits] [llvm] r44623 - in /llvm/trunk/lib/Target/PowerPC: PPCRegisterInfo.cpp PPCRegisterInfo.h Message-ID: <200712051841.lB5IfT6H011094@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 12:41:29 2007 New Revision: 44623 URL: http://llvm.org/viewvc/llvm-project?rev=44623&view=rev Log: Added canFoldMemoryOperand for PPC. Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=44623&r1=44622&r2=44623&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Wed Dec 5 12:41:29 2007 @@ -613,6 +613,26 @@ return NewMI; } +bool PPCRegisterInfo::canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const { + if (Ops.size() != 1) return NULL; + + // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because + // it takes more than one instruction to store it. + unsigned Opc = MI->getOpcode(); + + if ((Opc == PPC::OR && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) + return true; + else if ((Opc == PPC::OR8 && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) + return true; + else if (Opc == PPC::FMRD || Opc == PPC::FMRS) + return true; + + return false; +} + //===----------------------------------------------------------------------===// // Stack Frame Processing methods //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=44623&r1=44622&r2=44623&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Wed Dec 5 12:41:29 2007 @@ -75,6 +75,9 @@ return 0; } + virtual bool canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const; + const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const; const TargetRegisterClass* const* From baldrick at free.fr Wed Dec 5 15:03:29 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 05 Dec 2007 21:03:29 -0000 Subject: [llvm-commits] [llvm] r44626 - in /llvm/trunk/lib: Analysis/AliasAnalysis.cpp VMCore/Instruction.cpp Message-ID: <200712052103.lB5L3TC2019228@zion.cs.uiuc.edu> Author: baldrick Date: Wed Dec 5 15:03:28 2007 New Revision: 44626 URL: http://llvm.org/viewvc/llvm-project?rev=44626&view=rev Log: Commit 44487 broke bootstrap of llvm-gcc-4.2. It is not yet clear why, but in the meantime work around the problem by making less use of readnone/readonly info. Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp llvm/trunk/lib/VMCore/Instruction.cpp Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=44626&r1=44625&r2=44626&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Wed Dec 5 15:03:28 2007 @@ -116,13 +116,17 @@ AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(CallSite CS, std::vector *Info) { - if (CS.doesNotAccessMemory()) + if (CS.doesNotAccessMemory() && + // FIXME: workaround gcc bootstrap breakage + CS.getCalledFunction() && CS.getCalledFunction()->isDeclaration()) // Can't do better than this. return DoesNotAccessMemory; ModRefBehavior MRB = UnknownModRefBehavior; if (Function *F = CS.getCalledFunction()) MRB = getModRefBehavior(F, CS, Info); - if (MRB != DoesNotAccessMemory && CS.onlyReadsMemory()) + if (MRB != DoesNotAccessMemory && CS.onlyReadsMemory() && + // FIXME: workaround gcc bootstrap breakage + CS.getCalledFunction() && CS.getCalledFunction()->isDeclaration()) return OnlyReadsMemory; return MRB; } @@ -130,11 +134,15 @@ AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(Function *F, std::vector *Info) { - if (F->doesNotAccessMemory()) + if (F->doesNotAccessMemory() && + // FIXME: workaround gcc bootstrap breakage + F->isDeclaration()) // Can't do better than this. return DoesNotAccessMemory; ModRefBehavior MRB = getModRefBehavior(F, CallSite(), Info); - if (MRB != DoesNotAccessMemory && F->onlyReadsMemory()) + if (MRB != DoesNotAccessMemory && F->onlyReadsMemory() && + // FIXME: workaround gcc bootstrap breakage + F->isDeclaration()) return OnlyReadsMemory; return MRB; } Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=44626&r1=44625&r2=44626&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Wed Dec 5 15:03:28 2007 @@ -13,6 +13,7 @@ #include "llvm/Type.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" // FIXME: remove #include "llvm/Function.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" @@ -208,6 +209,8 @@ case Instruction::VAArg: return true; case Instruction::Call: + if (!isa(this)) + return true; // FIXME: workaround gcc bootstrap breakage return !cast(this)->onlyReadsMemory(); case Instruction::Load: return cast(this)->isVolatile(); From baldrick at free.fr Wed Dec 5 15:06:06 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 5 Dec 2007 22:06:06 +0100 Subject: [llvm-commits] [llvm] r44487 - in /llvm/trunk: include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp lib/Analysis/AliasAnalysisCounter.cpp lib/Analysis/AliasSetTracker.cpp lib/Analysis/BasicAliasAnalysis.cpp lib/Analysis/IPA/Global In-Reply-To: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> References: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> Message-ID: <200712052206.08056.baldrick@free.fr> Hi Bill, > This patch seems to be causing a bootstrap failure on my system. I try > to compile llvm-gcc-4.2 and it gives me errors like this during stage2 > of the bootstrapping build: I've committed a workaround. It's not yet clear what the root cause of the problem is. Best wishes, Duncan. From clattner at apple.com Wed Dec 5 15:06:46 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 5 Dec 2007 13:06:46 -0800 Subject: [llvm-commits] [llvm] r44487 - in /llvm/trunk: include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp lib/Analysis/AliasAnalysisCounter.cpp lib/Analysis/AliasSetTracker.cpp lib/Analysis/BasicAliasAnalysis.cpp lib/Analysis/IPA/Global In-Reply-To: <200712052206.08056.baldrick@free.fr> References: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> <200712052206.08056.baldrick@free.fr> Message-ID: On Dec 5, 2007, at 1:06 PM, Duncan Sands wrote: > Hi Bill, > >> This patch seems to be causing a bootstrap failure on my system. I >> try >> to compile llvm-gcc-4.2 and it gives me errors like this during >> stage2 >> of the bootstrapping build: > > I've committed a workaround. It's not yet clear what the root > cause of > the problem is. Thanks Duncan! -Chris From isanbard at gmail.com Wed Dec 5 15:09:31 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 5 Dec 2007 13:09:31 -0800 Subject: [llvm-commits] [llvm] r44487 - in /llvm/trunk: include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp lib/Analysis/AliasAnalysisCounter.cpp lib/Analysis/AliasSetTracker.cpp lib/Analysis/BasicAliasAnalysis.cpp lib/Analysis/IPA/Global In-Reply-To: <200712052206.08056.baldrick@free.fr> References: <16e5fdf90712042205j32f7ea7crc70d4b54e70bb7a9@mail.gmail.com> <200712052206.08056.baldrick@free.fr> Message-ID: <16e5fdf90712051309r16b3a4afq8b540c592fb4d7f6@mail.gmail.com> Hi Duncan, > > This patch seems to be causing a bootstrap failure on my system. I try > > to compile llvm-gcc-4.2 and it gives me errors like this during stage2 > > of the bootstrapping build: > > I've committed a workaround. It's not yet clear what the root cause of > the problem is. > Thanks for looking into/fixing this! -bw From scottm at aero.org Wed Dec 5 15:23:16 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 21:23:16 -0000 Subject: [llvm-commits] [llvm] r44627 - in /llvm/trunk: CREDITS.TXT autoconf/configure.ac lib/Target/CellSPU/SPUCallingConv.td Message-ID: <200712052123.lB5LNGxr020626@zion.cs.uiuc.edu> Author: pingbak Date: Wed Dec 5 15:23:16 2007 New Revision: 44627 URL: http://llvm.org/viewvc/llvm-project?rev=44627&view=rev Log: Minor updates: - Fix typo in SPUCallingConv.td - Credit myself for CellSPU work - Add CellSPU to 'all' host target list Modified: llvm/trunk/CREDITS.TXT llvm/trunk/autoconf/configure.ac llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Modified: llvm/trunk/CREDITS.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CREDITS.TXT?rev=44627&r1=44626&r2=44627&view=diff ============================================================================== --- llvm/trunk/CREDITS.TXT (original) +++ llvm/trunk/CREDITS.TXT Wed Dec 5 15:23:16 2007 @@ -257,3 +257,7 @@ D: Darwin exception handling D: MMX & SSSE3 instructions D: SPEC2006 support + +N: Scott Michel +E: scottm at aero.org +D: Added STI Cell SPU backend. Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=44627&r1=44626&r2=44627&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Wed Dec 5 15:23:16 2007 @@ -363,8 +363,7 @@ [Build specific host targets: all,host-only,{target-name} (default=all)]),, enableval=all) case "$enableval" in - # Note: Add "CellSPU" to all when fully functional. - all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips" ;; + all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU" ;; host-only) case "$llvm_cv_target_arch" in x86) TARGETS_TO_BUILD="X86" ;; Modified: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td?rev=44627&r1=44626&r2=44627&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Wed Dec 5 15:23:16 2007 @@ -48,7 +48,6 @@ // The first 12 Vector arguments are passed in altivec registers. CCIfType<[v16i8, v8i16, v4i32, v4f32], CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9, V10,V11,V12,V13]>> - */ /* // Integer/FP values get stored in stack slots that are 8 bytes in size and // 8-byte aligned if there are no more registers to hold them. @@ -56,6 +55,6 @@ // Vectors get 16-byte stack slots that are 16-byte aligned. CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCAssignToStack<16, 16>> + CCAssignToStack<16, 16>>*/ ]>; */ From scottm at aero.org Wed Dec 5 15:24:02 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 05 Dec 2007 21:24:02 -0000 Subject: [llvm-commits] [llvm] r44628 - /llvm/trunk/configure Message-ID: <200712052124.lB5LO3GT020662@zion.cs.uiuc.edu> Author: pingbak Date: Wed Dec 5 15:24:02 2007 New Revision: 44628 URL: http://llvm.org/viewvc/llvm-project?rev=44628&view=rev Log: Regenerated configure after autoconf/configure.ac change. Modified: llvm/trunk/configure Modified: llvm/trunk/configure URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=44628&r1=44627&r2=44628&view=diff ============================================================================== --- llvm/trunk/configure (original) +++ llvm/trunk/configure Wed Dec 5 15:24:02 2007 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60 for llvm 2.2svn. +# Generated by GNU Autoconf 2.61 for llvm 2.2svn. # # Report bugs to . # @@ -14,7 +14,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -23,10 +24,13 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -219,7 +223,7 @@ else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. @@ -237,7 +241,6 @@ # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -246,10 +249,12 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : _ASEOF @@ -257,7 +262,6 @@ CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -266,10 +270,12 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : (as_func_return () { @@ -516,19 +522,28 @@ as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -723,36 +738,36 @@ # Factoring default headers for most tests. ac_includes_default="\ #include -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H # include #endif -#if STDC_HEADERS +#ifdef STDC_HEADERS # include # include #else -# if HAVE_STDLIB_H +# ifdef HAVE_STDLIB_H # include # endif #endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif -#if HAVE_STRINGS_H +#ifdef HAVE_STRINGS_H # include #endif -#if HAVE_INTTYPES_H +#ifdef HAVE_INTTYPES_H # include #endif -#if HAVE_STDINT_H +#ifdef HAVE_STDINT_H # include #endif -#if HAVE_UNISTD_H +#ifdef HAVE_UNISTD_H # include #endif" @@ -845,8 +860,8 @@ CXXFLAGS ac_ct_CXX LEX -LEXLIB LEX_OUTPUT_ROOT +LEXLIB FLEX YACC YFLAGS @@ -936,6 +951,7 @@ CC CFLAGS LDFLAGS +LIBS CPPFLAGS CPP CXX @@ -1061,10 +1077,10 @@ -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) @@ -1080,10 +1096,10 @@ -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ @@ -1277,19 +1293,19 @@ -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) @@ -1581,6 +1597,7 @@ CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory + LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor @@ -1660,7 +1677,7 @@ if $ac_init_version; then cat <<\_ACEOF llvm configure 2.2svn -generated by GNU Autoconf 2.60 +generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -1676,7 +1693,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by llvm $as_me 2.2svn, which was -generated by GNU Autoconf 2.60. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2410,7 +2427,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2450,7 +2467,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2507,7 +2524,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2548,7 +2565,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -2606,7 +2623,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2650,7 +2667,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2791,7 +2808,7 @@ # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. -for ac_file in $ac_files +for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in @@ -2819,6 +2836,12 @@ test "$ac_cv_exeext" = no && ac_cv_exeext= else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -2830,8 +2853,6 @@ fi ac_exeext=$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. @@ -3009,27 +3030,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -3084,27 +3088,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -3139,27 +3126,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 @@ -3195,27 +3165,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -3331,27 +3284,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 @@ -3441,17 +3377,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -3485,17 +3414,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -3560,17 +3482,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -3604,17 +3519,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -3669,7 +3577,7 @@ for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -3751,7 +3659,7 @@ for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -3847,27 +3755,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 @@ -4043,27 +3934,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -4105,7 +3979,8 @@ int main () { -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ + && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) bogus endian macros #endif @@ -4126,27 +4001,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -4181,27 +4039,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 @@ -4252,27 +4093,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi @@ -4402,7 +4226,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="${ac_build_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4440,7 +4264,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4479,7 +4303,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -4742,7 +4566,7 @@ fi case "$enableval" in - all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips" ;; + all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU" ;; host-only) case "$llvm_cv_target_arch" in x86) TARGETS_TO_BUILD="X86" ;; @@ -4753,6 +4577,7 @@ IA64) TARGETS_TO_BUILD="IA64" ;; ARM) TARGETS_TO_BUILD="ARM" ;; Mips) TARGETS_TO_BUILD="Mips" ;; + CellSPU|SPU) TARGETS_TO_BUILD="CellSPU" ;; *) { { echo "$as_me:$LINENO: error: Can not set target to build" >&5 echo "$as_me: error: Can not set target to build" >&2;} { (exit 1); exit 1; }; } ;; @@ -4768,6 +4593,7 @@ ia64) TARGETS_TO_BUILD="IA64 $TARGETS_TO_BUILD" ;; arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;; mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;; + spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;; *) { { echo "$as_me:$LINENO: error: Unrecognized target $a_target" >&5 echo "$as_me: error: Unrecognized target $a_target" >&2;} { (exit 1); exit 1; }; } ;; @@ -4954,17 +4780,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -4998,17 +4817,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -5073,17 +4885,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -5117,17 +4922,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -5184,7 +4982,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5228,7 +5026,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5346,27 +5144,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -5421,27 +5202,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -5476,27 +5240,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 @@ -5532,27 +5279,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -5668,27 +5398,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 @@ -5753,7 +5466,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5797,7 +5510,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5910,27 +5623,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -5985,27 +5681,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 @@ -6040,27 +5719,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 @@ -6096,27 +5758,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 @@ -6180,7 +5825,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LEX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6205,116 +5850,123 @@ done test -n "$LEX" || LEX=":" -if test -z "$LEXLIB" -then - { echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 -echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6; } -if test "${ac_cv_lib_fl_yywrap+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lfl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" +if test "x$LEX" != "x:"; then + cat >conftest.l <<_ACEOF +%% +a { ECHO; } +b { REJECT; } +c { yymore (); } +d { yyless (1); } +e { yyless (input () != 0); } +f { unput (yytext[0]); } +. { BEGIN INITIAL; } +%% +#ifdef YYTEXT_POINTER +extern char *yytext; #endif -char yywrap (); int -main () +main (void) { -return yywrap (); - ; - return 0; + return ! yylex () + ! yywrap (); } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" +{ (ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$LEX conftest.l") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in + (exit $ac_status); } +{ echo "$as_me:$LINENO: checking lex output file root" >&5 +echo $ECHO_N "checking lex output file root... $ECHO_C" >&6; } +if test "${ac_cv_prog_lex_root+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 +echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} + { (exit 1); exit 1; }; } +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 +echo "${ECHO_T}$ac_cv_prog_lex_root" >&6; } +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +if test -z "${LEXLIB+set}"; then + { echo "$as_me:$LINENO: checking lex library" >&5 +echo $ECHO_N "checking lex library... $ECHO_C" >&6; } +if test "${ac_cv_lib_lex+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_save_LIBS=$LIBS + ac_cv_lib_lex='none needed' + for ac_lib in '' -lfl -ll; do + LIBS="$ac_lib $ac_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_link") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_fl_yywrap=yes + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_lex=$ac_lib else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_lib_fl_yywrap=no + fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + test "$ac_cv_lib_lex" != 'none needed' && break + done + LIBS=$ac_save_LIBS + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_lex" >&5 +echo "${ECHO_T}$ac_cv_lib_lex" >&6; } + test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 -echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6; } -if test $ac_cv_lib_fl_yywrap = yes; then - LEXLIB="-lfl" -else - { echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 -echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6; } -if test "${ac_cv_lib_l_yywrap+set}" = set; then + + +{ echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 +echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6; } +if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ll $LIBS" + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +ac_save_LIBS=$LIBS +LIBS="$LEXLIB $ac_save_LIBS" cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char yywrap (); -int -main () -{ -return yywrap (); - ; - return 0; -} +#define YYTEXT_POINTER 1 +`cat $LEX_OUTPUT_ROOT.c` _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" @@ -6329,147 +5981,22 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_l_yywrap=yes + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_prog_lex_yytext_pointer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_lib_l_yywrap=no + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 -echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6; } -if test $ac_cv_lib_l_yywrap = yes; then - LEXLIB="-ll" -fi - -fi - -fi - -if test "x$LEX" != "x:"; then - { echo "$as_me:$LINENO: checking lex output file root" >&5 -echo $ECHO_N "checking lex output file root... $ECHO_C" >&6; } -if test "${ac_cv_prog_lex_root+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # The minimal lex program is just a single line: %%. But some broken lexes -# (Solaris, I think it was) want two %% lines, so accommodate them. -cat >conftest.l <<_ACEOF -%% -%% -_ACEOF -{ (ac_try="$LEX conftest.l" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$LEX conftest.l") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -if test -f lex.yy.c; then - ac_cv_prog_lex_root=lex.yy -elif test -f lexyy.c; then - ac_cv_prog_lex_root=lexyy -else - { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 -echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} - { (exit 1); exit 1; }; } -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 -echo "${ECHO_T}$ac_cv_prog_lex_root" >&6; } -rm -f conftest.l -LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root - -{ echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 -echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6; } -if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # POSIX says lex can declare yytext either as a pointer or an array; the -# default is implementation-dependent. Figure out which it is, since -# not all implementations provide the %pointer and %array declarations. -ac_cv_prog_lex_yytext_pointer=no -echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c -ac_save_LIBS=$LIBS -LIBS="$LIBS $LEXLIB" -cat >conftest.$ac_ext <<_ACEOF -`cat $LEX_OUTPUT_ROOT.c` -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_lex_yytext_pointer=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS -rm -f "${LEX_OUTPUT_ROOT}.c" fi { echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 @@ -6481,6 +6008,7 @@ _ACEOF fi +rm -f conftest.l $LEX_OUTPUT_ROOT.c fi @@ -6519,7 +6047,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_YACC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6666,7 +6194,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CMP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6707,7 +6235,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6748,7 +6276,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DATE="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6789,7 +6317,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6830,7 +6358,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6871,7 +6399,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6912,7 +6440,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6952,7 +6480,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6992,7 +6520,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7049,7 +6577,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7090,7 +6618,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7131,7 +6659,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7172,7 +6700,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_BINPWD="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7214,7 +6742,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GRAPHVIZ="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7270,7 +6798,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7328,7 +6856,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GV="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7387,7 +6915,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOTTY="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7445,7 +6973,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7529,7 +7057,7 @@ # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -7592,7 +7120,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_BZIP2="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7633,7 +7161,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7674,7 +7202,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7715,7 +7243,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7756,7 +7284,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_POD2HTML="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7797,7 +7325,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_POD2MAN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7838,7 +7366,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RUNTEST="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7912,7 +7440,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TCLSH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7969,7 +7497,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8010,7 +7538,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8051,7 +7579,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLOPT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8092,7 +7620,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLDEP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8157,27 +7685,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then llvm_cv_link_use_r=yes else echo "$as_me: failed program was:" >&5 @@ -8186,7 +7698,7 @@ llvm_cv_link_use_r=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$oldcflags" ac_ext=c @@ -8229,10 +7741,10 @@ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; - const charset x; + const charset cs; /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; + char const *const *pcpcc; + char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; @@ -8241,11 +7753,11 @@ an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; - ccp = &g + (g ? g-g : 0); + pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; @@ -8272,7 +7784,7 @@ const int foo = 10; if (!foo) return 0; } - return !x[0] && !zero.x; + return !cs[0] && !zero.x; #endif ; @@ -8292,27 +7804,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 @@ -8377,27 +7872,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -8470,27 +7948,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -8499,7 +7961,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -8570,27 +8032,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -8599,7 +8045,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -8662,27 +8108,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -8718,17 +8147,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -8798,9 +8220,7 @@ fi - - -if test x"${enable_ltdl_install-no}" != xno; then + if test x"${enable_ltdl_install-no}" != xno; then INSTALL_LTDL_TRUE= INSTALL_LTDL_FALSE='#' else @@ -8808,9 +8228,7 @@ INSTALL_LTDL_FALSE= fi - - -if test x"${enable_ltdl_convenience-no}" != xno; then + if test x"${enable_ltdl_convenience-no}" != xno; then CONVENIENCE_LTDL_TRUE= CONVENIENCE_LTDL_FALSE='#' else @@ -9822,27 +9240,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -9851,7 +9253,7 @@ ac_cv_func_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 @@ -9905,27 +9307,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -9934,7 +9320,7 @@ ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -9990,27 +9376,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -10019,7 +9389,7 @@ ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -10064,27 +9434,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDL 1 @@ -10136,27 +9490,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -10165,7 +9503,7 @@ ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -10221,27 +9559,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 @@ -10250,7 +9572,7 @@ ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -10327,27 +9649,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func__dyld_func_lookup=yes else echo "$as_me: failed program was:" >&5 @@ -10356,7 +9662,7 @@ ac_cv_func__dyld_func_lookup=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func__dyld_func_lookup" >&5 @@ -10378,7 +9684,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi @@ -10461,27 +9767,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -10490,7 +9780,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -10577,7 +9867,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -10862,17 +10135,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -10977,27 +10243,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_error_t=yes else echo "$as_me: failed program was:" >&5 @@ -11097,27 +10346,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11126,7 +10359,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11206,27 +10439,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -11262,17 +10478,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -11378,27 +10587,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -11434,17 +10626,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -11548,27 +10733,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -11604,17 +10772,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -11747,27 +10908,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11776,7 +10921,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11858,27 +11003,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11887,7 +11016,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11969,27 +11098,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11998,7 +11111,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12080,27 +11193,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -12109,7 +11206,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12192,27 +11289,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -12221,7 +11302,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12721,7 +11802,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 12724 "configure"' > conftest.$ac_ext + echo '#line 11805 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -12845,27 +11926,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then lt_cv_cc_needs_belf=yes else echo "$as_me: failed program was:" >&5 @@ -12874,7 +11939,7 @@ lt_cv_cc_needs_belf=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -12969,17 +12034,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -13013,17 +12071,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -13088,17 +12139,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -13132,17 +12176,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -13183,7 +12220,7 @@ ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test -n "$ac_tool_prefix"; then - for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn + for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 @@ -13201,7 +12238,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_F77="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13227,7 +12264,7 @@ fi if test -z "$F77"; then ac_ct_F77=$F77 - for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn + for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -13245,7 +12282,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_F77="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13352,27 +12389,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -13415,27 +12435,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_f77_g=yes else echo "$as_me: failed program was:" >&5 @@ -13890,7 +12893,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13930,7 +12933,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13986,7 +12989,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -14026,7 +13029,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -14082,7 +13085,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -14122,7 +13125,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -14439,11 +13442,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14442: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13445: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14446: \$? = $ac_status" >&5 + echo "$as_me:13449: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14707,11 +13710,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14710: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13713: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14714: \$? = $ac_status" >&5 + echo "$as_me:13717: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14811,11 +13814,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14814: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13817: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14818: \$? = $ac_status" >&5 + echo "$as_me:13821: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15291,27 +14294,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -15325,7 +14312,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -15366,27 +14353,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -15400,7 +14371,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -16648,27 +15619,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -16677,7 +15632,7 @@ ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -16759,27 +15714,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -16788,7 +15727,7 @@ ac_cv_func_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 @@ -16838,27 +15777,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -16867,7 +15790,7 @@ ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -16939,27 +15862,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -16968,7 +15875,7 @@ ac_cv_func_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 @@ -17018,27 +15925,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -17047,7 +15938,7 @@ ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -17098,27 +15989,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -17127,7 +16002,7 @@ ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -17178,27 +16053,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 @@ -17207,7 +16066,7 @@ ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -17263,7 +16122,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -18484,7 +17327,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -18526,27 +17369,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -18560,7 +17387,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -19731,11 +18558,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:19734: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18561: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:19738: \$? = $ac_status" >&5 + echo "$as_me:18565: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -19835,11 +18662,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:19838: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18665: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:19842: \$? = $ac_status" >&5 + echo "$as_me:18669: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21405,11 +20232,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21408: $lt_compile\"" >&5) + (eval echo "\"\$as_me:20235: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:21412: \$? = $ac_status" >&5 + echo "$as_me:20239: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -21509,11 +20336,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21512: $lt_compile\"" >&5) + (eval echo "\"\$as_me:20339: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:21516: \$? = $ac_status" >&5 + echo "$as_me:20343: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21979,27 +20806,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -22013,7 +20824,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -22044,27 +20855,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -22078,7 +20873,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -23744,11 +22539,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23747: $lt_compile\"" >&5) + (eval echo "\"\$as_me:22542: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:23751: \$? = $ac_status" >&5 + echo "$as_me:22546: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24012,11 +22807,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24015: $lt_compile\"" >&5) + (eval echo "\"\$as_me:22810: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:24019: \$? = $ac_status" >&5 + echo "$as_me:22814: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24116,11 +22911,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24119: $lt_compile\"" >&5) + (eval echo "\"\$as_me:22914: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:24123: \$? = $ac_status" >&5 + echo "$as_me:22918: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -24596,27 +23391,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -24630,7 +23409,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -24671,27 +23450,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -24705,7 +23468,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -26845,7 +25608,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LLVMGCC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -26885,7 +25648,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LLVMGXX="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -27013,27 +25776,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_elf_elf_begin=yes else echo "$as_me: failed program was:" >&5 @@ -27042,7 +25789,7 @@ ac_cv_lib_elf_elf_begin=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -27100,27 +25847,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_m_sin=yes else echo "$as_me: failed program was:" >&5 @@ -27129,7 +25860,7 @@ ac_cv_lib_m_sin=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -27182,27 +25913,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_imagehlp_main=yes else echo "$as_me: failed program was:" >&5 @@ -27211,7 +25926,7 @@ ac_cv_lib_imagehlp_main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -27263,27 +25978,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_psapi_main=yes else echo "$as_me: failed program was:" >&5 @@ -27292,7 +25991,7 @@ ac_cv_lib_psapi_main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -27357,27 +26056,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_lt_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 @@ -27386,7 +26069,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_lt_dlopen+set}" = set; then break @@ -27466,27 +26149,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 @@ -27495,7 +26162,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dlopen+set}" = set; then break @@ -27573,27 +26240,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_mallinfo=$ac_res else echo "$as_me: failed program was:" >&5 @@ -27602,7 +26253,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_mallinfo+set}" = set; then break @@ -27673,27 +26324,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 @@ -27702,7 +26337,7 @@ ac_cv_lib_pthread_pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -27765,27 +26400,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_pthread_mutex_lock=$ac_res else echo "$as_me: failed program was:" >&5 @@ -27794,7 +26413,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then break @@ -27875,27 +26494,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_udis86_ud_init=yes else echo "$as_me: failed program was:" >&5 @@ -27904,7 +26507,7 @@ ac_cv_lib_udis86_ud_init=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -27981,27 +26584,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -28074,27 +26660,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -28103,7 +26673,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -28174,27 +26744,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -28203,7 +26757,7 @@ fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -28268,27 +26822,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_mmap_anon=yes else echo "$as_me: failed program was:" >&5 @@ -28331,38 +26868,48 @@ #include #if defined S_ISBLK && defined S_IFDIR -# if S_ISBLK (S_IFDIR) -You lose. -# endif +extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; #endif #if defined S_ISBLK && defined S_IFCHR -# if S_ISBLK (S_IFCHR) -You lose. -# endif +extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; #endif #if defined S_ISLNK && defined S_IFREG -# if S_ISLNK (S_IFREG) -You lose. -# endif +extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; #endif #if defined S_ISSOCK && defined S_IFREG -# if S_ISSOCK (S_IFREG) -You lose. -# endif +extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; #endif _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "You lose" >/dev/null 2>&1; then - ac_cv_header_stat_broken=yes -else +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stat_broken=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stat_broken=yes fi -rm -f conftest* +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 echo "${ECHO_T}$ac_cv_header_stat_broken" >&6; } @@ -28411,27 +26958,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 @@ -28608,27 +27138,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 @@ -28686,27 +27199,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 @@ -28772,27 +27268,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -28828,17 +27307,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -28946,27 +27418,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -29002,17 +27457,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -29115,27 +27563,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -29171,17 +27602,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -29287,27 +27711,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -29343,17 +27750,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -29458,27 +27858,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -29514,17 +27897,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -29628,27 +28004,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -29684,17 +28043,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -29883,27 +28235,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 @@ -29963,27 +28298,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 @@ -30041,27 +28359,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_signal=int else echo "$as_me: failed program was:" >&5 @@ -30097,7 +28398,9 @@ int main () { -struct tm *tp; tp->tm_sec; +struct tm tm; + int *p = &tm.tm_sec; + return !p; ; return 0; } @@ -30115,27 +28418,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 @@ -30193,27 +28479,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_int64_t=yes else echo "$as_me: failed program was:" >&5 @@ -30276,27 +28545,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_uint64_t=yes else echo "$as_me: failed program was:" >&5 @@ -30354,27 +28606,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_u_int64_t=yes else echo "$as_me: failed program was:" >&5 @@ -30477,27 +28712,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -30506,7 +28725,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -30590,27 +28809,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -30619,7 +28822,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -30704,27 +28907,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -30733,7 +28920,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -30816,27 +29003,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -30845,7 +29016,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -30932,27 +29103,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -30961,7 +29116,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -31045,27 +29200,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -31074,7 +29213,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -31158,27 +29297,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -31187,7 +29310,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -31331,27 +29454,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_working_alloca_h=yes else echo "$as_me: failed program was:" >&5 @@ -31360,7 +29467,7 @@ ac_cv_working_alloca_h=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 @@ -31391,7 +29498,7 @@ # include # define alloca _alloca # else -# if HAVE_ALLOCA_H +# ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX @@ -31427,27 +29534,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func_alloca_works=yes else echo "$as_me: failed program was:" >&5 @@ -31456,7 +29547,7 @@ ac_cv_func_alloca_works=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 @@ -31576,27 +29667,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -31605,7 +29680,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -31742,27 +29817,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_rand48=yes else echo "$as_me: failed program was:" >&5 @@ -31830,27 +29888,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_namespaces=yes else echo "$as_me: failed program was:" >&5 @@ -31921,27 +29962,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_std_ext_hash_map=yes else echo "$as_me: failed program was:" >&5 @@ -32018,27 +30042,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_gnu_ext_hash_map=yes else echo "$as_me: failed program was:" >&5 @@ -32112,27 +30119,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_global_hash_map=yes else echo "$as_me: failed program was:" >&5 @@ -32209,27 +30199,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_std_ext_hash_set=yes else echo "$as_me: failed program was:" >&5 @@ -32306,27 +30279,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_gnu_ext_hash_set=yes else echo "$as_me: failed program was:" >&5 @@ -32400,27 +30356,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_global_hash_set=yes else echo "$as_me: failed program was:" >&5 @@ -32497,27 +30436,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_std_iterator=yes else echo "$as_me: failed program was:" >&5 @@ -32595,27 +30517,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_bi_iterator=yes else echo "$as_me: failed program was:" >&5 @@ -32693,27 +30598,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_cxx_have_fwd_iterator=yes else echo "$as_me: failed program was:" >&5 @@ -32788,27 +30676,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isnan_in_math_h=yes else echo "$as_me: failed program was:" >&5 @@ -32876,27 +30747,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isnan_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -32963,27 +30817,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_std_isnan_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -33051,27 +30888,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isinf_in_math_h=yes else echo "$as_me: failed program was:" >&5 @@ -33138,27 +30958,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isinf_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -33225,27 +31028,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_std_isinf_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -33312,27 +31098,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_finite_in_ieeefp_h=yes else echo "$as_me: failed program was:" >&5 @@ -33403,27 +31172,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -33459,17 +31211,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -33600,27 +31345,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -33629,7 +31358,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -33686,21 +31415,21 @@ #include #include -#if !STDC_HEADERS && !HAVE_STDLIB_H +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ -#if !HAVE_GETPAGESIZE +#ifndef HAVE_GETPAGESIZE /* Assume that all systems that can run configure have sys/param.h. */ -# if !HAVE_SYS_PARAM_H +# ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ -# if HAVE_SYS_PARAM_H +# ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE @@ -34023,27 +31752,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -34052,7 +31765,7 @@ eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -34459,7 +32172,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -34468,10 +32182,13 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -34695,19 +32412,28 @@ as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -34723,7 +32449,7 @@ # values after options handling. ac_log=" This file was extended by llvm $as_me 2.2svn, which was -generated by GNU Autoconf 2.60. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -34752,7 +32478,7 @@ Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit - -V, --version print version number, then exit + -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions @@ -34776,7 +32502,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ llvm config.status 2.2svn -configured by $0, generated by GNU Autoconf 2.60, +configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. @@ -35061,8 +32787,8 @@ CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim LEX!$LEX$ac_delim -LEXLIB!$LEXLIB$ac_delim LEX_OUTPUT_ROOT!$LEX_OUTPUT_ROOT$ac_delim +LEXLIB!$LEXLIB$ac_delim FLEX!$FLEX$ac_delim YACC!$YACC$ac_delim YFLAGS!$YFLAGS$ac_delim @@ -35695,7 +33421,12 @@ case $ac_arg in *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac - ac_sub_configure_args="$ac_arg $ac_sub_configure_args" + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue From isanbard at gmail.com Wed Dec 5 15:26:55 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 05 Dec 2007 21:26:55 -0000 Subject: [llvm-commits] [llvm] r44629 - /llvm/trunk/CREDITS.TXT Message-ID: <200712052126.lB5LQt0c020793@zion.cs.uiuc.edu> Author: void Date: Wed Dec 5 15:26:54 2007 New Revision: 44629 URL: http://llvm.org/viewvc/llvm-project?rev=44629&view=rev Log: Alphabetizing; I want to be the last in the file!!!! ;-) Modified: llvm/trunk/CREDITS.TXT Modified: llvm/trunk/CREDITS.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CREDITS.TXT?rev=44629&r1=44628&r2=44629&view=diff ============================================================================== --- llvm/trunk/CREDITS.TXT (original) +++ llvm/trunk/CREDITS.TXT Wed Dec 5 15:26:54 2007 @@ -202,6 +202,10 @@ E: wanderer at rsu.ru D: Test suite fixes for FreeBSD +N: Scott Michel +E: scottm at aero.org +D: Added STI Cell SPU backend. + N: Morten Ofstad E: morten at hue.no D: Visual C++ compatibility fixes @@ -257,7 +261,3 @@ D: Darwin exception handling D: MMX & SSSE3 instructions D: SPEC2006 support - -N: Scott Michel -E: scottm at aero.org -D: Added STI Cell SPU backend. From sabre at nondot.org Wed Dec 5 16:58:20 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 22:58:20 -0000 Subject: [llvm-commits] [llvm] r44637 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200712052258.lB5MwKFo026653@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 16:58:19 2007 New Revision: 44637 URL: http://llvm.org/viewvc/llvm-project?rev=44637&view=rev Log: add a note Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=44637&r1=44636&r2=44637&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Wed Dec 5 16:58:19 2007 @@ -1532,3 +1532,23 @@ ret This should just fldl directly from the input stack slot. + +//===---------------------------------------------------------------------===// + +This code: +int foo (int x) { return (x & 65535) | 255; } + +Should compile into: + +_foo: + movzwl 4(%esp), %eax + orb $-1, %al ;; 'orl 255' is also fine :) + ret + +instead of: +_foo: + movl $255, %eax + orl 4(%esp), %eax + andl $65535, %eax + ret + From sabre at nondot.org Wed Dec 5 17:05:06 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 23:05:06 -0000 Subject: [llvm-commits] [llvm] r44638 - /llvm/trunk/lib/Target/README.txt Message-ID: <200712052305.lB5N56w0027499@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 17:05:06 2007 New Revision: 44638 URL: http://llvm.org/viewvc/llvm-project?rev=44638&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=44638&r1=44637&r2=44638&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Wed Dec 5 17:05:06 2007 @@ -463,5 +463,42 @@ ret int %tmp3 } +//===---------------------------------------------------------------------===// +on this code: +unsigned array[4]; +unsigned foo(unsigned long x) { + return array[(x>>2)&3ul]; +} + +we should dag combine the left+right shift together. We currently get: + +_foo: + movl 4(%esp), %eax + shrl $2, %eax + andl $3, %eax + movl _array(,%eax,4), %eax + ret + +similar on ppc: + +_foo: + lis r2, ha16(_array) + srwi r3, r3, 2 + la r2, lo16(_array)(r2) + rlwinm r3, r3, 2, 28, 29 + lwzx r3, r2, r3 + blr + +similar on arm: + +_foo: + mov r3, #3 + and r3, r3, r0, lsr #2 + ldr r2, LCPI1_0 + ldr r0, [r2, +r3, lsl #2] + bx lr + +this is a trivial dag combine xform. +//===---------------------------------------------------------------------===// From sabre at nondot.org Wed Dec 5 17:39:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 23:39:58 -0000 Subject: [llvm-commits] [llvm] r44640 - in /llvm/trunk: include/llvm/ExecutionEngine/JIT.h include/llvm/ExecutionEngine/JITMemoryManager.h lib/ExecutionEngine/JIT/JITEmitter.cpp lib/ExecutionEngine/JIT/JITMemoryManager.cpp Message-ID: <200712052339.lB5NdwkT029998@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 17:39:57 2007 New Revision: 44640 URL: http://llvm.org/viewvc/llvm-project?rev=44640&view=rev Log: split the JIT memory management code out from the main JIT logic into its own JITMemoryManager interface. There is no functionality change with this patch. Added: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/JIT.h llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/JIT.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JIT.h?rev=44640&r1=44639&r2=44640&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/JIT.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/JIT.h Wed Dec 5 17:39:57 2007 @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EXECUTION_ENGINE_JIT_H -#define EXECUTION_ENGINE_JIT_H +#ifndef LLVM_EXECUTION_ENGINE_JIT_H +#define LLVM_EXECUTION_ENGINE_JIT_H #include "llvm/ExecutionEngine/ExecutionEngine.h" #include Added: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h?rev=44640&view=auto ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h (added) +++ llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Wed Dec 5 17:39:57 2007 @@ -0,0 +1,96 @@ +//===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- 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 the JITMemoryManagerInterface +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTION_ENGINE_JIT_H +#define LLVM_EXECUTION_ENGINE_JIT_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + class Function; + +/// JITMemoryManager - This interface is used by the JIT to allocate and manage +/// memory for the code generated by the JIT. This can be reimplemented by +/// clients that have a strong desire to control how the layout of JIT'd memory +/// works. +class JITMemoryManager { +protected: + bool HasGOT; +public: + JITMemoryManager() : HasGOT(false) {} + virtual ~JITMemoryManager(); + + /// CreateDefaultMemManager - This is used to create the default + /// JIT Memory Manager if the client does not provide one to the JIT. + static JITMemoryManager *CreateDefaultMemManager(); + + //===--------------------------------------------------------------------===// + // Global Offset Table Management + //===--------------------------------------------------------------------===// + + /// AllocateGOT - If the current table requires a Global Offset Table, this + /// method is invoked to allocate it. This method is required to set HasGOT + /// to true. + virtual void AllocateGOT() = 0; + + /// isManagingGOT - Return true if the AllocateGOT method is called. + /// + bool isManagingGOT() const { + return HasGOT; + } + + /// getGOTBase - If this is managing a Global Offset Table, this method should + /// return a pointer to its base. + virtual unsigned char *getGOTBase() const = 0; + + //===--------------------------------------------------------------------===// + // Main Allocation Functions + //===--------------------------------------------------------------------===// + + /// startFunctionBody - When we start JITing a function, the JIT calls this + /// method to allocate a block of free RWX memory, which returns a pointer to + /// it. The JIT doesn't know ahead of time how much space it will need to + /// emit the function, so it doesn't pass in the size. Instead, this method + /// is required to pass back a "valid size". The JIT will be careful to not + /// write more than the returned ActualSize bytes of memory. + virtual unsigned char *startFunctionBody(const Function *F, + uintptr_t &ActualSize) = 0; + + /// allocateStub - This method is called by the JIT to allocate space for a + /// function stub (used to handle limited branch displacements) while it is + /// JIT compiling a function. For example, if foo calls bar, and if bar + /// either needs to be lazily compiled or is a native function that exists too + /// far away from the call site to work, this method will be used to make a + /// thunk for it. The stub should be "close" to the current function body, + /// but should not be included in the 'actualsize' returned by + /// startFunctionBody. + virtual unsigned char *allocateStub(unsigned StubSize, unsigned Alignment) =0; + + + /// endFunctionBody - This method is called when the JIT is done codegen'ing + /// the specified function. At this point we know the size of the JIT + /// compiled function. This passes in FunctionStart (which was returned by + /// the startFunctionBody method) and FunctionEnd which is a pointer to the + /// actual end of the function. This method should mark the space allocated + /// and remember where it is in case the client wants to deallocate it. + virtual void endFunctionBody(const Function *F, unsigned char *FunctionStart, + unsigned char *FunctionEnd) = 0; + + /// deallocateMemForFunction - Free JIT memory for the specified function. + /// This is never called when the JIT is currently emitting a function. + virtual void deallocateMemForFunction(const Function *F) = 0; +}; + +} // end namespace llvm. + +#endif Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=44640&r1=44639&r2=44640&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Wed Dec 5 17:39:57 2007 @@ -22,7 +22,7 @@ #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineRelocation.h" -#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetJITInfo.h" #include "llvm/Target/TargetMachine.h" @@ -30,7 +30,6 @@ #include "llvm/Support/MutexGuard.h" #include "llvm/System/Disassembler.h" #include "llvm/ADT/Statistic.h" -#include "llvm/System/Memory.h" #include using namespace llvm; @@ -38,395 +37,6 @@ STATISTIC(NumRelos, "Number of relocations applied"); static JIT *TheJIT = 0; -//===----------------------------------------------------------------------===// -// JITMemoryManager code. -// -namespace { - /// MemoryRangeHeader - For a range of memory, this is the header that we put - /// on the block of memory. It is carefully crafted to be one word of memory. - /// Allocated blocks have just this header, free'd blocks have FreeRangeHeader - /// which starts with this. - struct FreeRangeHeader; - struct MemoryRangeHeader { - /// ThisAllocated - This is true if this block is currently allocated. If - /// not, this can be converted to a FreeRangeHeader. - unsigned ThisAllocated : 1; - - /// PrevAllocated - Keep track of whether the block immediately before us is - /// allocated. If not, the word immediately before this header is the size - /// of the previous block. - unsigned PrevAllocated : 1; - - /// BlockSize - This is the size in bytes of this memory block, - /// including this header. - uintptr_t BlockSize : (sizeof(intptr_t)*8 - 2); - - - /// getBlockAfter - Return the memory block immediately after this one. - /// - MemoryRangeHeader &getBlockAfter() const { - return *(MemoryRangeHeader*)((char*)this+BlockSize); - } - - /// getFreeBlockBefore - If the block before this one is free, return it, - /// otherwise return null. - FreeRangeHeader *getFreeBlockBefore() const { - if (PrevAllocated) return 0; - intptr_t PrevSize = ((intptr_t *)this)[-1]; - return (FreeRangeHeader*)((char*)this-PrevSize); - } - - /// FreeBlock - Turn an allocated block into a free block, adjusting - /// bits in the object headers, and adding an end of region memory block. - FreeRangeHeader *FreeBlock(FreeRangeHeader *FreeList); - - /// TrimAllocationToSize - If this allocated block is significantly larger - /// than NewSize, split it into two pieces (where the former is NewSize - /// bytes, including the header), and add the new block to the free list. - FreeRangeHeader *TrimAllocationToSize(FreeRangeHeader *FreeList, - uint64_t NewSize); - }; - - /// FreeRangeHeader - For a memory block that isn't already allocated, this - /// keeps track of the current block and has a pointer to the next free block. - /// Free blocks are kept on a circularly linked list. - struct FreeRangeHeader : public MemoryRangeHeader { - FreeRangeHeader *Prev; - FreeRangeHeader *Next; - - /// getMinBlockSize - Get the minimum size for a memory block. Blocks - /// smaller than this size cannot be created. - static unsigned getMinBlockSize() { - return sizeof(FreeRangeHeader)+sizeof(intptr_t); - } - - /// SetEndOfBlockSizeMarker - The word at the end of every free block is - /// known to be the size of the free block. Set it for this block. - void SetEndOfBlockSizeMarker() { - void *EndOfBlock = (char*)this + BlockSize; - ((intptr_t *)EndOfBlock)[-1] = BlockSize; - } - - FreeRangeHeader *RemoveFromFreeList() { - assert(Next->Prev == this && Prev->Next == this && "Freelist broken!"); - Next->Prev = Prev; - return Prev->Next = Next; - } - - void AddToFreeList(FreeRangeHeader *FreeList) { - Next = FreeList; - Prev = FreeList->Prev; - Prev->Next = this; - Next->Prev = this; - } - - /// GrowBlock - The block after this block just got deallocated. Merge it - /// into the current block. - void GrowBlock(uintptr_t NewSize); - - /// AllocateBlock - Mark this entire block allocated, updating freelists - /// etc. This returns a pointer to the circular free-list. - FreeRangeHeader *AllocateBlock(); - }; -} - - -/// AllocateBlock - Mark this entire block allocated, updating freelists -/// etc. This returns a pointer to the circular free-list. -FreeRangeHeader *FreeRangeHeader::AllocateBlock() { - assert(!ThisAllocated && !getBlockAfter().PrevAllocated && - "Cannot allocate an allocated block!"); - // Mark this block allocated. - ThisAllocated = 1; - getBlockAfter().PrevAllocated = 1; - - // Remove it from the free list. - return RemoveFromFreeList(); -} - -/// FreeBlock - Turn an allocated block into a free block, adjusting -/// bits in the object headers, and adding an end of region memory block. -/// If possible, coalesce this block with neighboring blocks. Return the -/// FreeRangeHeader to allocate from. -FreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) { - MemoryRangeHeader *FollowingBlock = &getBlockAfter(); - assert(ThisAllocated && "This block is already allocated!"); - assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); - - FreeRangeHeader *FreeListToReturn = FreeList; - - // If the block after this one is free, merge it into this block. - if (!FollowingBlock->ThisAllocated) { - FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; - // "FreeList" always needs to be a valid free block. If we're about to - // coalesce with it, update our notion of what the free list is. - if (&FollowingFreeBlock == FreeList) { - FreeList = FollowingFreeBlock.Next; - FreeListToReturn = 0; - assert(&FollowingFreeBlock != FreeList && "No tombstone block?"); - } - FollowingFreeBlock.RemoveFromFreeList(); - - // Include the following block into this one. - BlockSize += FollowingFreeBlock.BlockSize; - FollowingBlock = &FollowingFreeBlock.getBlockAfter(); - - // Tell the block after the block we are coalescing that this block is - // allocated. - FollowingBlock->PrevAllocated = 1; - } - - assert(FollowingBlock->ThisAllocated && "Missed coalescing?"); - - if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { - PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); - return FreeListToReturn ? FreeListToReturn : PrevFreeBlock; - } - - // Otherwise, mark this block free. - FreeRangeHeader &FreeBlock = *(FreeRangeHeader*)this; - FollowingBlock->PrevAllocated = 0; - FreeBlock.ThisAllocated = 0; - - // Link this into the linked list of free blocks. - FreeBlock.AddToFreeList(FreeList); - - // Add a marker at the end of the block, indicating the size of this free - // block. - FreeBlock.SetEndOfBlockSizeMarker(); - return FreeListToReturn ? FreeListToReturn : &FreeBlock; -} - -/// GrowBlock - The block after this block just got deallocated. Merge it -/// into the current block. -void FreeRangeHeader::GrowBlock(uintptr_t NewSize) { - assert(NewSize > BlockSize && "Not growing block?"); - BlockSize = NewSize; - SetEndOfBlockSizeMarker(); - getBlockAfter().PrevAllocated = 0; -} - -/// TrimAllocationToSize - If this allocated block is significantly larger -/// than NewSize, split it into two pieces (where the former is NewSize -/// bytes, including the header), and add the new block to the free list. -FreeRangeHeader *MemoryRangeHeader:: -TrimAllocationToSize(FreeRangeHeader *FreeList, uint64_t NewSize) { - assert(ThisAllocated && getBlockAfter().PrevAllocated && - "Cannot deallocate part of an allocated block!"); - - // Round up size for alignment of header. - unsigned HeaderAlign = __alignof(FreeRangeHeader); - NewSize = (NewSize+ (HeaderAlign-1)) & ~(HeaderAlign-1); - - // Size is now the size of the block we will remove from the start of the - // current block. - assert(NewSize <= BlockSize && - "Allocating more space from this block than exists!"); - - // If splitting this block will cause the remainder to be too small, do not - // split the block. - if (BlockSize <= NewSize+FreeRangeHeader::getMinBlockSize()) - return FreeList; - - // Otherwise, we splice the required number of bytes out of this block, form - // a new block immediately after it, then mark this block allocated. - MemoryRangeHeader &FormerNextBlock = getBlockAfter(); - - // Change the size of this block. - BlockSize = NewSize; - - // Get the new block we just sliced out and turn it into a free block. - FreeRangeHeader &NewNextBlock = (FreeRangeHeader &)getBlockAfter(); - NewNextBlock.BlockSize = (char*)&FormerNextBlock - (char*)&NewNextBlock; - NewNextBlock.ThisAllocated = 0; - NewNextBlock.PrevAllocated = 1; - NewNextBlock.SetEndOfBlockSizeMarker(); - FormerNextBlock.PrevAllocated = 0; - NewNextBlock.AddToFreeList(FreeList); - return &NewNextBlock; -} - - -namespace { - /// JITMemoryManager - Manage memory for the JIT code generation in a logical, - /// sane way. This splits a large block of MAP_NORESERVE'd memory into two - /// sections, one for function stubs, one for the functions themselves. We - /// have to do this because we may need to emit a function stub while in the - /// middle of emitting a function, and we don't know how large the function we - /// are emitting is. This never bothers to release the memory, because when - /// we are ready to destroy the JIT, the program exits. - class JITMemoryManager { - std::vector Blocks; // Memory blocks allocated by the JIT - FreeRangeHeader *FreeMemoryList; // Circular list of free blocks. - - // When emitting code into a memory block, this is the block. - MemoryRangeHeader *CurBlock; - - unsigned char *CurStubPtr, *StubBase; - unsigned char *GOTBase; // Target Specific reserved memory - - // Centralize memory block allocation. - sys::MemoryBlock getNewMemoryBlock(unsigned size); - - std::map FunctionBlocks; - public: - JITMemoryManager(bool useGOT); - ~JITMemoryManager(); - - inline unsigned char *allocateStub(unsigned StubSize, unsigned Alignment); - - /// startFunctionBody - When a function starts, allocate a block of free - /// executable memory, returning a pointer to it and its actual size. - unsigned char *startFunctionBody(uintptr_t &ActualSize) { - CurBlock = FreeMemoryList; - - // Allocate the entire memory block. - FreeMemoryList = FreeMemoryList->AllocateBlock(); - ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader); - return (unsigned char *)(CurBlock+1); - } - - /// endFunctionBody - The function F is now allocated, and takes the memory - /// in the range [FunctionStart,FunctionEnd). - void endFunctionBody(const Function *F, unsigned char *FunctionStart, - unsigned char *FunctionEnd) { - assert(FunctionEnd > FunctionStart); - assert(FunctionStart == (unsigned char *)(CurBlock+1) && - "Mismatched function start/end!"); - - uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock; - FunctionBlocks[F] = CurBlock; - - // Release the memory at the end of this block that isn't needed. - FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); - } - - unsigned char *getGOTBase() const { - return GOTBase; - } - bool isManagingGOT() const { - return GOTBase != NULL; - } - - /// deallocateMemForFunction - Deallocate all memory for the specified - /// function body. - void deallocateMemForFunction(const Function *F) { - std::map::iterator - I = FunctionBlocks.find(F); - if (I == FunctionBlocks.end()) return; - - // Find the block that is allocated for this function. - MemoryRangeHeader *MemRange = I->second; - assert(MemRange->ThisAllocated && "Block isn't allocated!"); - - // Fill the buffer with garbage! - DEBUG(memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange))); - - // Free the memory. - FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); - - // Finally, remove this entry from FunctionBlocks. - FunctionBlocks.erase(I); - } - }; -} - -JITMemoryManager::JITMemoryManager(bool useGOT) { - // Allocate a 16M block of memory for functions. - sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20); - - unsigned char *MemBase = reinterpret_cast(MemBlock.base()); - - // Allocate stubs backwards from the base, allocate functions forward - // from the base. - StubBase = MemBase; - CurStubPtr = MemBase + 512*1024; // Use 512k for stubs, working backwards. - - // We set up the memory chunk with 4 mem regions, like this: - // [ START - // [ Free #0 ] -> Large space to allocate functions from. - // [ Allocated #1 ] -> Tiny space to separate regions. - // [ Free #2 ] -> Tiny space so there is always at least 1 free block. - // [ Allocated #3 ] -> Tiny space to prevent looking past end of block. - // END ] - // - // The last three blocks are never deallocated or touched. - - // Add MemoryRangeHeader to the end of the memory region, indicating that - // the space after the block of memory is allocated. This is block #3. - MemoryRangeHeader *Mem3 = (MemoryRangeHeader*)(MemBase+MemBlock.size())-1; - Mem3->ThisAllocated = 1; - Mem3->PrevAllocated = 0; - Mem3->BlockSize = 0; - - /// Add a tiny free region so that the free list always has one entry. - FreeRangeHeader *Mem2 = - (FreeRangeHeader *)(((char*)Mem3)-FreeRangeHeader::getMinBlockSize()); - Mem2->ThisAllocated = 0; - Mem2->PrevAllocated = 1; - Mem2->BlockSize = FreeRangeHeader::getMinBlockSize(); - Mem2->SetEndOfBlockSizeMarker(); - Mem2->Prev = Mem2; // Mem2 *is* the free list for now. - Mem2->Next = Mem2; - - /// Add a tiny allocated region so that Mem2 is never coalesced away. - MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; - Mem1->ThisAllocated = 1; - Mem1->PrevAllocated = 0; - Mem1->BlockSize = (char*)Mem2 - (char*)Mem1; - - // Add a FreeRangeHeader to the start of the function body region, indicating - // that the space is free. Mark the previous block allocated so we never look - // at it. - FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr; - Mem0->ThisAllocated = 0; - Mem0->PrevAllocated = 1; - Mem0->BlockSize = (char*)Mem1-(char*)Mem0; - Mem0->SetEndOfBlockSizeMarker(); - Mem0->AddToFreeList(Mem2); - - // Start out with the freelist pointing to Mem0. - FreeMemoryList = Mem0; - - // Allocate the GOT. - GOTBase = NULL; - if (useGOT) GOTBase = new unsigned char[sizeof(void*) * 8192]; -} - -JITMemoryManager::~JITMemoryManager() { - for (unsigned i = 0, e = Blocks.size(); i != e; ++i) - sys::Memory::ReleaseRWX(Blocks[i]); - - delete[] GOTBase; - Blocks.clear(); -} - -unsigned char *JITMemoryManager::allocateStub(unsigned StubSize, - unsigned Alignment) { - CurStubPtr -= StubSize; - CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) & - ~(intptr_t)(Alignment-1)); - if (CurStubPtr < StubBase) { - // FIXME: allocate a new block - cerr << "JIT ran out of memory for function stubs!\n"; - abort(); - } - return CurStubPtr; -} - -sys::MemoryBlock JITMemoryManager::getNewMemoryBlock(unsigned size) { - // Allocate a new block close to the last one. - const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front(); - std::string ErrMsg; - sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld, &ErrMsg); - if (B.base() == 0) { - cerr << "Allocation failed when allocating new memory in the JIT\n"; - cerr << ErrMsg << "\n"; - abort(); - } - Blocks.push_back(B); - return B; -} //===----------------------------------------------------------------------===// // JIT lazy compilation code. @@ -504,9 +114,9 @@ } /// getGOTIndexForAddress - Return a new or existing index in the GOT for - /// and address. This function only manages slots, it does not manage the + /// an address. This function only manages slots, it does not manage the /// contents of the slots or the memory associated with the GOT. - unsigned getGOTIndexForAddr(void* addr); + unsigned getGOTIndexForAddr(void *addr); /// JITCompilerFn - This function is called to resolve a stub to a compiled /// address. If the LLVM Function corresponding to the stub has not yet @@ -597,7 +207,6 @@ revGOTMap[addr] = idx; DOUT << "Adding GOT entry " << idx << " for addr " << addr << "\n"; - // ((void**)MemMgr.getGOTBase())[idx] = addr; } return idx; } @@ -669,7 +278,7 @@ /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is /// used to output functions to memory for execution. class JITEmitter : public MachineCodeEmitter { - JITMemoryManager MemMgr; + JITMemoryManager *MemMgr; // When outputting a function stub in the context of some other function, we // save BufferBegin/BufferEnd/CurBufferPtr here. @@ -703,9 +312,15 @@ /// Resolver - This contains info about the currently resolved functions. JITResolver Resolver; public: - JITEmitter(JIT &jit) - : MemMgr(jit.getJITInfo().needsGOT()), Resolver(jit) { - if (MemMgr.isManagingGOT()) DOUT << "JIT is managing a GOT\n"; + JITEmitter(JIT &jit) : Resolver(jit) { + MemMgr = JITMemoryManager::CreateDefaultMemManager(); + if (jit.getJITInfo().needsGOT()) { + MemMgr->AllocateGOT(); + DOUT << "JIT is managing a GOT\n"; + } + } + ~JITEmitter() { + delete MemMgr; } JITResolver &getJITResolver() { return Resolver; } @@ -742,7 +357,7 @@ /// deallocateMemForFunction - Deallocate all memory for the specified /// function body. void deallocateMemForFunction(Function *F) { - MemMgr.deallocateMemForFunction(F); + MemMgr->deallocateMemForFunction(F); } private: void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); @@ -783,7 +398,8 @@ void JITEmitter::startFunction(MachineFunction &F) { uintptr_t ActualSize; - BufferBegin = CurBufferPtr = MemMgr.startFunctionBody(ActualSize); + BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), + ActualSize); BufferEnd = BufferBegin+ActualSize; // Ensure the constant pool/jump table info is at least 4-byte aligned. @@ -814,7 +430,7 @@ (unsigned char *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); unsigned char *FnEnd = CurBufferPtr; - MemMgr.endFunctionBody(F.getFunction(), BufferBegin, FnEnd); + MemMgr->endFunctionBody(F.getFunction(), BufferBegin, FnEnd); NumBytes += FnEnd-FnStart; if (!Relocations.empty()) { @@ -847,29 +463,29 @@ // if we are managing the GOT and the relocation wants an index, // give it one - if (MemMgr.isManagingGOT() && MR.isGOTRelative()) { + if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); MR.setGOTIndex(idx); - if (((void**)MemMgr.getGOTBase())[idx] != ResultPtr) { + if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { DOUT << "GOT was out of date for " << ResultPtr - << " pointing at " << ((void**)MemMgr.getGOTBase())[idx] + << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n"; - ((void**)MemMgr.getGOTBase())[idx] = ResultPtr; + ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; } } } TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], - Relocations.size(), MemMgr.getGOTBase()); + Relocations.size(), MemMgr->getGOTBase()); } // Update the GOT entry for F to point to the new code. - if (MemMgr.isManagingGOT()) { + if (MemMgr->isManagingGOT()) { unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); - if (((void**)MemMgr.getGOTBase())[idx] != (void*)BufferBegin) { + if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { DOUT << "GOT was out of date for " << (void*)BufferBegin - << " pointing at " << ((void**)MemMgr.getGOTBase())[idx] << "\n"; - ((void**)MemMgr.getGOTBase())[idx] = (void*)BufferBegin; + << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n"; + ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; } } @@ -976,7 +592,7 @@ SavedBufferEnd = BufferEnd; SavedCurBufferPtr = CurBufferPtr; - BufferBegin = CurBufferPtr = MemMgr.allocateStub(StubSize, Alignment); + BufferBegin = CurBufferPtr = MemMgr->allocateStub(StubSize, Alignment); BufferEnd = BufferBegin+StubSize+1; } Added: llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp?rev=44640&view=auto ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp (added) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp Wed Dec 5 17:39:57 2007 @@ -0,0 +1,427 @@ +//===-- JITMemoryManager.cpp - Memory Allocator for JIT'd code ------------===// +// +// 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 the DefaultJITMemoryManager class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/Support/Compiler.h" +#include "llvm/System/Memory.h" +#include +#include +using namespace llvm; + + +JITMemoryManager::~JITMemoryManager() {} + +//===----------------------------------------------------------------------===// +// Memory Block Implementation. +//===----------------------------------------------------------------------===// + +namespace { + /// MemoryRangeHeader - For a range of memory, this is the header that we put + /// on the block of memory. It is carefully crafted to be one word of memory. + /// Allocated blocks have just this header, free'd blocks have FreeRangeHeader + /// which starts with this. + struct FreeRangeHeader; + struct MemoryRangeHeader { + /// ThisAllocated - This is true if this block is currently allocated. If + /// not, this can be converted to a FreeRangeHeader. + unsigned ThisAllocated : 1; + + /// PrevAllocated - Keep track of whether the block immediately before us is + /// allocated. If not, the word immediately before this header is the size + /// of the previous block. + unsigned PrevAllocated : 1; + + /// BlockSize - This is the size in bytes of this memory block, + /// including this header. + uintptr_t BlockSize : (sizeof(intptr_t)*8 - 2); + + + /// getBlockAfter - Return the memory block immediately after this one. + /// + MemoryRangeHeader &getBlockAfter() const { + return *(MemoryRangeHeader*)((char*)this+BlockSize); + } + + /// getFreeBlockBefore - If the block before this one is free, return it, + /// otherwise return null. + FreeRangeHeader *getFreeBlockBefore() const { + if (PrevAllocated) return 0; + intptr_t PrevSize = ((intptr_t *)this)[-1]; + return (FreeRangeHeader*)((char*)this-PrevSize); + } + + /// FreeBlock - Turn an allocated block into a free block, adjusting + /// bits in the object headers, and adding an end of region memory block. + FreeRangeHeader *FreeBlock(FreeRangeHeader *FreeList); + + /// TrimAllocationToSize - If this allocated block is significantly larger + /// than NewSize, split it into two pieces (where the former is NewSize + /// bytes, including the header), and add the new block to the free list. + FreeRangeHeader *TrimAllocationToSize(FreeRangeHeader *FreeList, + uint64_t NewSize); + }; + + /// FreeRangeHeader - For a memory block that isn't already allocated, this + /// keeps track of the current block and has a pointer to the next free block. + /// Free blocks are kept on a circularly linked list. + struct FreeRangeHeader : public MemoryRangeHeader { + FreeRangeHeader *Prev; + FreeRangeHeader *Next; + + /// getMinBlockSize - Get the minimum size for a memory block. Blocks + /// smaller than this size cannot be created. + static unsigned getMinBlockSize() { + return sizeof(FreeRangeHeader)+sizeof(intptr_t); + } + + /// SetEndOfBlockSizeMarker - The word at the end of every free block is + /// known to be the size of the free block. Set it for this block. + void SetEndOfBlockSizeMarker() { + void *EndOfBlock = (char*)this + BlockSize; + ((intptr_t *)EndOfBlock)[-1] = BlockSize; + } + + FreeRangeHeader *RemoveFromFreeList() { + assert(Next->Prev == this && Prev->Next == this && "Freelist broken!"); + Next->Prev = Prev; + return Prev->Next = Next; + } + + void AddToFreeList(FreeRangeHeader *FreeList) { + Next = FreeList; + Prev = FreeList->Prev; + Prev->Next = this; + Next->Prev = this; + } + + /// GrowBlock - The block after this block just got deallocated. Merge it + /// into the current block. + void GrowBlock(uintptr_t NewSize); + + /// AllocateBlock - Mark this entire block allocated, updating freelists + /// etc. This returns a pointer to the circular free-list. + FreeRangeHeader *AllocateBlock(); + }; +} + + +/// AllocateBlock - Mark this entire block allocated, updating freelists +/// etc. This returns a pointer to the circular free-list. +FreeRangeHeader *FreeRangeHeader::AllocateBlock() { + assert(!ThisAllocated && !getBlockAfter().PrevAllocated && + "Cannot allocate an allocated block!"); + // Mark this block allocated. + ThisAllocated = 1; + getBlockAfter().PrevAllocated = 1; + + // Remove it from the free list. + return RemoveFromFreeList(); +} + +/// FreeBlock - Turn an allocated block into a free block, adjusting +/// bits in the object headers, and adding an end of region memory block. +/// If possible, coalesce this block with neighboring blocks. Return the +/// FreeRangeHeader to allocate from. +FreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) { + MemoryRangeHeader *FollowingBlock = &getBlockAfter(); + assert(ThisAllocated && "This block is already allocated!"); + assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); + + FreeRangeHeader *FreeListToReturn = FreeList; + + // If the block after this one is free, merge it into this block. + if (!FollowingBlock->ThisAllocated) { + FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; + // "FreeList" always needs to be a valid free block. If we're about to + // coalesce with it, update our notion of what the free list is. + if (&FollowingFreeBlock == FreeList) { + FreeList = FollowingFreeBlock.Next; + FreeListToReturn = 0; + assert(&FollowingFreeBlock != FreeList && "No tombstone block?"); + } + FollowingFreeBlock.RemoveFromFreeList(); + + // Include the following block into this one. + BlockSize += FollowingFreeBlock.BlockSize; + FollowingBlock = &FollowingFreeBlock.getBlockAfter(); + + // Tell the block after the block we are coalescing that this block is + // allocated. + FollowingBlock->PrevAllocated = 1; + } + + assert(FollowingBlock->ThisAllocated && "Missed coalescing?"); + + if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { + PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); + return FreeListToReturn ? FreeListToReturn : PrevFreeBlock; + } + + // Otherwise, mark this block free. + FreeRangeHeader &FreeBlock = *(FreeRangeHeader*)this; + FollowingBlock->PrevAllocated = 0; + FreeBlock.ThisAllocated = 0; + + // Link this into the linked list of free blocks. + FreeBlock.AddToFreeList(FreeList); + + // Add a marker at the end of the block, indicating the size of this free + // block. + FreeBlock.SetEndOfBlockSizeMarker(); + return FreeListToReturn ? FreeListToReturn : &FreeBlock; +} + +/// GrowBlock - The block after this block just got deallocated. Merge it +/// into the current block. +void FreeRangeHeader::GrowBlock(uintptr_t NewSize) { + assert(NewSize > BlockSize && "Not growing block?"); + BlockSize = NewSize; + SetEndOfBlockSizeMarker(); + getBlockAfter().PrevAllocated = 0; +} + +/// TrimAllocationToSize - If this allocated block is significantly larger +/// than NewSize, split it into two pieces (where the former is NewSize +/// bytes, including the header), and add the new block to the free list. +FreeRangeHeader *MemoryRangeHeader:: +TrimAllocationToSize(FreeRangeHeader *FreeList, uint64_t NewSize) { + assert(ThisAllocated && getBlockAfter().PrevAllocated && + "Cannot deallocate part of an allocated block!"); + + // Round up size for alignment of header. + unsigned HeaderAlign = __alignof(FreeRangeHeader); + NewSize = (NewSize+ (HeaderAlign-1)) & ~(HeaderAlign-1); + + // Size is now the size of the block we will remove from the start of the + // current block. + assert(NewSize <= BlockSize && + "Allocating more space from this block than exists!"); + + // If splitting this block will cause the remainder to be too small, do not + // split the block. + if (BlockSize <= NewSize+FreeRangeHeader::getMinBlockSize()) + return FreeList; + + // Otherwise, we splice the required number of bytes out of this block, form + // a new block immediately after it, then mark this block allocated. + MemoryRangeHeader &FormerNextBlock = getBlockAfter(); + + // Change the size of this block. + BlockSize = NewSize; + + // Get the new block we just sliced out and turn it into a free block. + FreeRangeHeader &NewNextBlock = (FreeRangeHeader &)getBlockAfter(); + NewNextBlock.BlockSize = (char*)&FormerNextBlock - (char*)&NewNextBlock; + NewNextBlock.ThisAllocated = 0; + NewNextBlock.PrevAllocated = 1; + NewNextBlock.SetEndOfBlockSizeMarker(); + FormerNextBlock.PrevAllocated = 0; + NewNextBlock.AddToFreeList(FreeList); + return &NewNextBlock; +} + +//===----------------------------------------------------------------------===// +// Memory Block Implementation. +//===----------------------------------------------------------------------===// + +namespace { + /// DefaultJITMemoryManager - Manage memory for the JIT code generation. + /// This splits a large block of MAP_NORESERVE'd memory into two + /// sections, one for function stubs, one for the functions themselves. We + /// have to do this because we may need to emit a function stub while in the + /// middle of emitting a function, and we don't know how large the function we + /// are emitting is. + class VISIBILITY_HIDDEN DefaultJITMemoryManager : public JITMemoryManager { + std::vector Blocks; // Memory blocks allocated by the JIT + FreeRangeHeader *FreeMemoryList; // Circular list of free blocks. + + // When emitting code into a memory block, this is the block. + MemoryRangeHeader *CurBlock; + + unsigned char *CurStubPtr, *StubBase; + unsigned char *GOTBase; // Target Specific reserved memory + + // Centralize memory block allocation. + sys::MemoryBlock getNewMemoryBlock(unsigned size); + + std::map FunctionBlocks; + public: + DefaultJITMemoryManager(); + ~DefaultJITMemoryManager(); + + void AllocateGOT(); + + unsigned char *allocateStub(unsigned StubSize, unsigned Alignment); + + /// startFunctionBody - When a function starts, allocate a block of free + /// executable memory, returning a pointer to it and its actual size. + unsigned char *startFunctionBody(const Function *F, uintptr_t &ActualSize) { + CurBlock = FreeMemoryList; + + // Allocate the entire memory block. + FreeMemoryList = FreeMemoryList->AllocateBlock(); + ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader); + return (unsigned char *)(CurBlock+1); + } + + /// endFunctionBody - The function F is now allocated, and takes the memory + /// in the range [FunctionStart,FunctionEnd). + void endFunctionBody(const Function *F, unsigned char *FunctionStart, + unsigned char *FunctionEnd) { + assert(FunctionEnd > FunctionStart); + assert(FunctionStart == (unsigned char *)(CurBlock+1) && + "Mismatched function start/end!"); + + uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock; + FunctionBlocks[F] = CurBlock; + + // Release the memory at the end of this block that isn't needed. + FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); + } + + unsigned char *getGOTBase() const { + return GOTBase; + } + + /// deallocateMemForFunction - Deallocate all memory for the specified + /// function body. + void deallocateMemForFunction(const Function *F) { + std::map::iterator + I = FunctionBlocks.find(F); + if (I == FunctionBlocks.end()) return; + + // Find the block that is allocated for this function. + MemoryRangeHeader *MemRange = I->second; + assert(MemRange->ThisAllocated && "Block isn't allocated!"); + + // Fill the buffer with garbage! +#ifndef NDEBUG + memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange)); +#endif + + // Free the memory. + FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); + + // Finally, remove this entry from FunctionBlocks. + FunctionBlocks.erase(I); + } + }; +} + +DefaultJITMemoryManager::DefaultJITMemoryManager() { + // Allocate a 16M block of memory for functions. + sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20); + + unsigned char *MemBase = reinterpret_cast(MemBlock.base()); + + // Allocate stubs backwards from the base, allocate functions forward + // from the base. + StubBase = MemBase; + CurStubPtr = MemBase + 512*1024; // Use 512k for stubs, working backwards. + + // We set up the memory chunk with 4 mem regions, like this: + // [ START + // [ Free #0 ] -> Large space to allocate functions from. + // [ Allocated #1 ] -> Tiny space to separate regions. + // [ Free #2 ] -> Tiny space so there is always at least 1 free block. + // [ Allocated #3 ] -> Tiny space to prevent looking past end of block. + // END ] + // + // The last three blocks are never deallocated or touched. + + // Add MemoryRangeHeader to the end of the memory region, indicating that + // the space after the block of memory is allocated. This is block #3. + MemoryRangeHeader *Mem3 = (MemoryRangeHeader*)(MemBase+MemBlock.size())-1; + Mem3->ThisAllocated = 1; + Mem3->PrevAllocated = 0; + Mem3->BlockSize = 0; + + /// Add a tiny free region so that the free list always has one entry. + FreeRangeHeader *Mem2 = + (FreeRangeHeader *)(((char*)Mem3)-FreeRangeHeader::getMinBlockSize()); + Mem2->ThisAllocated = 0; + Mem2->PrevAllocated = 1; + Mem2->BlockSize = FreeRangeHeader::getMinBlockSize(); + Mem2->SetEndOfBlockSizeMarker(); + Mem2->Prev = Mem2; // Mem2 *is* the free list for now. + Mem2->Next = Mem2; + + /// Add a tiny allocated region so that Mem2 is never coalesced away. + MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; + Mem1->ThisAllocated = 1; + Mem1->PrevAllocated = 0; + Mem1->BlockSize = (char*)Mem2 - (char*)Mem1; + + // Add a FreeRangeHeader to the start of the function body region, indicating + // that the space is free. Mark the previous block allocated so we never look + // at it. + FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr; + Mem0->ThisAllocated = 0; + Mem0->PrevAllocated = 1; + Mem0->BlockSize = (char*)Mem1-(char*)Mem0; + Mem0->SetEndOfBlockSizeMarker(); + Mem0->AddToFreeList(Mem2); + + // Start out with the freelist pointing to Mem0. + FreeMemoryList = Mem0; + + GOTBase = NULL; +} + +void DefaultJITMemoryManager::AllocateGOT() { + assert(GOTBase == 0 && "Cannot allocate the got multiple times"); + GOTBase = new unsigned char[sizeof(void*) * 8192]; + HasGOT = true; +} + + +DefaultJITMemoryManager::~DefaultJITMemoryManager() { + for (unsigned i = 0, e = Blocks.size(); i != e; ++i) + sys::Memory::ReleaseRWX(Blocks[i]); + + delete[] GOTBase; + Blocks.clear(); +} + +unsigned char *DefaultJITMemoryManager::allocateStub(unsigned StubSize, + unsigned Alignment) { + CurStubPtr -= StubSize; + CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) & + ~(intptr_t)(Alignment-1)); + if (CurStubPtr < StubBase) { + // FIXME: allocate a new block + fprintf(stderr, "JIT ran out of memory for function stubs!\n"); + abort(); + } + return CurStubPtr; +} + +sys::MemoryBlock DefaultJITMemoryManager::getNewMemoryBlock(unsigned size) { + // Allocate a new block close to the last one. + const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front(); + std::string ErrMsg; + sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld, &ErrMsg); + if (B.base() == 0) { + fprintf(stderr, + "Allocation failed when allocating new memory in the JIT\n%s\n", + ErrMsg.c_str()); + abort(); + } + Blocks.push_back(B); + return B; +} + + +JITMemoryManager *JITMemoryManager::CreateDefaultMemManager() { + return new DefaultJITMemoryManager(); +} From sabre at nondot.org Wed Dec 5 17:45:41 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 05 Dec 2007 23:45:41 -0000 Subject: [llvm-commits] [llvm] r44641 - /llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Message-ID: <200712052345.lB5Njflo030359@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 17:45:41 2007 New Revision: 44641 URL: http://llvm.org/viewvc/llvm-project?rev=44641&view=rev Log: improve header guard Modified: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Modified: llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h?rev=44641&r1=44640&r2=44641&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/JITMemoryManager.h Wed Dec 5 17:45:41 2007 @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_JIT_H -#define LLVM_EXECUTION_ENGINE_JIT_H +#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H +#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H #include "llvm/Support/DataTypes.h" From evan.cheng at apple.com Wed Dec 5 17:58:20 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 05 Dec 2007 23:58:20 -0000 Subject: [llvm-commits] [llvm] r44643 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200712052358.lB5NwKhR031055@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 17:58:20 2007 New Revision: 44643 URL: http://llvm.org/viewvc/llvm-project?rev=44643&view=rev Log: If both result of the {s|z}xt and its source are live out, rewrite all uses of the source with result of extension. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=44643&r1=44642&r2=44643&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Dec 5 17:58:20 2007 @@ -28,11 +28,17 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" using namespace llvm; +namespace { + cl::opt OptExtUses("optimize-ext-uses", + cl::init(false), cl::Hidden); +} + namespace { class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass { /// TLI - Keep a pointer of a TargetLowering to consult for determining @@ -52,6 +58,7 @@ bool OptimizeLoadStoreInst(Instruction *I, Value *Addr, const Type *AccessTy, DenseMap &SunkAddrs); + bool OptimizeExtUses(Instruction *I); }; } @@ -913,6 +920,61 @@ return true; } +bool CodeGenPrepare::OptimizeExtUses(Instruction *I) { + BasicBlock *DefBB = I->getParent(); + + // If both result of the {s|z}xt and its source are live out, rewrite all + // other uses of the source with result of extension. + Value *Src = I->getOperand(0); + if (Src->hasOneUse()) + return false; + + bool DefIsLiveOut = false; + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + Instruction *User = cast(*UI); + + // Figure out which BB this ext is used in. + BasicBlock *UserBB = User->getParent(); + if (UserBB == DefBB) continue; + DefIsLiveOut = true; + break; + } + if (!DefIsLiveOut) + return false; + + // InsertedTruncs - Only insert one trunc in each block once. + DenseMap InsertedTruncs; + + bool MadeChange = false; + for (Value::use_iterator UI = Src->use_begin(), E = Src->use_end(); + UI != E; ++UI) { + Use &TheUse = UI.getUse(); + Instruction *User = cast(*UI); + + // Figure out which BB this ext is used in. + BasicBlock *UserBB = User->getParent(); + if (UserBB == DefBB) continue; + + // Both src and def are live in this block. Rewrite the use. + Instruction *&InsertedTrunc = InsertedTruncs[UserBB]; + + if (!InsertedTrunc) { + BasicBlock::iterator InsertPt = UserBB->begin(); + while (isa(InsertPt)) ++InsertPt; + + InsertedTrunc = new TruncInst(I, Src->getType(), "", InsertPt); + } + + // Replace a use of the {s|z}ext source with a use of the result. + TheUse = InsertedTrunc; + + MadeChange = true; + } + + return MadeChange; +} + // In this pass we look for GEP and cast instructions that are used // across basic blocks and rewrite them to improve basic-block-at-a-time // selection. @@ -948,8 +1010,14 @@ if (isa(CI->getOperand(0))) continue; - if (TLI) - MadeChange |= OptimizeNoopCopyExpression(CI, *TLI); + bool Change = false; + if (TLI) { + Change = OptimizeNoopCopyExpression(CI, *TLI); + MadeChange |= Change; + } + + if (OptExtUses && !Change && (isa(I) || isa(I))) + MadeChange |= OptimizeExtUses(I); } else if (CmpInst *CI = dyn_cast(I)) { MadeChange |= OptimizeCmpExpression(CI); } else if (LoadInst *LI = dyn_cast(I)) { From evan.cheng at apple.com Wed Dec 5 18:01:57 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Dec 2007 00:01:57 -0000 Subject: [llvm-commits] [llvm] r44644 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/ARM/lsr-code-insertion.ll Message-ID: <200712060001.lB601vir031367@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 5 18:01:56 2007 New Revision: 44644 URL: http://llvm.org/viewvc/llvm-project?rev=44644&view=rev Log: Fix for PR1831: if all defs of an interval are re-materializable, then it's a preferred spill candiate. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=44644&r1=44643&r2=44644&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Wed Dec 5 18:01:56 2007 @@ -233,6 +233,11 @@ addIntervalsForSpills(const LiveInterval& i, const LoopInfo *loopInfo, VirtRegMap& vrm); + /// isReMaterializable - Returns true if every definition of MI of every + /// val# of the specified interval is re-materializable. Also returns true + /// by reference if all of the defs are load instructions. + bool isReMaterializable(const LiveInterval &li, bool &isLoad); + private: /// computeIntervals - Compute live intervals. void computeIntervals(); @@ -265,9 +270,10 @@ LiveInterval &interval, bool isAlias = false); /// isReMaterializable - Returns true if the definition MI of the specified - /// val# of the specified interval is re-materializable. + /// val# of the specified interval is re-materializable. Also returns true + /// by reference if the def is a load. bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo, - MachineInstr *MI); + MachineInstr *MI, bool &isLoad); /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from /// slot / to reg or any rematerialized load into ith operand of specified Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44644&r1=44643&r2=44644&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Dec 5 18:01:56 2007 @@ -607,12 +607,16 @@ /// isReMaterializable - Returns true if the definition MI of the specified /// val# of the specified interval is re-materializable. bool LiveIntervals::isReMaterializable(const LiveInterval &li, - const VNInfo *ValNo, MachineInstr *MI) { + const VNInfo *ValNo, MachineInstr *MI, + bool &isLoad) { if (DisableReMat) return false; - if (tii_->isTriviallyReMaterializable(MI)) + isLoad = false; + if (tii_->isTriviallyReMaterializable(MI)) { + isLoad = MI->getInstrDescriptor()->Flags & M_LOAD_FLAG; return true; + } int FrameIdx = 0; if (!tii_->isLoadFromStackSlot(MI, FrameIdx) || @@ -621,6 +625,7 @@ // This is a load from fixed stack slot. It can be rematerialized unless it's // re-defined by a two-address instruction. + isLoad = true; for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end(); i != e; ++i) { const VNInfo *VNI = *i; @@ -631,8 +636,32 @@ continue; // Dead val#. MachineInstr *DefMI = (DefIdx == ~0u) ? NULL : getInstructionFromIndex(DefIdx); - if (DefMI && DefMI->isRegReDefinedByTwoAddr(li.reg)) + if (DefMI && DefMI->isRegReDefinedByTwoAddr(li.reg)) { + isLoad = false; + return false; + } + } + return true; +} + +/// isReMaterializable - Returns true if every definition of MI of every +/// val# of the specified interval is re-materializable. +bool LiveIntervals::isReMaterializable(const LiveInterval &li, bool &isLoad) { + isLoad = false; + for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end(); + i != e; ++i) { + const VNInfo *VNI = *i; + unsigned DefIdx = VNI->def; + if (DefIdx == ~1U) + continue; // Dead val#. + // Is the def for the val# rematerializable? + if (DefIdx == ~0u) + return false; + MachineInstr *ReMatDefMI = getInstructionFromIndex(DefIdx); + bool DefIsLoad = false; + if (!ReMatDefMI || !isReMaterializable(li, VNI, ReMatDefMI, DefIsLoad)) return false; + isLoad |= DefIsLoad; } return true; } @@ -1225,7 +1254,8 @@ // Is the def for the val# rematerializable? MachineInstr *ReMatDefMI = (DefIdx == ~0u) ? 0 : getInstructionFromIndex(DefIdx); - if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI)) { + bool dummy; + if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI, dummy)) { // Remember how to remat the def of this val#. ReMatOrigDefs[VN] = ReMatDefMI; // Original def may be modified so we have to make a copy here. vrm must Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=44644&r1=44643&r2=44644&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Dec 5 18:01:56 2007 @@ -1485,6 +1485,20 @@ // it and hope it will be easier to allocate for this li. if (isZeroLengthInterval(&LI)) LI.weight = HUGE_VALF; + else { + bool isLoad = false; + if (li_->isReMaterializable(LI, isLoad)) { + // If all of the definitions of the interval are re-materializable, + // it is a preferred candidate for spilling. If non of the defs are + // loads, then it's potentially very cheap to re-materialize. + // FIXME: this gets much more complicated once we support non-trivial + // re-materialization. + if (isLoad) + LI.weight *= 0.9F; + else + LI.weight *= 0.5F; + } + } // Slightly prefer live interval that has been assigned a preferred reg. if (LI.preference) Modified: llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll?rev=44644&r1=44643&r2=44644&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll (original) +++ llvm/trunk/test/CodeGen/ARM/lsr-code-insertion.ll Wed Dec 5 18:01:56 2007 @@ -1,4 +1,5 @@ -; RUN: llvm-as < %s | llc -stats |& grep {40.*Number of machine instrs printed} +; RUN: llvm-as < %s | llc -stats |& grep {39.*Number of machine instrs printed} +; RUN: llvm-as < %s | llc -stats |& grep {.*Number of re-materialization} ; This test really wants to check that the resultant "cond_true" block only ; has a single store in it, and that cond_true55 only has code to materialize ; the constant and do a store. We do *not* want something like this: @@ -7,7 +8,6 @@ ; add r8, r0, r6 ; str r10, [r8, #+4] ; -; XFAIL: * target triple = "arm-apple-darwin8" define void @foo(i32* %mc, i32* %mpp, i32* %ip, i32* %dpp, i32* %tpmm, i32 %M, i32* %tpim, i32* %tpdm, i32* %bp, i32* %ms, i32 %xmb) { From clattner at apple.com Wed Dec 5 18:08:10 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 5 Dec 2007 16:08:10 -0800 Subject: [llvm-commits] [llvm] r44643 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <200712052358.lB5NwKhR031055@zion.cs.uiuc.edu> References: <200712052358.lB5NwKhR031055@zion.cs.uiuc.edu> Message-ID: On Dec 5, 2007, at 3:58 PM, Evan Cheng wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=44643&view=rev > Log: > If both result of the {s|z}xt and its source are live out, rewrite > all uses of the source with result of extension. I assume this is experimental, right? What sort of case does it fix? Testcase please :) -Chris > Modified: > llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ > Scalar/CodeGenPrepare.cpp?rev=44643&r1=44642&r2=44643&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Dec 5 > 17:58:20 2007 > @@ -28,11 +28,17 @@ > #include "llvm/Transforms/Utils/Local.h" > #include "llvm/ADT/DenseMap.h" > #include "llvm/ADT/SmallSet.h" > -#include "llvm/Support/Debug.h" > +#include "llvm/Support/CommandLine.h" > #include "llvm/Support/Compiler.h" > +#include "llvm/Support/Debug.h" > #include "llvm/Support/GetElementPtrTypeIterator.h" > using namespace llvm; > > +namespace { > + cl::opt OptExtUses("optimize-ext-uses", > + cl::init(false), cl::Hidden); > +} > + > namespace { > class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass { > /// TLI - Keep a pointer of a TargetLowering to consult for > determining > @@ -52,6 +58,7 @@ > bool OptimizeLoadStoreInst(Instruction *I, Value *Addr, > const Type *AccessTy, > DenseMap &SunkAddrs); > + bool OptimizeExtUses(Instruction *I); > }; > } > > @@ -913,6 +920,61 @@ > return true; > } > > +bool CodeGenPrepare::OptimizeExtUses(Instruction *I) { > + BasicBlock *DefBB = I->getParent(); > + > + // If both result of the {s|z}xt and its source are live out, > rewrite all > + // other uses of the source with result of extension. > + Value *Src = I->getOperand(0); > + if (Src->hasOneUse()) > + return false; > + > + bool DefIsLiveOut = false; > + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); > + UI != E; ++UI) { > + Instruction *User = cast(*UI); > + > + // Figure out which BB this ext is used in. > + BasicBlock *UserBB = User->getParent(); > + if (UserBB == DefBB) continue; > + DefIsLiveOut = true; > + break; > + } > + if (!DefIsLiveOut) > + return false; > + > + // InsertedTruncs - Only insert one trunc in each block once. > + DenseMap InsertedTruncs; > + > + bool MadeChange = false; > + for (Value::use_iterator UI = Src->use_begin(), E = Src->use_end(); > + UI != E; ++UI) { > + Use &TheUse = UI.getUse(); > + Instruction *User = cast(*UI); > + > + // Figure out which BB this ext is used in. > + BasicBlock *UserBB = User->getParent(); > + if (UserBB == DefBB) continue; > + > + // Both src and def are live in this block. Rewrite the use. > + Instruction *&InsertedTrunc = InsertedTruncs[UserBB]; > + > + if (!InsertedTrunc) { > + BasicBlock::iterator InsertPt = UserBB->begin(); > + while (isa(InsertPt)) ++InsertPt; > + > + InsertedTrunc = new TruncInst(I, Src->getType(), "", InsertPt); > + } > + > + // Replace a use of the {s|z}ext source with a use of the result. > + TheUse = InsertedTrunc; > + > + MadeChange = true; > + } > + > + return MadeChange; > +} > + > // In this pass we look for GEP and cast instructions that are used > // across basic blocks and rewrite them to improve basic-block-at- > a-time > // selection. > @@ -948,8 +1010,14 @@ > if (isa(CI->getOperand(0))) > continue; > > - if (TLI) > - MadeChange |= OptimizeNoopCopyExpression(CI, *TLI); > + bool Change = false; > + if (TLI) { > + Change = OptimizeNoopCopyExpression(CI, *TLI); > + MadeChange |= Change; > + } > + > + if (OptExtUses && !Change && (isa(I) || > isa(I))) > + MadeChange |= OptimizeExtUses(I); > } else if (CmpInst *CI = dyn_cast(I)) { > MadeChange |= OptimizeCmpExpression(CI); > } else if (LoadInst *LI = dyn_cast(I)) { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Dec 5 19:05:53 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 01:05:53 -0000 Subject: [llvm-commits] [llvm] r44645 - /llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll Message-ID: <200712060105.lB615rUt002378@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 19:05:52 2007 New Revision: 44645 URL: http://llvm.org/viewvc/llvm-project?rev=44645&view=rev Log: fix this when run on non x86 hosts. Modified: llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll Modified: llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll?rev=44645&r1=44644&r2=44645&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll Wed Dec 5 19:05:52 2007 @@ -1,6 +1,6 @@ -; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep pxor | count 1 -; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep xorps | count 1 -; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep pcmpeqd | count 2 +; RUN: llvm-as < %s | llc -relocation-model=static -march=x86 -mcpu=yonah | grep pxor | count 1 +; RUN: llvm-as < %s | llc -relocation-model=static -march=x86 -mcpu=yonah | grep xorps | count 1 +; RUN: llvm-as < %s | llc -relocation-model=static -march=x86 -mcpu=yonah | grep pcmpeqd | count 2 @M1 = external global <1 x i64> @M2 = external global <2 x i32> From sabre at nondot.org Wed Dec 5 19:08:10 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 01:08:10 -0000 Subject: [llvm-commits] [llvm] r44646 - in /llvm/trunk: include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/Interpreter/Interpreter.cpp lib/ExecutionEngine/Interpreter/Interpreter.h lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JIT.h lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200712060108.lB618AiV002632@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 19:08:09 2007 New Revision: 44646 URL: http://llvm.org/viewvc/llvm-project?rev=44646&view=rev Log: simplify creation of the interpreter, make ExecutionEngine ctor protected, delete one ExecutionEngine ctor, minor cleanup. Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.h llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Wed Dec 5 19:08:09 2007 @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EXECUTION_ENGINE_H -#define EXECUTION_ENGINE_H +#ifndef LLVM_EXECUTION_ENGINE_H +#define LLVM_EXECUTION_ENGINE_H #include #include @@ -34,6 +34,7 @@ class TargetData; class Type; class MutexGuard; +class JITMemoryManager; class ExecutionEngineState { private: @@ -90,18 +91,36 @@ /// any of those classes. sys::Mutex lock; // Used to make this class and subclasses thread-safe - ExecutionEngine(ModuleProvider *P); - ExecutionEngine(Module *M); - virtual ~ExecutionEngine(); + //===----------------------------------------------------------------------===// + // ExecutionEngine Startup + //===----------------------------------------------------------------------===// - const TargetData *getTargetData() const { return TD; } + virtual ~ExecutionEngine(); + /// create - This is the factory method for creating an execution engine which + /// is appropriate for the current machine. This takes ownership of the + /// module provider. + static ExecutionEngine *create(ModuleProvider *MP, + bool ForceInterpreter = false, + std::string *ErrorStr = 0); + + /// create - This is the factory method for creating an execution engine which + /// is appropriate for the current machine. This takes ownership of the + /// module. + static ExecutionEngine *create(Module *M); + + /// addModuleProvider - Add a ModuleProvider to the list of modules that we /// can JIT from. Note that this takes ownership of the ModuleProvider: when /// the ExecutionEngine is destroyed, it destroys the MP as well. void addModuleProvider(ModuleProvider *P) { Modules.push_back(P); } + + //===----------------------------------------------------------------------===// + + const TargetData *getTargetData() const { return TD; } + /// removeModuleProvider - Remove a ModuleProvider from the list of modules. /// Release module from ModuleProvider. @@ -112,18 +131,6 @@ /// general code. Function *FindFunctionNamed(const char *FnName); - /// create - This is the factory method for creating an execution engine which - /// is appropriate for the current machine. This takes ownership of the - /// module provider. - static ExecutionEngine *create(ModuleProvider *MP, - bool ForceInterpreter = false, - std::string *ErrorStr = 0); - - /// create - This is the factory method for creating an execution engine which - /// is appropriate for the current machine. This takes ownership of the - /// module. - static ExecutionEngine *create(Module *M); - /// runFunction - Execute the specified function with the specified arguments, /// and return the result. /// @@ -233,6 +240,8 @@ } protected: + ExecutionEngine(ModuleProvider *P); + void emitGlobals(); // EmitGlobalVariable - This method emits the specified global variable to the Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Wed Dec 5 19:08:09 2007 @@ -39,12 +39,6 @@ assert(P && "ModuleProvider is null?"); } -ExecutionEngine::ExecutionEngine(Module *M) : LazyFunctionCreator(0) { - LazyCompilationDisabled = false; - assert(M && "Module is null?"); - Modules.push_back(new ExistingModuleProvider(M)); -} - ExecutionEngine::~ExecutionEngine() { clearAllGlobalMappings(); for (unsigned i = 0, e = Modules.size(); i != e; ++i) Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp Wed Dec 5 19:08:09 2007 @@ -33,26 +33,18 @@ /// ExecutionEngine *Interpreter::create(ModuleProvider *MP, std::string* ErrStr) { // Tell this ModuleProvide to materialize and release the module - Module *M = MP->releaseModule(ErrStr); - if (!M) + if (!MP->materializeModule(ErrStr)) // We got an error, just return 0 return 0; - // This is a bit nasty, but the ExecutionEngine won't be able to delete the - // module due to use/def issues if we don't delete this MP here. Below we - // construct a new Interpreter with the Module we just got. This creates a - // new ExistingModuleProvider in the EE instance. Consequently, MP is left - // dangling and it contains references into the module which cause problems - // when the module is deleted via the ExistingModuleProvide via EE. - delete MP; - - return new Interpreter(M); + return new Interpreter(MP); } //===----------------------------------------------------------------------===// // Interpreter ctor - Initialize stuff // -Interpreter::Interpreter(Module *M) : ExecutionEngine(M), TD(M) { +Interpreter::Interpreter(ModuleProvider *M) + : ExecutionEngine(M), TD(M->getModule()) { memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped)); setTargetData(&TD); Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h Wed Dec 5 19:08:09 2007 @@ -94,7 +94,7 @@ std::vector AtExitHandlers; public: - explicit Interpreter(Module *M); + explicit Interpreter(ModuleProvider *M); ~Interpreter(); /// runAtExitHandlers - Run any functions registered by the program's calls to Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Wed Dec 5 19:08:09 2007 @@ -66,7 +66,7 @@ setTargetData(TM.getTargetData()); // Initialize MCE - MCE = createEmitter(*this); + MCE = createEmitter(*this, 0); // Add target data MutexGuard locked(lock); Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Wed Dec 5 19:08:09 2007 @@ -121,7 +121,7 @@ /// getCodeEmitter - Return the code emitter this JIT is emitting into. MachineCodeEmitter *getCodeEmitter() const { return MCE; } private: - static MachineCodeEmitter *createEmitter(JIT &J); + static MachineCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM); void runJITOnFunction (Function *F); }; Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=44646&r1=44645&r2=44646&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Wed Dec 5 19:08:09 2007 @@ -312,8 +312,8 @@ /// Resolver - This contains info about the currently resolved functions. JITResolver Resolver; public: - JITEmitter(JIT &jit) : Resolver(jit) { - MemMgr = JITMemoryManager::CreateDefaultMemManager(); + JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit) { + MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); if (jit.getJITInfo().needsGOT()) { MemMgr->AllocateGOT(); DOUT << "JIT is managing a GOT\n"; @@ -637,8 +637,8 @@ // Public interface to this file //===----------------------------------------------------------------------===// -MachineCodeEmitter *JIT::createEmitter(JIT &jit) { - return new JITEmitter(jit); +MachineCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM) { + return new JITEmitter(jit, JMM); } // getPointerToNamedFunction - This function is used as a global wrapper to From sabre at nondot.org Wed Dec 5 19:34:05 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 01:34:05 -0000 Subject: [llvm-commits] [llvm] r44647 - in /llvm/trunk: include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JIT.h lib/ExecutionEngine/JIT/TargetSelect.cpp Message-ID: <200712060134.lB61Y5Xf004082@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 19:34:04 2007 New Revision: 44647 URL: http://llvm.org/viewvc/llvm-project?rev=44647&view=rev Log: add a new ExecutionEngine::createJIT which can be used if you only want to create a JIT. This lets you specify JIT-specific configuration items like the JITMemoryManager to use. Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.h llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=44647&r1=44646&r2=44647&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Wed Dec 5 19:34:04 2007 @@ -108,6 +108,14 @@ /// is appropriate for the current machine. This takes ownership of the /// module. static ExecutionEngine *create(Module *M); + + /// createJIT - This is the factory method for creating a JIT for the current + /// machine, it does not fall back to the interpreter. This takes ownership + /// of the ModuleProvider and JITMemoryManager if successful. + static ExecutionEngine *createJIT(ModuleProvider *MP, + std::string *ErrorStr = 0, + JITMemoryManager *JMM = 0); + /// addModuleProvider - Add a ModuleProvider to the list of modules that we Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=44647&r1=44646&r2=44647&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Wed Dec 5 19:34:04 2007 @@ -61,12 +61,29 @@ } } -JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji) +/// createJIT - This is the factory method for creating a JIT for the current +/// machine, it does not fall back to the interpreter. This takes ownership +/// of the module provider. +ExecutionEngine *ExecutionEngine::createJIT(ModuleProvider *MP, + std::string *ErrorStr, + JITMemoryManager *JMM) { + ExecutionEngine *EE = JIT::createJIT(MP, ErrorStr, JMM); + if (!EE) return 0; + + + // Make sure we can resolve symbols in the program as well. The zero arg + // to the function tells DynamicLibrary to load the program, not a library. + sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr); + return EE; +} + +JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji, + JITMemoryManager *JMM) : ExecutionEngine(MP), TM(tm), TJI(tji), jitstate(MP) { setTargetData(TM.getTargetData()); // Initialize MCE - MCE = createEmitter(*this, 0); + MCE = createEmitter(*this, JMM); // Add target data MutexGuard locked(lock); Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=44647&r1=44646&r2=44647&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Wed Dec 5 19:34:04 2007 @@ -56,7 +56,8 @@ JITState jitstate; - JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji); + JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji, + JITMemoryManager *JMM); public: ~JIT(); @@ -71,7 +72,9 @@ /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// - static ExecutionEngine *create(ModuleProvider *MP, std::string* = 0); + static ExecutionEngine *create(ModuleProvider *MP, std::string *Err) { + return createJIT(MP, Err, 0); + } /// run - Start execution with the specified function and arguments. /// @@ -120,6 +123,10 @@ /// getCodeEmitter - Return the code emitter this JIT is emitting into. MachineCodeEmitter *getCodeEmitter() const { return MCE; } + + static ExecutionEngine *createJIT(ModuleProvider *MP, std::string *Err, + JITMemoryManager *JMM); + private: static MachineCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM); void runJITOnFunction (Function *F); Modified: llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp?rev=44647&r1=44646&r2=44647&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp Wed Dec 5 19:34:04 2007 @@ -36,10 +36,11 @@ cl::desc("Target specific attributes (-mattr=help for details)"), cl::value_desc("a1,+a2,-a3,...")); -/// create - Create an return a new JIT compiler if there is one available -/// for the current target. Otherwise, return null. +/// createInternal - Create an return a new JIT compiler if there is one +/// available for the current target. Otherwise, return null. /// -ExecutionEngine *JIT::create(ModuleProvider *MP, std::string *ErrorStr) { +ExecutionEngine *JIT::createJIT(ModuleProvider *MP, std::string *ErrorStr, + JITMemoryManager *JMM) { const TargetMachineRegistry::entry *TheArch = MArch; if (TheArch == 0) { std::string Error; @@ -71,7 +72,7 @@ // If the target supports JIT code generation, return a new JIT now. if (TargetJITInfo *TJ = Target->getJITInfo()) - return new JIT(MP, *Target, *TJ); + return new JIT(MP, *Target, *TJ, JMM); if (ErrorStr) *ErrorStr = "target does not support JIT code generation"; From dalej at apple.com Wed Dec 5 19:43:50 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 06 Dec 2007 01:43:50 -0000 Subject: [llvm-commits] [llvm] r44649 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200712060143.lB61hpQI004504@zion.cs.uiuc.edu> Author: johannes Date: Wed Dec 5 19:43:46 2007 New Revision: 44649 URL: http://llvm.org/viewvc/llvm-project?rev=44649&view=rev Log: Fix PR1842. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=44649&r1=44648&r2=44649&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 5 19:43:46 2007 @@ -2396,6 +2396,10 @@ MVT::ValueType VT = N->getValueType(0); MVT::ValueType VT0 = N0.getValueType(); + + // Some targets have SETCC types bigger than 1 bit, but do not set all the + // bits to 1; identified by getSetCCResultContents. Watch out for these. + // fold select C, X, X -> X if (N1 == N2) return N1; @@ -2420,14 +2424,22 @@ return DAG.getNode(ISD::TRUNCATE, VT, XORNode); } // fold select C, 0, X -> ~C & X - if (VT == VT0 && N1C && N1C->isNullValue()) { - SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); + if (VT == VT0 && N1C && N1C->isNullValue() && + (N0.Val->getOpcode()!=ISD::SETCC || VT==MVT::i1 || + TLI.getSetCCResultContents()== + TargetLowering::ZeroOrNegativeOneSetCCResult)) { + SDOperand XORNode; + XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(~0UL, VT)); AddToWorkList(XORNode.Val); return DAG.getNode(ISD::AND, VT, XORNode, N2); } // fold select C, X, 1 -> ~C | X - if (VT == VT0 && N2C && N2C->getValue() == 1) { - SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); + if (VT == VT0 && N2C && N2C->getValue() == 1 && + (N0.Val->getOpcode()!=ISD::SETCC || VT==MVT::i1 || + TLI.getSetCCResultContents()== + TargetLowering::ZeroOrNegativeOneSetCCResult)) { + SDOperand XORNode; + XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(~0UL, VT)); AddToWorkList(XORNode.Val); return DAG.getNode(ISD::OR, VT, XORNode, N1); } From sabre at nondot.org Wed Dec 5 19:59:47 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 01:59:47 -0000 Subject: [llvm-commits] [llvm] r44650 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200712060159.lB61xlWg005154@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 19:59:46 2007 New Revision: 44650 URL: http://llvm.org/viewvc/llvm-project?rev=44650&view=rev Log: move some ashr-specific code out of commonShiftTransforms into visitAShr. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=44650&r1=44649&r2=44650&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Dec 5 19:59:46 2007 @@ -5872,7 +5872,22 @@ } Instruction *InstCombiner::visitAShr(BinaryOperator &I) { - return commonShiftTransforms(I); + if (Instruction *R = commonShiftTransforms(I)) + return R; + + Value *Op0 = I.getOperand(0); + + // ashr int -1, X = -1 (for any arithmetic shift rights of ~0) + if (ConstantInt *CSI = dyn_cast(Op0)) + if (CSI->isAllOnesValue()) + return ReplaceInstUsesWith(I, CSI); + + // See if we can turn a signed shr into an unsigned shr. + if (MaskedValueIsZero(Op0, + APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()))) + return BinaryOperator::createLShr(Op0, I.getOperand(1)); + + return 0; } Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) { @@ -5898,26 +5913,12 @@ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); } - // ashr int -1, X = -1 (for any arithmetic shift rights of ~0) - if (I.getOpcode() == Instruction::AShr) - if (ConstantInt *CSI = dyn_cast(Op0)) - if (CSI->isAllOnesValue()) - return ReplaceInstUsesWith(I, CSI); - // Try to fold constant and into select arguments. if (isa(Op0)) if (SelectInst *SI = dyn_cast(Op1)) if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; - // See if we can turn a signed shr into an unsigned shr. - if (I.isArithmeticShift()) { - if (MaskedValueIsZero(Op0, - APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()))) { - return BinaryOperator::createLShr(Op0, Op1, I.getName()); - } - } - if (ConstantInt *CUI = dyn_cast(Op1)) if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I)) return Res; From cfr at adobe.com Wed Dec 5 20:03:01 2007 From: cfr at adobe.com (Chuck Rose III) Date: Thu, 06 Dec 2007 02:03:01 -0000 Subject: [llvm-commits] [llvm] r44651 - in /llvm/trunk: lib/ExecutionEngine/JIT/JITMemoryManager.cpp win32/ExecutionEngine/ExecutionEngine.vcproj Message-ID: <200712060203.lB6232PE005276@zion.cs.uiuc.edu> Author: cfr Date: Wed Dec 5 20:03:01 2007 New Revision: 44651 URL: http://llvm.org/viewvc/llvm-project?rev=44651&view=rev Log: Adjust VStudio files to add JITMemoryManager files + include from same. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp llvm/trunk/win32/ExecutionEngine/ExecutionEngine.vcproj Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp?rev=44651&r1=44650&r2=44651&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp Wed Dec 5 20:03:01 2007 @@ -16,6 +16,7 @@ #include "llvm/System/Memory.h" #include #include +#include using namespace llvm; Modified: llvm/trunk/win32/ExecutionEngine/ExecutionEngine.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/ExecutionEngine/ExecutionEngine.vcproj?rev=44651&r1=44650&r2=44651&view=diff ============================================================================== --- llvm/trunk/win32/ExecutionEngine/ExecutionEngine.vcproj (original) +++ llvm/trunk/win32/ExecutionEngine/ExecutionEngine.vcproj Wed Dec 5 20:03:01 2007 @@ -335,6 +335,10 @@ > + + @@ -343,6 +347,14 @@ > + + + + From dpatel at apple.com Wed Dec 5 21:13:39 2007 From: dpatel at apple.com (Devang Patel) Date: Thu, 06 Dec 2007 03:13:39 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r44652 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200712060313.lB63DdJa008824@zion.cs.uiuc.edu> Author: dpatel Date: Wed Dec 5 21:13:37 2007 New Revision: 44652 URL: http://llvm.org/viewvc/llvm-project?rev=44652&view=rev Log: Fix thin build. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=44652&r1=44651&r2=44652&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Wed Dec 5 21:13:37 2007 @@ -155,7 +155,7 @@ # LLVM LOCAL begin if [ "$ENABLE_LLVM" == true ]; then - CONFIGFLAGS="$CONFIGFLAGS --enable-llvm=/usr/local" + CONFIGFLAGS="$CONFIGFLAGS --enable-llvm=$LLVMCORE_PATH" fi # LLVM LOCAL end @@ -372,7 +372,7 @@ $DIR/dst-*-$t/$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-gcc || exit 1 # APPLE LOCAL LLVM build_gcc bug with non-/usr $DEST_ROOT lipo -output .$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-llvm-g++-$MAJ_VERS -create \ - $DIR/dst-*-$t/$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-g++ || exit 1 + $DIR/dst-*-$t/$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-llvm-g++ || exit 1 done # lib From sabre at nondot.org Wed Dec 5 23:53:44 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 05:53:44 -0000 Subject: [llvm-commits] [llvm] r44654 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200712060553.lB65rivt016277@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 5 23:53:43 2007 New Revision: 44654 URL: http://llvm.org/viewvc/llvm-project?rev=44654&view=rev Log: implement the rest of the functionality from SelectionDAGLegalize::ScalarizeVectorOp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44654&r1=44653&r2=44654&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Wed Dec 5 23:53:43 2007 @@ -209,8 +209,9 @@ SDOperand ScalarizeRes_BinOp(SDNode *N); SDOperand ScalarizeRes_UnaryOp(SDNode *N); SDOperand ScalarizeRes_FPOWI(SDNode *N); - SDOperand ScalarizeRes_BUILD_VECTOR(SDNode *N); - SDOperand ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N); + SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N); + SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N); + SDOperand ScalarizeRes_SELECT(SDNode *N); // Operand Promotion. bool PromoteOperand(SDNode *N, unsigned OperandNo); @@ -1655,10 +1656,13 @@ case ISD::FABS: case ISD::FSQRT: case ISD::FSIN: - case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; - case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; - case ISD::BUILD_VECTOR: R = ScalarizeRes_BUILD_VECTOR(N); break; - case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break; + case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; + case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; + case ISD::BUILD_VECTOR: R = N->getOperand(0); break; + case ISD::INSERT_VECTOR_ELT: R = N->getOperand(1); break; + case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break; + case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break; + case ISD::SELECT: R = ScalarizeRes_SELECT(N); break; } // If R is null, the sub-method took care of registering the resul. @@ -1698,12 +1702,22 @@ return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); } -SDOperand DAGTypeLegalizer::ScalarizeRes_BUILD_VECTOR(SDNode *N) { - return N->getOperand(0); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) { - return N->getOperand(1); // Returning the inserted scalar element. +SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) { + // Figure out if the scalar is the LHS or RHS and return it. + SDOperand EltNum = N->getOperand(2).getOperand(0); + unsigned Op = cast(EltNum)->getValue() != 0; + return GetScalarizedOp(N->getOperand(Op)); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) { + MVT::ValueType NewVT = MVT::getVectorElementType(N->getValueType(0)); + return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) { + SDOperand LHS = GetScalarizedOp(N->getOperand(1)); + return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS, + GetScalarizedOp(N->getOperand(2))); } From sabre at nondot.org Thu Dec 6 00:25:05 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 06:25:05 -0000 Subject: [llvm-commits] [llvm] r44655 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200712060625.lB66P5ML017838@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 6 00:25:04 2007 New Revision: 44655 URL: http://llvm.org/viewvc/llvm-project?rev=44655&view=rev Log: simplify some code. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=44655&r1=44654&r2=44655&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Dec 6 00:25:04 2007 @@ -6082,9 +6082,8 @@ // the constant which would cause it to be modified for this // operation. // - if (isValid && !isLeftShift && I.getOpcode() == Instruction::AShr) { + if (isValid && I.getOpcode() == Instruction::AShr) isValid = Op0C->getValue()[TypeBits-1] == highBitSet; - } if (isValid) { Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, Op1); From sabre at nondot.org Thu Dec 6 01:33:36 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 07:33:36 -0000 Subject: [llvm-commits] [llvm] r44656 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/Target/README.txt test/CodeGen/X86/shift-combine.ll Message-ID: <200712060733.lB67Xa9V020694@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 6 01:33:36 2007 New Revision: 44656 URL: http://llvm.org/viewvc/llvm-project?rev=44656&view=rev Log: implement a readme entry, compiling the code into: _foo: movl $12, %eax andl 4(%esp), %eax movl _array(%eax), %eax ret instead of: _foo: movl 4(%esp), %eax shrl $2, %eax andl $3, %eax movl _array(,%eax,4), %eax ret As it turns out, this triggers all the time, in a wide variety of situations, for example, I see diffs like this in various programs: - movl 8(%eax), %eax - shll $2, %eax - andl $1020, %eax - movl (%esi,%eax), %eax + movzbl 8(%eax), %eax + movl (%esi,%eax,4), %eax - shll $2, %edx - andl $1020, %edx - movl (%edi,%edx), %edx + andl $255, %edx + movl (%edi,%edx,4), %edx Unfortunately, I also see stuff like this, which can be fixed in the X86 backend: - andl $85, %ebx - addl _bit_count(,%ebx,4), %ebp + shll $2, %ebx + andl $340, %ebx + addl _bit_count(%ebx), %ebp Added: llvm/trunk/test/CodeGen/X86/shift-combine.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=44656&r1=44655&r2=44656&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Dec 6 01:33:36 2007 @@ -9,22 +9,6 @@ // // This pass combines dag nodes to form fewer, simpler DAG nodes. It can be run // both before and after the DAG is legalized. -// -// FIXME: Missing folds -// sdiv, udiv, srem, urem (X, const) where X is an integer can be expanded into -// a sequence of multiplies, shifts, and adds. This should be controlled by -// some kind of hint from the target that int div is expensive. -// various folds of mulh[s,u] by constants such as -1, powers of 2, etc. -// -// FIXME: select C, pow2, pow2 -> something smart -// FIXME: trunc(select X, Y, Z) -> select X, trunc(Y), trunc(Z) -// FIXME: Dead stores -> nuke -// FIXME: shr X, (and Y,31) -> shr X, Y (TRICKY!) -// FIXME: mul (x, const) -> shifts + adds -// FIXME: undef values -// FIXME: divide by zero is currently left unfolded. do we want to turn this -// into an undef? -// FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false // //===----------------------------------------------------------------------===// @@ -280,6 +264,8 @@ SDOperand XformToShuffleWithZero(SDNode *N); SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS); + SDOperand visitShiftByConstant(SDNode *N, unsigned Amt); + bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS); SDOperand SimplifyBinOpWithSameOpcodeHands(SDNode *N); SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2); @@ -2145,6 +2131,64 @@ return SDOperand(); } +/// visitShiftByConstant - Handle transforms common to the three shifts, when +/// the shift amount is a constant. +SDOperand DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { + SDNode *LHS = N->getOperand(0).Val; + if (!LHS->hasOneUse()) return SDOperand(); + + // We want to pull some binops through shifts, so that we have (and (shift)) + // instead of (shift (and)), likewise for add, or, xor, etc. This sort of + // thing happens with address calculations, so it's important to canonicalize + // it. + bool HighBitSet = false; // Can we transform this if the high bit is set? + + switch (LHS->getOpcode()) { + default: return SDOperand(); + case ISD::OR: + case ISD::XOR: + HighBitSet = false; // We can only transform sra if the high bit is clear. + break; + case ISD::AND: + HighBitSet = true; // We can only transform sra if the high bit is set. + break; + case ISD::ADD: + if (N->getOpcode() != ISD::SHL) + return SDOperand(); // only shl(add) not sr[al](add). + HighBitSet = false; // We can only transform sra if the high bit is clear. + break; + } + + // We require the RHS of the binop to be a constant as well. + ConstantSDNode *BinOpCst = dyn_cast(LHS->getOperand(1)); + if (!BinOpCst) return SDOperand(); + + MVT::ValueType VT = N->getValueType(0); + + // If this is a signed shift right, and the high bit is modified + // by the logical operation, do not perform the transformation. + // The highBitSet boolean indicates the value of the high bit of + // the constant which would cause it to be modified for this + // operation. + if (N->getOpcode() == ISD::SRA) { + uint64_t BinOpRHSSign = BinOpCst->getValue() >> MVT::getSizeInBits(VT)-1; + if ((bool)BinOpRHSSign != HighBitSet) + return SDOperand(); + } + + // Fold the constants, shifting the binop RHS by the shift amount. + SDOperand NewRHS = DAG.getNode(N->getOpcode(), N->getValueType(0), + LHS->getOperand(1), N->getOperand(1)); + + // Create the new shift. + SDOperand NewShift = DAG.getNode(N->getOpcode(), VT, LHS->getOperand(0), + N->getOperand(1)); + + // Create the new binop. + return DAG.getNode(LHS->getOpcode(), VT, NewShift, NewRHS); +} + + SDOperand DAGCombiner::visitSHL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); @@ -2199,7 +2243,8 @@ if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) return DAG.getNode(ISD::AND, VT, N0.getOperand(0), DAG.getConstant(~0ULL << N1C->getValue(), VT)); - return SDOperand(); + + return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDOperand(); } SDOperand DAGCombiner::visitSRA(SDNode *N) { @@ -2259,7 +2304,8 @@ // If the sign bit is known to be zero, switch this to a SRL. if (DAG.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT))) return DAG.getNode(ISD::SRL, VT, N0, N1); - return SDOperand(); + + return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDOperand(); } SDOperand DAGCombiner::visitSRL(SDNode *N) { @@ -2353,7 +2399,7 @@ if (N1C && SimplifyDemandedBits(SDOperand(N, 0))) return SDOperand(N, 0); - return SDOperand(); + return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDOperand(); } SDOperand DAGCombiner::visitCTLZ(SDNode *N) { Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=44656&r1=44655&r2=44656&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Dec 6 01:33:36 2007 @@ -464,41 +464,3 @@ } //===---------------------------------------------------------------------===// -on this code: - -unsigned array[4]; -unsigned foo(unsigned long x) { - return array[(x>>2)&3ul]; -} - -we should dag combine the left+right shift together. We currently get: - -_foo: - movl 4(%esp), %eax - shrl $2, %eax - andl $3, %eax - movl _array(,%eax,4), %eax - ret - -similar on ppc: - -_foo: - lis r2, ha16(_array) - srwi r3, r3, 2 - la r2, lo16(_array)(r2) - rlwinm r3, r3, 2, 28, 29 - lwzx r3, r2, r3 - blr - -similar on arm: - -_foo: - mov r3, #3 - and r3, r3, r0, lsr #2 - ldr r2, LCPI1_0 - ldr r0, [r2, +r3, lsl #2] - bx lr - -this is a trivial dag combine xform. - -//===---------------------------------------------------------------------===// Added: llvm/trunk/test/CodeGen/X86/shift-combine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-combine.ll?rev=44656&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/shift-combine.ll (added) +++ llvm/trunk/test/CodeGen/X86/shift-combine.ll Thu Dec 6 01:33:36 2007 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc | not grep shrl + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i686-apple-darwin8" + at array = weak global [4 x i32] zeroinitializer ; <[4 x i32]*> [#uses=1] + +define i32 @foo(i32 %x) { +entry: + %tmp2 = lshr i32 %x, 2 ; [#uses=1] + %tmp3 = and i32 %tmp2, 3 ; [#uses=1] + %tmp4 = getelementptr [4 x i32]* @array, i32 0, i32 %tmp3 ; [#uses=1] + %tmp5 = load i32* %tmp4, align 4 ; [#uses=1] + ret i32 %tmp5 +} + From sabre at nondot.org Thu Dec 6 01:44:34 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 07:44:34 -0000 Subject: [llvm-commits] [llvm] r44657 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/shift-combine.ll Message-ID: <200712060744.lB67iYv4021256@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 6 01:44:31 2007 New Revision: 44657 URL: http://llvm.org/viewvc/llvm-project?rev=44657&view=rev Log: Actually, disable this code for now. More analysis and improvements to the X86 backend are needed before this should be enabled by default. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/shift-combine.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=44657&r1=44656&r2=44657&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Dec 6 01:44:31 2007 @@ -2134,6 +2134,12 @@ /// visitShiftByConstant - Handle transforms common to the three shifts, when /// the shift amount is a constant. SDOperand DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { + // FIXME: disable this for now. This pessimizes some common cases like: + // + //void foo(int *X, int i) { X[i & 1235] = 1; } + //int bar(int *X, int i) { return X[i & 255]; } + return SDOperand(); + SDNode *LHS = N->getOperand(0).Val; if (!LHS->hasOneUse()) return SDOperand(); Modified: llvm/trunk/test/CodeGen/X86/shift-combine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-combine.ll?rev=44657&r1=44656&r2=44657&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/shift-combine.ll (original) +++ llvm/trunk/test/CodeGen/X86/shift-combine.ll Thu Dec 6 01:44:31 2007 @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | llc | not grep shrl +; XFAIL: * target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i686-apple-darwin8" From sabre at nondot.org Thu Dec 6 01:48:02 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 06 Dec 2007 07:48:02 -0000 Subject: [llvm-commits] [llvm] r44658 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/shift-combine.ll Message-ID: <200712060748.lB67m3b3021415@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 6 01:47:55 2007 New Revision: 44658 URL: http://llvm.org/viewvc/llvm-project?rev=44658&view=rev Log: third time around: instead of disabling this completely, only disable it if we don't know it will be obviously profitable. Still fixme, but less so. :) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/shift-combine.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=44658&r1=44657&r2=44658&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Dec 6 01:47:55 2007 @@ -2134,12 +2134,6 @@ /// visitShiftByConstant - Handle transforms common to the three shifts, when /// the shift amount is a constant. SDOperand DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { - // FIXME: disable this for now. This pessimizes some common cases like: - // - //void foo(int *X, int i) { X[i & 1235] = 1; } - //int bar(int *X, int i) { return X[i & 255]; } - return SDOperand(); - SDNode *LHS = N->getOperand(0).Val; if (!LHS->hasOneUse()) return SDOperand(); @@ -2169,6 +2163,19 @@ ConstantSDNode *BinOpCst = dyn_cast(LHS->getOperand(1)); if (!BinOpCst) return SDOperand(); + + // FIXME: disable this for unless the input to the binop is a shift by a + // constant. If it is not a shift, it pessimizes some common cases like: + // + //void foo(int *X, int i) { X[i & 1235] = 1; } + //int bar(int *X, int i) { return X[i & 255]; } + SDNode *BinOpLHSVal = LHS->getOperand(0).Val; + if ((BinOpLHSVal->getOpcode() != ISD::SHL && + BinOpLHSVal->getOpcode() != ISD::SRA && + BinOpLHSVal->getOpcode() != ISD::SRL) || + !isa(BinOpLHSVal->getOperand(1))) + return SDOperand(); + MVT::ValueType VT = N->getValueType(0); // If this is a signed shift right, and the high bit is modified Modified: llvm/trunk/test/CodeGen/X86/shift-combine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-combine.ll?rev=44658&r1=44657&r2=44658&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/shift-combine.ll (original) +++ llvm/trunk/test/CodeGen/X86/shift-combine.ll Thu Dec 6 01:47:55 2007 @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | llc | not grep shrl -; XFAIL: * target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i686-apple-darwin8" From baldrick at free.fr Thu Dec 6 02:10:52 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 06 Dec 2007 08:10:52 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r44659 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200712060810.lB68Aqmh022379@zion.cs.uiuc.edu> Author: baldrick Date: Thu Dec 6 02:10:52 2007 New Revision: 44659 URL: http://llvm.org/viewvc/llvm-project?rev=44659&view=rev Log: Inspect the nounwind attribute rather than using the special fact that intrinsics cannot throw. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=44659&r1=44658&r2=44659&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Dec 6 02:10:52 2007 @@ -2307,36 +2307,36 @@ /// result, otherwise store it in DestLoc. Value *TreeToLLVM::EmitCallOf(Value *Callee, tree exp, const MemRef *DestLoc, const ParamAttrsList *PAL) { + if (!PAL && isa(Callee)) + PAL = cast(Callee)->getParamAttrs(); + // Determine if we need to generate an invoke instruction (instead of a simple // call) and if so, what the exception destination will be. BasicBlock *LandingPad = 0; - bool NoUnwind = false; - - // Do not turn intrinsic calls into invokes. - if (!isa(Callee) || !cast(Callee)->getIntrinsicID()) { - // Do not turn no-throw calls into invokes; mark them as "nounwind". - NoUnwind = !tree_could_throw_p(exp); - - if (!NoUnwind) { - int RegionNo = lookup_stmt_eh_region(exp); - - // Is the call contained in an exception handling region? - if (RegionNo > 0) { - // Are there any exception handlers for this region? - if (can_throw_internal_1(RegionNo, false)) { - // Turn the call into an invoke. - LandingPads.grow(RegionNo); - BasicBlock *&ThisPad = LandingPads[RegionNo]; - - // Create a landing pad if one didn't exist already. - if (!ThisPad) - ThisPad = new BasicBlock("lpad"); + bool NoUnwind = + (PAL && PAL->paramHasAttr(0, ParamAttr::NoUnwind)) || + !tree_could_throw_p(exp); + + // Do not turn nounwind calls into invokes. + if (!NoUnwind) { + int RegionNo = lookup_stmt_eh_region(exp); + + // Is the call contained in an exception handling region? + if (RegionNo > 0) { + // Are there any exception handlers for this region? + if (can_throw_internal_1(RegionNo, false)) { + // Turn the call into an invoke. + LandingPads.grow(RegionNo); + BasicBlock *&ThisPad = LandingPads[RegionNo]; + + // Create a landing pad if one didn't exist already. + if (!ThisPad) + ThisPad = new BasicBlock("lpad"); - LandingPad = ThisPad; - } else { - // Can this call unwind out of the current function? - NoUnwind = !can_throw_external_1(RegionNo, false); - } + LandingPad = ThisPad; + } else { + // Can this call unwind out of the current function? + NoUnwind = !can_throw_external_1(RegionNo, false); } } } From evan.cheng at apple.com Thu Dec 6 02:54:32 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Dec 2007 08:54:32 -0000 Subject: [llvm-commits] [test-suite] r44660 - /test-suite/trunk/Makefile.programs Message-ID: <200712060854.lB68sWRi031446@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 6 02:54:31 2007 New Revision: 44660 URL: http://llvm.org/viewvc/llvm-project?rev=44660&view=rev Log: Turning simple splitting on. Start testing new coalescer heuristics as new llcbeta. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=44660&r1=44659&r2=44660&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Thu Dec 6 02:54:31 2007 @@ -209,7 +209,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -split-intervals-at-bb +LLCBETAOPTION := -new-coalescer-heuristic=true #--enable-tail-merge #--enable-ppc-preinc #-regalloc=local -fast @@ -222,8 +222,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -split-intervals-at-bb -#-new-coalescer-heuristic=true +LLCBETAOPTION := -new-coalescer-heuristic=true #-tailcallopt #-regalloc=local -fast #-disable-rematerialization @@ -234,9 +233,8 @@ LLCBETAOPTION := -enable-sparc-v9-insts endif ifeq ($(ARCH),ARM) -LLCBETAOPTION := -split-intervals-at-bb +LLCBETAOPTION := -new-coalescer-heuristic=true #-disable-rematerialization -#-enable-arm-if-conversion #-march=thumb endif ifeq ($(ARCH),THUMB) From evan.cheng at apple.com Thu Dec 6 02:54:33 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Dec 2007 08:54:33 -0000 Subject: [llvm-commits] [llvm] r44660 - in /llvm/trunk: lib/CodeGen/LiveIntervalAnalysis.cpp test/CodeGen/ARM/remat.ll test/CodeGen/X86/2007-08-13-SpillerReuse.ll test/CodeGen/X86/2007-11-30-TestLoadFolding.ll Message-ID: <200712060854.lB68sXvf031454@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 6 02:54:31 2007 New Revision: 44660 URL: http://llvm.org/viewvc/llvm-project?rev=44660&view=rev Log: Turning simple splitting on. Start testing new coalescer heuristics as new llcbeta. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/test/CodeGen/ARM/remat.ll llvm/trunk/test/CodeGen/X86/2007-08-13-SpillerReuse.ll llvm/trunk/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44660&r1=44659&r2=44660&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Dec 6 02:54:31 2007 @@ -42,7 +42,7 @@ cl::init(false), cl::Hidden); cl::opt SplitAtBB("split-intervals-at-bb", - cl::init(false), cl::Hidden); + cl::init(true), cl::Hidden); cl::opt SplitLimit("split-limit", cl::init(-1), cl::Hidden); } Modified: llvm/trunk/test/CodeGen/ARM/remat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/remat.ll?rev=44660&r1=44659&r2=44660&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/remat.ll (original) +++ llvm/trunk/test/CodeGen/ARM/remat.ll Thu Dec 6 02:54:31 2007 @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 5 +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 3 %struct.CONTENTBOX = type { i32, i32, i32, i32, i32 } %struct.LOCBOX = type { i32, i32, i32, i32 } Modified: llvm/trunk/test/CodeGen/X86/2007-08-13-SpillerReuse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-08-13-SpillerReuse.ll?rev=44660&r1=44659&r2=44660&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-08-13-SpillerReuse.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-08-13-SpillerReuse.ll Thu Dec 6 02:54:31 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin | grep "48(%esp)" | count 6 +; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin | grep "48(%esp)" | count 5 %struct..0anon = type { i32 } %struct.rtvec_def = type { i32, [1 x %struct..0anon] } Modified: llvm/trunk/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll?rev=44660&r1=44659&r2=44660&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll Thu Dec 6 02:54:31 2007 @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 -stats |& \ -; RUN: grep {2 .*folded into instructions} +; RUN: grep {1 .*folded into instructions} ; RUN: llvm-as < %s | llc -march=x86 | grep cmp | count 3 %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* } From dalej at apple.com Thu Dec 6 11:53:32 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 06 Dec 2007 17:53:32 -0000 Subject: [llvm-commits] [llvm] r44663 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200712061753.lB6HrWTt026702@zion.cs.uiuc.edu> Author: johannes Date: Thu Dec 6 11:53:31 2007 New Revision: 44663 URL: http://llvm.org/viewvc/llvm-project?rev=44663&view=rev Log: Redo previous patch so optimization only done for i1. Simpler and safer. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=44663&r1=44662&r2=44663&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Dec 6 11:53:31 2007 @@ -2455,10 +2455,6 @@ MVT::ValueType VT = N->getValueType(0); MVT::ValueType VT0 = N0.getValueType(); - - // Some targets have SETCC types bigger than 1 bit, but do not set all the - // bits to 1; identified by getSetCCResultContents. Watch out for these. - // fold select C, X, X -> X if (N1 == N2) return N1; @@ -2483,22 +2479,14 @@ return DAG.getNode(ISD::TRUNCATE, VT, XORNode); } // fold select C, 0, X -> ~C & X - if (VT == VT0 && N1C && N1C->isNullValue() && - (N0.Val->getOpcode()!=ISD::SETCC || VT==MVT::i1 || - TLI.getSetCCResultContents()== - TargetLowering::ZeroOrNegativeOneSetCCResult)) { - SDOperand XORNode; - XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(~0UL, VT)); + if (VT == VT0 && VT == MVT::i1 && N1C && N1C->isNullValue()) { + SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); AddToWorkList(XORNode.Val); return DAG.getNode(ISD::AND, VT, XORNode, N2); } // fold select C, X, 1 -> ~C | X - if (VT == VT0 && N2C && N2C->getValue() == 1 && - (N0.Val->getOpcode()!=ISD::SETCC || VT==MVT::i1 || - TLI.getSetCCResultContents()== - TargetLowering::ZeroOrNegativeOneSetCCResult)) { - SDOperand XORNode; - XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(~0UL, VT)); + if (VT == VT0 && VT == MVT::i1 && N2C && N2C->getValue() == 1) { + SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); AddToWorkList(XORNode.Val); return DAG.getNode(ISD::OR, VT, XORNode, N1); } From isanbard at gmail.com Thu Dec 6 16:10:03 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 06 Dec 2007 22:10:03 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r44667 - in /llvm-gcc-4.2/trunk: build_gcc driverdriver.c Message-ID: <200712062210.lB6MA377007835@zion.cs.uiuc.edu> Author: void Date: Thu Dec 6 16:10:02 2007 New Revision: 44667 URL: http://llvm.org/viewvc/llvm-project?rev=44667&view=rev Log: Hacked to link the drivers into the ${Fnord}/Developer/usr/bin directory. This isn't optimal, but gets around the hack we had of trying to find the correct driver... Modified: llvm-gcc-4.2/trunk/build_gcc llvm-gcc-4.2/trunk/driverdriver.c Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=44667&r1=44666&r2=44667&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Thu Dec 6 16:10:02 2007 @@ -372,7 +372,7 @@ $DIR/dst-*-$t/$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-gcc || exit 1 # APPLE LOCAL LLVM build_gcc bug with non-/usr $DEST_ROOT lipo -output .$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-llvm-g++-$MAJ_VERS -create \ - $DIR/dst-*-$t/$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-llvm-g++ || exit 1 + $DIR/dst-*-$t/$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-g++ || exit 1 done # lib @@ -524,11 +524,17 @@ ln -s -f ../../../$DEST_ROOT/bin/llvm-gcc-$MAJ_VERS llvm-gcc-$MAJ_VERS || exit 1 ln -s -f ../../../$DEST_ROOT/bin/llvm-g++-$MAJ_VERS llvm-g++-$MAJ_VERS || exit 1 - # Copy one of the libllvmgcc.dylib's up to libexec/gcc. +# FIXME: This is a hack to get things working. +for h in $HOSTS ; do + ln -s -f ../../../$DEST_ROOT/bin/$h-apple-darwin$DARWIN_VERS-llvm-gcc-$MAJ_VERS $h-apple-darwin$DARWIN_VERS-llvm-gcc-$MAJ_VERS || exit 1 + ln -s -f ../../../$DEST_ROOT/bin/$h-apple-darwin$DARWIN_VERS-llvm-g++-$MAJ_VERS $h-apple-darwin$DARWIN_VERS-llvm-g++-$MAJ_VERS || exit 1 +done + +# Copy one of the libllvmgcc.dylib's up to libexec/gcc. cp $DEST_DIR/$DEST_ROOT/libexec/gcc/$BUILD-apple-darwin$DARWIN_VERS/$VERS/libllvmgcc.dylib \ $DEST_DIR/$DEST_ROOT/libexec/gcc/ - # Replace the installed ones with symlinks to the common one. +# Replace the installed ones with symlinks to the common one. for t in $TARGETS ; do cd $DEST_DIR/$DEST_ROOT/libexec/gcc/$t-apple-darwin$DARWIN_VERS/$VERS/ rm libllvmgcc.dylib Modified: llvm-gcc-4.2/trunk/driverdriver.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/driverdriver.c?rev=44667&r1=44666&r2=44667&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/driverdriver.c (original) +++ llvm-gcc-4.2/trunk/driverdriver.c Thu Dec 6 16:10:02 2007 @@ -1253,6 +1253,7 @@ strncpy (curr_dir, argv[0], prefix_len); curr_dir[prefix_len] = '\0'; /* LLVM LOCAL begin - These drivers live in /.../usr/llvm-gcc-4.2/bin */ +#if 0 { size_t curr_dir_len = strlen (curr_dir); const char *llvm_bin_dir = "/usr/llvm-gcc-4.2/bin/"; @@ -1267,6 +1268,9 @@ } else driver_exec_prefix = curr_dir; } +#else + driver_exec_prefix = curr_dir; +#endif /* LLVM LOCAL end - These drivers live in /.../usr/llvm-gcc-4.2/bin */ #ifdef DEBUG @@ -1553,7 +1557,11 @@ final_cleanup (); free (curr_dir); + /* LLVM LOCAL - begin */ +#if 0 if (delete_prefix) free (driver_exec_prefix); +#endif + /* LLVM LOCAL - end */ return greatest_status; } From evan.cheng at apple.com Thu Dec 6 16:12:45 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Dec 2007 22:12:45 -0000 Subject: [llvm-commits] [llvm] r44668 - /llvm/trunk/test/CodeGen/X86/vec_set-2.ll Message-ID: <200712062212.lB6MCjKR007941@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 6 16:12:45 2007 New Revision: 44668 URL: http://llvm.org/viewvc/llvm-project?rev=44668&view=rev Log: Fix a bogus test case. Modified: llvm/trunk/test/CodeGen/X86/vec_set-2.ll Modified: llvm/trunk/test/CodeGen/X86/vec_set-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-2.ll?rev=44668&r1=44667&r2=44668&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-2.ll Thu Dec 6 16:12:45 2007 @@ -1,23 +1,19 @@ -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 -mattr=+sse2 | grep movss | count 1 -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 -mattr=+sse2 | grep movd | count 1 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movss | count 1 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movd | count 1 -<4 x float> %test1(float %a) { - %tmp = insertelement <4 x float> zeroinitializer, float %a, uint 0 - %tmp5 = insertelement <4 x float> %tmp, float 0.000000e+00, uint 1 - %tmp6 = insertelement <4 x float> %tmp5, float 0.000000e+00, uint 2 - %tmp7 = insertelement <4 x float> %tmp6, float 0.000000e+00, uint 3 +define <4 x float> @test1(float %a) { + %tmp = insertelement <4 x float> zeroinitializer, float %a, i32 0 ; <<4 x float>> [#uses=1] + %tmp5 = insertelement <4 x float> %tmp, float 0.000000e+00, i32 1 ; <<4 x float>> [#uses=1] + %tmp6 = insertelement <4 x float> %tmp5, float 0.000000e+00, i32 2 ; <<4 x float>> [#uses=1] + %tmp7 = insertelement <4 x float> %tmp6, float 0.000000e+00, i32 3 ; <<4 x float>> [#uses=1] ret <4 x float> %tmp7 } -<2 x long> %test(short %a) { - %tmp = insertelement <8 x short> zeroinitializer, short %a, uint 0 - %tmp6 = insertelement <8 x short> %tmp, short 0, uint 1 - %tmp8 = insertelement <8 x short> %tmp6, short 0, uint 2 - %tmp10 = insertelement <8 x short> %tmp8, short 0, uint 3 - %tmp12 = insertelement <8 x short> %tmp10, short 0, uint 4 - %tmp14 = insertelement <8 x short> %tmp12, short 0, uint 5 - %tmp16 = insertelement <8 x short> %tmp14, short 0, uint 6 - %tmp18 = insertelement <8 x short> %tmp16, short 0, uint 7 - %tmp19 = cast <8 x short> %tmp18 to <2 x long> - ret <2 x long> %tmp19 +define <2 x i64> @test(i32 %a) { + %tmp = insertelement <4 x i32> zeroinitializer, i32 %a, i32 0 ; <<8 x i16>> [#uses=1] + %tmp6 = insertelement <4 x i32> %tmp, i32 0, i32 1 ; <<8 x i32>> [#uses=1] + %tmp8 = insertelement <4 x i32> %tmp6, i32 0, i32 2 ; <<8 x i32>> [#uses=1] + %tmp10 = insertelement <4 x i32> %tmp8, i32 0, i32 3 ; <<8 x i32>> [#uses=1] + %tmp19 = bitcast <4 x i32> %tmp10 to <2 x i64> ; <<2 x i64>> [#uses=1] + ret <2 x i64> %tmp19 } From evan.cheng at apple.com Thu Dec 6 16:14:22 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 06 Dec 2007 22:14:22 -0000 Subject: [llvm-commits] [llvm] r44669 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86InstrSSE.td Message-ID: <200712062214.lB6MEMwx008023@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 6 16:14:22 2007 New Revision: 44669 URL: http://llvm.org/viewvc/llvm-project?rev=44669&view=rev Log: Remove a bogus optimization. It's not possible to do a move to low element to a <8 x i16> or <16 x i8> vector. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44669&r1=44668&r2=44669&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Dec 6 16:14:22 2007 @@ -2462,7 +2462,7 @@ /// specifies a shuffle of elements that is suitable for input to MOVSS, /// MOVSD, and MOVD, i.e. setting the lowest element. static bool isMOVLMask(const SDOperand *Elts, unsigned NumElts) { - if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16) + if (NumElts != 2 && NumElts != 4) return false; if (!isUndefOrEqual(Elts[0], NumElts)) Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=44669&r1=44668&r2=44669&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Thu Dec 6 16:14:22 2007 @@ -2734,12 +2734,6 @@ // Move scalar to XMM zero-extended // movd to XMM register zero-extends let AddedComplexity = 15 in { -def : Pat<(v8i16 (vector_shuffle immAllZerosV_bc, - (v8i16 (X86s2vec GR32:$src)), MOVL_shuffle_mask)), - (MOVZDI2PDIrr GR32:$src)>, Requires<[HasSSE2]>; -def : Pat<(v16i8 (vector_shuffle immAllZerosV_bc, - (v16i8 (X86s2vec GR32:$src)), MOVL_shuffle_mask)), - (MOVZDI2PDIrr GR32:$src)>, Requires<[HasSSE2]>; // Zeroing a VR128 then do a MOVS{S|D} to the lower bits. def : Pat<(v2f64 (vector_shuffle immAllZerosV_bc, (v2f64 (scalar_to_vector FR64:$src)), MOVL_shuffle_mask)), From evan.cheng at apple.com Thu Dec 6 18:28:33 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Dec 2007 00:28:33 -0000 Subject: [llvm-commits] [llvm] r44671 - /llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Message-ID: <200712070028.lB70SXUc014387@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 6 18:28:32 2007 New Revision: 44671 URL: http://llvm.org/viewvc/llvm-project?rev=44671&view=rev Log: Add an option to control this heuristic tweak so I can test it. Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=44671&r1=44670&r2=44671&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Thu Dec 6 18:28:32 2007 @@ -52,6 +52,11 @@ cl::desc("Use new coalescer heuristic"), cl::init(false)); + static cl::opt + ReMatSpillWeight("tweak-remat-spill-weight", + cl::desc("Tweak spill weight of re-materializable intervals"), + cl::init(true)); + RegisterPass X("simple-register-coalescing", "Simple Register Coalescing"); @@ -1487,7 +1492,7 @@ LI.weight = HUGE_VALF; else { bool isLoad = false; - if (li_->isReMaterializable(LI, isLoad)) { + if (ReMatSpillWeight && li_->isReMaterializable(LI, isLoad)) { // If all of the definitions of the interval are re-materializable, // it is a preferred candidate for spilling. If non of the defs are // loads, then it's potentially very cheap to re-materialize. From evan.cheng at apple.com Thu Dec 6 19:44:15 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 6 Dec 2007 17:44:15 -0800 Subject: [llvm-commits] [llvm] r44643 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <200712052358.lB5NwKhR031055@zion.cs.uiuc.edu> Message-ID: On Dec 5, 2007, at 4:08 PM, Chris Lattner wrote: > On Dec 5, 2007, at 3:58 PM, Evan Cheng wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=44643&view=rev >> Log: >> If both result of the {s|z}xt and its source are live out, rewrite >> all uses of the source with result of extension. > > I assume this is experimental, right? What sort of case does it > fix? Testcase please :) It's experimental. I'll reduce some a test case when it's enabled. :-) Evan > > > -Chris > >> Modified: >> llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp >> >> Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ >> Scalar/CodeGenPrepare.cpp?rev=44643&r1=44642&r2=44643&view=diff >> >> = >> ===================================================================== >> ======== >> --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) >> +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Dec 5 >> 17:58:20 2007 >> @@ -28,11 +28,17 @@ >> #include "llvm/Transforms/Utils/Local.h" >> #include "llvm/ADT/DenseMap.h" >> #include "llvm/ADT/SmallSet.h" >> -#include "llvm/Support/Debug.h" >> +#include "llvm/Support/CommandLine.h" >> #include "llvm/Support/Compiler.h" >> +#include "llvm/Support/Debug.h" >> #include "llvm/Support/GetElementPtrTypeIterator.h" >> using namespace llvm; >> >> +namespace { >> + cl::opt OptExtUses("optimize-ext-uses", >> + cl::init(false), cl::Hidden); >> +} >> + >> namespace { >> class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass { >> /// TLI - Keep a pointer of a TargetLowering to consult for >> determining >> @@ -52,6 +58,7 @@ >> bool OptimizeLoadStoreInst(Instruction *I, Value *Addr, >> const Type *AccessTy, >> DenseMap &SunkAddrs); >> + bool OptimizeExtUses(Instruction *I); >> }; >> } >> >> @@ -913,6 +920,61 @@ >> return true; >> } >> >> +bool CodeGenPrepare::OptimizeExtUses(Instruction *I) { >> + BasicBlock *DefBB = I->getParent(); >> + >> + // If both result of the {s|z}xt and its source are live out, >> rewrite all >> + // other uses of the source with result of extension. >> + Value *Src = I->getOperand(0); >> + if (Src->hasOneUse()) >> + return false; >> + >> + bool DefIsLiveOut = false; >> + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); >> + UI != E; ++UI) { >> + Instruction *User = cast(*UI); >> + >> + // Figure out which BB this ext is used in. >> + BasicBlock *UserBB = User->getParent(); >> + if (UserBB == DefBB) continue; >> + DefIsLiveOut = true; >> + break; >> + } >> + if (!DefIsLiveOut) >> + return false; >> + >> + // InsertedTruncs - Only insert one trunc in each block once. >> + DenseMap InsertedTruncs; >> + >> + bool MadeChange = false; >> + for (Value::use_iterator UI = Src->use_begin(), E = Src- >> >use_end(); >> + UI != E; ++UI) { >> + Use &TheUse = UI.getUse(); >> + Instruction *User = cast(*UI); >> + >> + // Figure out which BB this ext is used in. >> + BasicBlock *UserBB = User->getParent(); >> + if (UserBB == DefBB) continue; >> + >> + // Both src and def are live in this block. Rewrite the use. >> + Instruction *&InsertedTrunc = InsertedTruncs[UserBB]; >> + >> + if (!InsertedTrunc) { >> + BasicBlock::iterator InsertPt = UserBB->begin(); >> + while (isa(InsertPt)) ++InsertPt; >> + >> + InsertedTrunc = new TruncInst(I, Src->getType(), "", >> InsertPt); >> + } >> + >> + // Replace a use of the {s|z}ext source with a use of the >> result. >> + TheUse = InsertedTrunc; >> + >> + MadeChange = true; >> + } >> + >> + return MadeChange; >> +} >> + >> // In this pass we look for GEP and cast instructions that are used >> // across basic blocks and rewrite them to improve basic-block-at- >> a-time >> // selection. >> @@ -948,8 +1010,14 @@ >> if (isa(CI->getOperand(0))) >> continue; >> >> - if (TLI) >> - MadeChange |= OptimizeNoopCopyExpression(CI, *TLI); >> + bool Change = false; >> + if (TLI) { >> + Change = OptimizeNoopCopyExpression(CI, *TLI); >> + MadeChange |= Change; >> + } >> + >> + if (OptExtUses && !Change && (isa(I) || >> isa(I))) >> + MadeChange |= OptimizeExtUses(I); >> } else if (CmpInst *CI = dyn_cast(I)) { >> MadeChange |= OptimizeCmpExpression(CI); >> } else if (LoadInst *LI = dyn_cast(I)) { >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Thu Dec 6 19:46:30 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 6 Dec 2007 17:46:30 -0800 Subject: [llvm-commits] [llvm] r44643 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: References: <200712052358.lB5NwKhR031055@zion.cs.uiuc.edu> Message-ID: <886CE11F-664C-4BAF-B877-ED6D2BFBE615@apple.com> On Dec 6, 2007, at 5:44 PM, Evan Cheng wrote: > > On Dec 5, 2007, at 4:08 PM, Chris Lattner wrote: > >> On Dec 5, 2007, at 3:58 PM, Evan Cheng wrote: >>> URL: http://llvm.org/viewvc/llvm-project?rev=44643&view=rev >>> Log: >>> If both result of the {s|z}xt and its source are live out, rewrite >>> all uses of the source with result of extension. >> >> I assume this is experimental, right? What sort of case does it >> fix? Testcase please :) > > It's experimental. I'll reduce some a test case when it's enabled. :-) ok -Chris From evan.cheng at apple.com Thu Dec 6 19:48:46 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Dec 2007 01:48:46 -0000 Subject: [llvm-commits] [llvm] r44672 - /llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll Message-ID: <200712070148.lB71mkSE018628@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 6 19:48:46 2007 New Revision: 44672 URL: http://llvm.org/viewvc/llvm-project?rev=44672&view=rev Log: New test case. Added: llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll Added: llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll?rev=44672&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll (added) +++ llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll Thu Dec 6 19:48:46 2007 @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 + +define void @test(<8 x i16>* %res, <8 x i16>* %A, <8 x i16>* %B) { + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> < i32 8, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 > + store <8 x i16> %tmp3, <8 x i16>* %res + ret void +} From resistor at mac.com Thu Dec 6 22:04:55 2007 From: resistor at mac.com (Owen Anderson) Date: Fri, 07 Dec 2007 04:04:55 -0000 Subject: [llvm-commits] [llvm] r44674 - /llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h Message-ID: <200712070404.lB744twi025324@zion.cs.uiuc.edu> Author: resistor Date: Thu Dec 6 22:04:55 2007 New Revision: 44674 URL: http://llvm.org/viewvc/llvm-project?rev=44674&view=rev Log: Fix a stupid error that Chris pointed out. Modified: llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h Modified: llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h?rev=44674&r1=44673&r2=44674&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h Thu Dec 6 22:04:55 2007 @@ -123,8 +123,6 @@ /// runOnFunction - Calculate the natural loop information. /// virtual bool runOnMachineFunction(MachineFunction &F); - - bool runOnFunction(Function& F) { return false; } virtual void releaseMemory() { LI->releaseMemory(); } From dpatel at apple.com Thu Dec 6 23:30:06 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 07 Dec 2007 05:30:06 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r44675 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200712070530.lB75U6HK030562@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 6 23:30:06 2007 New Revision: 44675 URL: http://llvm.org/viewvc/llvm-project?rev=44675&view=rev Log: Fix broken links that point to assembler and linker. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=44675&r1=44674&r2=44675&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Thu Dec 6 23:30:06 2007 @@ -348,8 +348,9 @@ cp -p $DIR/dst-$BUILD-$t$DL/$f .$DL/$f || exit 1 fi done - ln -s ../../../../bin/as .$DL/as - ln -s ../../../../bin/ld .$DL/ld + # LLVM LOCAL fix broken link + ln -s ../../../../../bin/as .$DL/as + ln -s ../../../../../bin/ld .$DL/ld done # bin From evan.cheng at apple.com Fri Dec 7 02:07:41 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Dec 2007 08:07:41 -0000 Subject: [llvm-commits] [llvm] r44676 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2007-12-05-VectorShuffle.ll test/CodeGen/X86/vec_shuffle-12.ll Message-ID: <200712070807.lB787fIn005672@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 7 02:07:39 2007 New Revision: 44676 URL: http://llvm.org/viewvc/llvm-project?rev=44676&view=rev Log: Much improved v8i16 shuffles. (Step 1). Added: llvm/trunk/test/CodeGen/X86/vec_shuffle-12.ll Removed: llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44676&r1=44675&r2=44676&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 7 02:07:39 2007 @@ -2754,10 +2754,33 @@ } std::swap(V1, V2); - Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size()); + Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], NumElems); return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); } +static +SDOperand CommuteVectorShuffleMask(SDOperand Mask, SelectionDAG &DAG) { + MVT::ValueType MaskVT = Mask.getValueType(); + MVT::ValueType EltVT = MVT::getVectorElementType(MaskVT); + unsigned NumElems = Mask.getNumOperands(); + SmallVector MaskVec; + for (unsigned i = 0; i != NumElems; ++i) { + SDOperand Arg = Mask.getOperand(i); + if (Arg.getOpcode() == ISD::UNDEF) { + MaskVec.push_back(DAG.getNode(ISD::UNDEF, EltVT)); + continue; + } + assert(isa(Arg) && "Invalid VECTOR_SHUFFLE mask!"); + unsigned Val = cast(Arg)->getValue(); + if (Val < NumElems) + MaskVec.push_back(DAG.getConstant(Val + NumElems, EltVT)); + else + MaskVec.push_back(DAG.getConstant(Val - NumElems, EltVT)); + } + return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], NumElems); +} + + /// ShouldXformToMOVHLPS - Return true if the node should be transformed to /// match movhlps. The lower half elements should come from upper half of /// V1 (and in order), and the upper half elements should come from the upper @@ -3282,6 +3305,102 @@ return SDOperand(); } +static +SDOperand LowerVECTOR_SHUFFLEv8i16(SDOperand V1, SDOperand V2, + SDOperand PermMask, SelectionDAG &DAG, + TargetLowering &TLI) { + MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(8); + MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT); + if (isPSHUFHW_PSHUFLWMask(PermMask.Val)) { + // Handle v8i16 shuffle high / low shuffle node pair. + SmallVector MaskVec; + for (unsigned i = 0; i != 4; ++i) + MaskVec.push_back(PermMask.getOperand(i)); + for (unsigned i = 4; i != 8; ++i) + MaskVec.push_back(DAG.getConstant(i, MaskEVT)); + SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], 8); + V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v8i16, V1, V2, Mask); + MaskVec.clear(); + for (unsigned i = 0; i != 4; ++i) + MaskVec.push_back(DAG.getConstant(i, MaskEVT)); + for (unsigned i = 4; i != 8; ++i) + MaskVec.push_back(PermMask.getOperand(i)); + Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], 8); + return DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v8i16, V1, V2, Mask); + } + + // Lower than into extracts and inserts but try to do as few as possible. + // First, let's find out how many elements are already in the right order. + unsigned V1InOrder = 0; + unsigned V1FromV1 = 0; + unsigned V2InOrder = 0; + unsigned V2FromV2 = 0; + SmallVector V1Elts; + SmallVector V2Elts; + for (unsigned i = 0; i < 8; ++i) { + SDOperand Elt = PermMask.getOperand(i); + if (Elt.getOpcode() == ISD::UNDEF) { + V1Elts.push_back(i); + V2Elts.push_back(i); + ++V1InOrder; + ++V2InOrder; + } else { + unsigned EltIdx = cast(Elt)->getValue(); + if (EltIdx == i) { + V1Elts.push_back(i); + V2Elts.push_back(i+8); + ++V1InOrder; + } else if (EltIdx == i+8) { + V1Elts.push_back(i+8); + V2Elts.push_back(i); + ++V2InOrder; + } else { + V1Elts.push_back(EltIdx); + V2Elts.push_back(EltIdx); + if (EltIdx < 8) + ++V1FromV1; + else + ++V2FromV2; + } + } + } + + if (V2InOrder > V1InOrder) { + PermMask = CommuteVectorShuffleMask(PermMask, DAG); + std::swap(V1, V2); + std::swap(V1Elts, V2Elts); + std::swap(V1FromV1, V2FromV2); + } + + MVT::ValueType PtrVT = TLI.getPointerTy(); + if (V1FromV1) { + // If there are elements that are from V1 but out of place, + // then first sort them in place + SmallVector MaskVec; + for (unsigned i = 0; i < 8; ++i) { + unsigned EltIdx = V1Elts[i]; + if (EltIdx >= 8) + MaskVec.push_back(DAG.getNode(ISD::UNDEF, MaskEVT)); + else + MaskVec.push_back(DAG.getConstant(EltIdx, MaskEVT)); + } + SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], 8); + V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v8i16, V1, V1, Mask); + } + + // Now let's insert elements from the other vector. + for (unsigned i = 0; i < 8; ++i) { + unsigned EltIdx = V1Elts[i]; + if (EltIdx < 8) + continue; + SDOperand ExtOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, V2, + DAG.getConstant(EltIdx - 8, PtrVT)); + V1 = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V1, ExtOp, + DAG.getConstant(i, PtrVT)); + } + return V1; +} + SDOperand X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { SDOperand V1 = Op.getOperand(0); @@ -3406,27 +3525,6 @@ if (X86::isSHUFPMask(PermMask.Val) && MVT::getSizeInBits(VT) != 64) // Don't do this for MMX. return Op; - - // Handle v8i16 shuffle high / low shuffle node pair. - if (VT == MVT::v8i16 && isPSHUFHW_PSHUFLWMask(PermMask.Val)) { - MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT); - SmallVector MaskVec; - for (unsigned i = 0; i != 4; ++i) - MaskVec.push_back(PermMask.getOperand(i)); - for (unsigned i = 4; i != 8; ++i) - MaskVec.push_back(DAG.getConstant(i, BaseVT)); - SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, - &MaskVec[0], MaskVec.size()); - V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); - MaskVec.clear(); - for (unsigned i = 0; i != 4; ++i) - MaskVec.push_back(DAG.getConstant(i, BaseVT)); - for (unsigned i = 4; i != 8; ++i) - MaskVec.push_back(PermMask.getOperand(i)); - Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0],MaskVec.size()); - return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); - } } else { // Floating point cases in the other order. if (X86::isSHUFPMask(PermMask.Val)) @@ -3441,9 +3539,12 @@ } } - if (NumElems == 4 && - // Don't do this for MMX. - MVT::getSizeInBits(VT) != 64) { + // Handle v8i16 specifically since SSE can do byte extraction and insertion. + if (VT == MVT::v8i16) + return LowerVECTOR_SHUFFLEv8i16(V1, V2, PermMask, DAG, *this); + + if (NumElems == 4 && MVT::getSizeInBits(VT) != 64) { + // Don't do this for MMX. MVT::ValueType MaskVT = PermMask.getValueType(); MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT); SmallVector, 8> Locs; Removed: llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll?rev=44675&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-12-05-VectorShuffle.ll (removed) @@ -1,9 +0,0 @@ -; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 - -define void @test(<8 x i16>* %res, <8 x i16>* %A, <8 x i16>* %B) { - %tmp1 = load <8 x i16>* %A - %tmp2 = load <8 x i16>* %B - %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> < i32 8, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 > - store <8 x i16> %tmp3, <8 x i16>* %res - ret void -} Added: llvm/trunk/test/CodeGen/X86/vec_shuffle-12.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-12.ll?rev=44676&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shuffle-12.ll (added) +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-12.ll Fri Dec 7 02:07:39 2007 @@ -0,0 +1,37 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | not grep punpck +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep pextrw | count 7 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep pinsrw | count 7 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep pshuf | count 2 + +define void @t1(<8 x i16>* %res, <8 x i16>* %A, <8 x i16>* %B) { + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> < i32 8, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 > + store <8 x i16> %tmp3, <8 x i16>* %res + ret void +} + +define void @t2(<8 x i16>* %res, <8 x i16>* %A, <8 x i16>* %B) { + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> < i32 8, i32 1, i32 2, i32 13, i32 4, i32 5, i32 6, i32 7 > + store <8 x i16> %tmp3, <8 x i16>* %res + ret void +} + +define void @t3(<8 x i16>* %res, <8 x i16>* %A, <8 x i16>* %B) { + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> < i32 8, i32 3, i32 2, i32 13, i32 7, i32 6, i32 5, i32 4 > + store <8 x i16> %tmp3, <8 x i16>* %res + ret void +} + +define void @t4(<8 x i16>* %res, <8 x i16>* %A, <8 x i16>* %B) { + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> < i32 8, i32 9, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 > + store <8 x i16> %tmp3, <8 x i16>* %res + ret void +} From clattner at apple.com Fri Dec 7 10:13:59 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Dec 2007 08:13:59 -0800 Subject: [llvm-commits] [llvm] r44676 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2007-12-05-VectorShuffle.ll test/CodeGen/X86/vec_shuffle-12.ll In-Reply-To: <200712070807.lB787fIn005672@zion.cs.uiuc.edu> References: <200712070807.lB787fIn005672@zion.cs.uiuc.edu> Message-ID: <45B8E521-3DB6-47AE-A08C-10B10FCC35BD@apple.com> Hey Evan, > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 7 > 02:07:39 2007 > @@ -2754,10 +2754,33 @@ > } > > std::swap(V1, V2); > - Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], > MaskVec.size()); > + Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], > NumElems); > return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); > } > > +static > +SDOperand CommuteVectorShuffleMask(SDOperand Mask, SelectionDAG > &DAG) { Please add a comment over this that gives an example of what it does. I kept misreading the name as "compute..." and couldn't figure out what it did :) > +static > +SDOperand LowerVECTOR_SHUFFLEv8i16(SDOperand V1, SDOperand V2, > + SDOperand PermMask, > SelectionDAG &DAG, > + TargetLowering &TLI) { Does this cause any pessimizations for v8i16 shuffles that could be done as v4i32? -Chris From evan.cheng at apple.com Fri Dec 7 11:27:48 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 7 Dec 2007 09:27:48 -0800 Subject: [llvm-commits] [llvm] r44676 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2007-12-05-VectorShuffle.ll test/CodeGen/X86/vec_shuffle-12.ll In-Reply-To: <45B8E521-3DB6-47AE-A08C-10B10FCC35BD@apple.com> References: <200712070807.lB787fIn005672@zion.cs.uiuc.edu> <45B8E521-3DB6-47AE-A08C-10B10FCC35BD@apple.com> Message-ID: On Dec 7, 2007, at 8:13 AM, Chris Lattner wrote: > Hey Evan, > >> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 7 >> 02:07:39 2007 >> @@ -2754,10 +2754,33 @@ >> } >> >> std::swap(V1, V2); >> - Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], >> MaskVec.size()); >> + Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], >> NumElems); >> return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); >> } >> >> +static >> +SDOperand CommuteVectorShuffleMask(SDOperand Mask, SelectionDAG >> &DAG) { > > Please add a comment over this that gives an example of what it > does. I kept misreading the name as "compute..." and couldn't figure > out what it did :) Ok. > > >> +static >> +SDOperand LowerVECTOR_SHUFFLEv8i16(SDOperand V1, SDOperand V2, >> + SDOperand PermMask, >> SelectionDAG &DAG, >> + TargetLowering &TLI) { > > Does this cause any pessimizations for v8i16 shuffles that could be > done as v4i32? No. Because the lowering before this patch is even worse. :-) I plan on improving this further. Evan > > > -Chris > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From criswell at uiuc.edu Fri Dec 7 12:05:13 2007 From: criswell at uiuc.edu (John Criswell) Date: Fri, 07 Dec 2007 18:05:13 -0000 Subject: [llvm-commits] [poolalloc] r44677 - /poolalloc/trunk/include/poolalloc/PoolAllocate.h Message-ID: <200712071805.lB7I5E7X013946@zion.cs.uiuc.edu> Author: criswell Date: Fri Dec 7 12:05:12 2007 New Revision: 44677 URL: http://llvm.org/viewvc/llvm-project?rev=44677&view=rev Log: Do not use an absolute path to find the header file from SAFECode. The configure script now sets up -I options to the compiler to help us find it. Modified: poolalloc/trunk/include/poolalloc/PoolAllocate.h Modified: poolalloc/trunk/include/poolalloc/PoolAllocate.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/PoolAllocate.h?rev=44677&r1=44676&r2=44677&view=diff ============================================================================== --- poolalloc/trunk/include/poolalloc/PoolAllocate.h (original) +++ poolalloc/trunk/include/poolalloc/PoolAllocate.h Fri Dec 7 12:05:12 2007 @@ -26,8 +26,7 @@ #include "poolalloc/Config/config.h" #ifdef SAFECODE -//FIXME : make this use some configuration options -#include "/home/vadve/criswell/src/latestllvm/projects/safecode/include/ConvertUnsafeAllocas.h" +#include "ConvertUnsafeAllocas.h" #endif From criswell at uiuc.edu Fri Dec 7 12:06:17 2007 From: criswell at uiuc.edu (John Criswell) Date: Fri, 07 Dec 2007 18:06:17 -0000 Subject: [llvm-commits] [poolalloc] r44678 - /poolalloc/trunk/include/dsa/DataStructure.h Message-ID: <200712071806.lB7I6HtV014004@zion.cs.uiuc.edu> Author: criswell Date: Fri Dec 7 12:06:17 2007 New Revision: 44678 URL: http://llvm.org/viewvc/llvm-project?rev=44678&view=rev Log: Comment out the declarations of deleteValue() and copyValue() for the TDDataStructure pass. These methods are never defined and are uneeded. Need review from Andrew Lenharth to see whether these should be removed permanently. Modified: poolalloc/trunk/include/dsa/DataStructure.h Modified: poolalloc/trunk/include/dsa/DataStructure.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=44678&r1=44677&r2=44678&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DataStructure.h (original) +++ poolalloc/trunk/include/dsa/DataStructure.h Fri Dec 7 12:06:17 2007 @@ -272,10 +272,12 @@ virtual bool runOnModule(Module &M); +#if 0 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program. /// These correspond to the interfaces defined in the AliasAnalysis class. void deleteValue(Value *V); void copyValue(Value *From, Value *To); +#endif /// print - Print out the analysis results... /// From criswell at uiuc.edu Fri Dec 7 12:07:27 2007 From: criswell at uiuc.edu (John Criswell) Date: Fri, 07 Dec 2007 18:07:27 -0000 Subject: [llvm-commits] [poolalloc] r44680 - in /poolalloc/trunk/lib: DSA/Makefile PoolAllocate/Makefile Message-ID: <200712071807.lB7I7ROk014059@zion.cs.uiuc.edu> Author: criswell Date: Fri Dec 7 12:07:27 2007 New Revision: 44680 URL: http://llvm.org/viewvc/llvm-project?rev=44680&view=rev Log: Build relinked libraries for the SAFECode tool. Modified: poolalloc/trunk/lib/DSA/Makefile poolalloc/trunk/lib/PoolAllocate/Makefile Modified: poolalloc/trunk/lib/DSA/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Makefile?rev=44680&r1=44679&r2=44680&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Makefile (original) +++ poolalloc/trunk/lib/DSA/Makefile Fri Dec 7 12:07:27 2007 @@ -9,8 +9,6 @@ LEVEL = ../.. SHARED_LIBRARY=1 -LOADABLE_MODULE = 1 -DONT_BUILD_RELINKED=1 LIBRARYNAME = LLVMDataStructure include $(LEVEL)/Makefile.common Modified: poolalloc/trunk/lib/PoolAllocate/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/Makefile?rev=44680&r1=44679&r2=44680&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/Makefile (original) +++ poolalloc/trunk/lib/PoolAllocate/Makefile Fri Dec 7 12:07:27 2007 @@ -7,8 +7,6 @@ # Give the name of a library. This will build a dynamic version. # SHARED_LIBRARY=1 -LOADABLE_MODULE = 1 -DONT_BUILD_RELINKED=1 LIBRARYNAME=poolalloc # From criswell at uiuc.edu Fri Dec 7 12:06:47 2007 From: criswell at uiuc.edu (John Criswell) Date: Fri, 07 Dec 2007 18:06:47 -0000 Subject: [llvm-commits] [poolalloc] r44679 - /poolalloc/trunk/lib/DSA/DataStructure.cpp Message-ID: <200712071806.lB7I6lst014030@zion.cs.uiuc.edu> Author: criswell Date: Fri Dec 7 12:06:47 2007 New Revision: 44679 URL: http://llvm.org/viewvc/llvm-project?rev=44679&view=rev Log: Implement the isPointerType() method found in the DS namespace. Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=44679&r1=44678&r2=44679&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DataStructure.cpp (original) +++ poolalloc/trunk/lib/DSA/DataStructure.cpp Fri Dec 7 12:06:47 2007 @@ -14,6 +14,7 @@ #include "dsa/DSGraphTraits.h" #include "dsa/DataStructure.h" #include "dsa/DSGraph.h" +#include "dsa/DSSupport.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" @@ -60,6 +61,16 @@ using namespace DS; +// +// Function: DS::isPointerType() +// +// Description: +// This returns whether the given type is a pointer. +// +bool DS::isPointerType(const Type *Ty) { + return isa(Ty); +} + /// isForwarding - Return true if this NodeHandle is forwarding to another /// one. bool DSNodeHandle::isForwarding() const { From criswell at uiuc.edu Fri Dec 7 15:05:24 2007 From: criswell at uiuc.edu (John Criswell) Date: Fri, 07 Dec 2007 21:05:24 -0000 Subject: [llvm-commits] [poolalloc] r44683 - /poolalloc/trunk/include/dsa/DataStructure.h Message-ID: <200712072105.lB7L5O2r024643@zion.cs.uiuc.edu> Author: criswell Date: Fri Dec 7 15:05:23 2007 New Revision: 44683 URL: http://llvm.org/viewvc/llvm-project?rev=44683&view=rev Log: Removed deleteValue() and copyValue() from TDDataStructure; these methods should be implemented by the base class. Modified: poolalloc/trunk/include/dsa/DataStructure.h Modified: poolalloc/trunk/include/dsa/DataStructure.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=44683&r1=44682&r2=44683&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DataStructure.h (original) +++ poolalloc/trunk/include/dsa/DataStructure.h Fri Dec 7 15:05:23 2007 @@ -272,13 +272,6 @@ virtual bool runOnModule(Module &M); -#if 0 - /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program. - /// These correspond to the interfaces defined in the AliasAnalysis class. - void deleteValue(Value *V); - void copyValue(Value *From, Value *To); -#endif - /// print - Print out the analysis results... /// void print(std::ostream &O, const Module *M) const; From evan.cheng at apple.com Fri Dec 7 15:30:01 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 07 Dec 2007 21:30:01 -0000 Subject: [llvm-commits] [llvm] r44686 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200712072130.lB7LU1vD025822@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 7 15:30:01 2007 New Revision: 44686 URL: http://llvm.org/viewvc/llvm-project?rev=44686&view=rev Log: Add comment. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44686&r1=44685&r2=44686&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 7 15:30:01 2007 @@ -2758,6 +2758,8 @@ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); } +/// CommuteVectorShuffleMask - Change values in a shuffle permute mask assuming +/// the two vector operands have swapped position. static SDOperand CommuteVectorShuffleMask(SDOperand Mask, SelectionDAG &DAG) { MVT::ValueType MaskVT = Mask.getValueType(); From isanbard at gmail.com Fri Dec 7 15:42:32 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 07 Dec 2007 21:42:32 -0000 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td Message-ID: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> Author: void Date: Fri Dec 7 15:42:31 2007 New Revision: 44687 URL: http://llvm.org/viewvc/llvm-project?rev=44687&view=rev Log: Initial commit of the machine code LICM pass. It successfully hoists this: _foo: li r2, 0 LBB1_1: ; bb li r5, 0 stw r5, 0(r3) addi r2, r2, 1 addi r3, r3, 4 cmplw cr0, r2, r4 bne cr0, LBB1_1 ; bb LBB1_2: ; return blr to: _foo: li r2, 0 li r5, 0 LBB1_1: ; bb stw r5, 0(r3) addi r2, r2, 1 addi r3, r3, 4 cmplw cr0, r2, r4 bne cr0, LBB1_1 ; bb LBB1_2: ; return blr ZOMG!! :-) Moar to come... Added: llvm/trunk/lib/CodeGen/MachineLICM.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=44687&r1=44686&r2=44687&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Fri Dec 7 15:42:31 2007 @@ -135,6 +135,10 @@ /// for the Sparc. FunctionPass *getRegisterAllocator(TargetMachine &T); + /// createMachineLICMPass - This pass performs LICM on machine instructions. + /// + FunctionPass *createMachineLICMPass(); + } // End llvm namespace #endif Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=44687&r1=44686&r2=44687&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Fri Dec 7 15:42:31 2007 @@ -66,7 +66,9 @@ // Print the instruction selected machine code... if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(cerr)); - + + PM.add(createMachineLICMPass()); + // Perform register allocation to convert to a concrete x86 representation PM.add(createRegisterAllocator()); @@ -92,7 +94,7 @@ // Branch folding must be run after regalloc and prolog/epilog insertion. if (!Fast) PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - + // Fold redundant debug labels. PM.add(createDebugLabelFoldingPass()); @@ -175,7 +177,9 @@ // Print the instruction selected machine code... if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(cerr)); - + + PM.add(createMachineLICMPass()); + // Perform register allocation to convert to a concrete x86 representation PM.add(createRegisterAllocator()); @@ -204,7 +208,7 @@ // Branch folding must be run after regalloc and prolog/epilog insertion. if (!Fast) PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - + if (addPreEmitPass(PM, Fast) && PrintMachineCode) PM.add(createMachineFunctionPrinterPass(cerr)); Added: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=44687&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (added) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Fri Dec 7 15:42:31 2007 @@ -0,0 +1,336 @@ +//===-- MachineLICM.cpp - Machine Loop Invariant Code Motion Pass ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Bill Wendling and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass performs loop invariant code motion on machine instructions. We +// attempt to remove as much code from the body of a loop as possible. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "machine-licm" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Support/CFG.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetMachine.h" +#include + +using namespace llvm; + +namespace { + // Hidden options to help debugging + cl::opt + PerformLICM("machine-licm", + cl::init(false), cl::Hidden); +} + +namespace { + class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { + // Various analyses that we use... + MachineLoopInfo *LI; // Current MachineLoopInfo + MachineDominatorTree *DT; // Machine dominator tree for the current Loop + + const TargetInstrInfo *TII; + + // State that is updated as we process loops + bool Changed; // True if a loop is changed. + MachineLoop *CurLoop; // The current loop we are working on. + + // Map the def of a virtual register to the machine instruction. + std::map VRegDefs; + public: + static char ID; // Pass identification, replacement for typeid + MachineLICM() : MachineFunctionPass((intptr_t)&ID) {} + + virtual bool runOnMachineFunction(MachineFunction &MF); + + /// FIXME: Loop preheaders? + /// + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + AU.addRequired(); + AU.addRequired(); + } + private: + /// GatherAllLoops - Get all loops in depth first order. + /// + void GatherAllLoops(MachineLoop *L, SmallVectorImpl &Loops) { + const std::vector &SubLoops = L->getSubLoops(); + + for (MachineLoop::iterator + I = SubLoops.begin(), E = SubLoops.end(); I != E; ++I) + GatherAllLoops(*I, Loops); + + Loops.push_back(L); + } + + /// MapVirtualRegisterDefs - Create a map of which machine instruction + /// defines a virtual register. + /// + void MapVirtualRegisterDefs(const MachineFunction &MF); + + /// isInSubLoop - A little predicate that returns true if the specified + /// basic block is in a subloop of the current one, not the current one + /// itself. + /// + bool isInSubLoop(MachineBasicBlock *BB) { + assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop"); + + for (MachineLoop::iterator + I = CurLoop->begin(), E = CurLoop->end(); I != E; ++I) + if ((*I)->contains(BB)) + return true; // A subloop actually contains this block! + + return false; + } + + /// CanHoistInst - Checks that this instructions is one that can be hoisted + /// out of the loop. I.e., it has no side effects, isn't a control flow + /// instr, etc. + /// + bool CanHoistInst(MachineInstr &I) const { + const TargetInstrDescriptor *TID = I.getInstrDescriptor(); + MachineOpCode Opcode = TID->Opcode; + + return TII->isTriviallyReMaterializable(&I) && + // FIXME: Below necessary? + !(TII->isReturn(Opcode) || + TII->isTerminatorInstr(Opcode) || + TII->isBranch(Opcode) || + TII->isIndirectBranch(Opcode) || + TII->isBarrier(Opcode) || + TII->isCall(Opcode) || + TII->isLoad(Opcode) || // TODO: Do loads and stores. + TII->isStore(Opcode)); + } + + /// isLoopInvariantInst - Returns true if the instruction is loop + /// invariant. I.e., all virtual register operands are defined outside of + /// the loop, physical registers aren't accessed (explicitly or implicitly), + /// and the instruction is hoistable. + /// + bool isLoopInvariantInst(MachineInstr &I); + + /// FindPredecessors - Get all of the predecessors of the loop that are not + /// back-edges. + /// + void FindPredecessors(std::vector &Preds){ + const MachineBasicBlock *Header = CurLoop->getHeader(); + + for (MachineBasicBlock::const_pred_iterator + I = Header->pred_begin(), E = Header->pred_end(); I != E; ++I) + if (!CurLoop->contains(*I)) + Preds.push_back(*I); + } + + /// MoveInstToBlock - Moves the machine instruction to the bottom of the + /// predecessor basic block (but before the terminator instructions). + /// + void MoveInstToBlock(MachineBasicBlock *MBB, MachineInstr *MI) { + MachineBasicBlock::iterator Iter = MBB->getFirstTerminator(); + MBB->insert(Iter, MI); + } + + /// HoistRegion - Walk the specified region of the CFG (defined by all + /// blocks dominated by the specified block, and that are in the current + /// loop) in depth first order w.r.t the DominatorTree. This allows us to + /// visit definitions before uses, allowing us to hoist a loop body in one + /// pass without iteration. + /// + void HoistRegion(MachineDomTreeNode *N); + + /// Hoist - When an instruction is found to only use loop invariant operands + /// that is safe to hoist, this instruction is called to do the dirty work. + /// + bool Hoist(MachineInstr &MI); + }; + + char MachineLICM::ID = 0; + RegisterPass X("machine-licm", + "Machine Loop Invariant Code Motion"); +} // end anonymous namespace + +FunctionPass *llvm::createMachineLICMPass() { return new MachineLICM(); } + +/// Hoist expressions out of the specified loop. Note, alias info for inner loop +/// is not preserved so it is not a good idea to run LICM multiple times on one +/// loop. +/// +bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { + if (!PerformLICM) return false; // For debugging. + + Changed = false; + TII = MF.getTarget().getInstrInfo(); + + // Get our Loop information... + LI = &getAnalysis(); + DT = &getAnalysis(); + + for (MachineLoopInfo::iterator + I = LI->begin(), E = LI->end(); I != E; ++I) { + MachineLoop *L = *I; + CurLoop = L; + + // Visit all of the instructions of the loop. We want to visit the subloops + // first, though, so that we can hoist their invariants first into their + // containing loop before we process that loop. + SmallVector Loops; + GatherAllLoops(L, Loops); + + for (SmallVector::iterator + II = Loops.begin(), IE = Loops.end(); II != IE; ++II) { + L = *II; + + // Traverse the body of the loop in depth first order on the dominator + // tree so that we are guaranteed to see definitions before we see uses. + HoistRegion(DT->getNode(L->getHeader())); + } + } + + return Changed; +} + +/// MapVirtualRegisterDefs - Create a map of which machine instruction defines a +/// virtual register. +/// +void MachineLICM::MapVirtualRegisterDefs(const MachineFunction &MF) { + for (MachineFunction::const_iterator + I = MF.begin(), E = MF.end(); I != E; ++I) { + const MachineBasicBlock &MBB = *I; + + for (MachineBasicBlock::const_iterator + II = MBB.begin(), IE = MBB.end(); II != IE; ++II) { + const MachineInstr &MI = *II; + + if (MI.getNumOperands() > 0) { + const MachineOperand &MO = MI.getOperand(0); + + if (MO.isRegister() && MO.isDef() && + MRegisterInfo::isVirtualRegister(MO.getReg())) + VRegDefs[MO.getReg()] = &MI; + } + } + } +} + +/// HoistRegion - Walk the specified region of the CFG (defined by all blocks +/// dominated by the specified block, and that are in the current loop) in depth +/// first order w.r.t the DominatorTree. This allows us to visit definitions +/// before uses, allowing us to hoist a loop body in one pass without iteration. +/// +void MachineLICM::HoistRegion(MachineDomTreeNode *N) { + assert(N != 0 && "Null dominator tree node?"); + MachineBasicBlock *BB = N->getBlock(); + + // If this subregion is not in the top level loop at all, exit. + if (!CurLoop->contains(BB)) return; + + // Only need to process the contents of this block if it is not part of a + // subloop (which would already have been processed). + if (!isInSubLoop(BB)) + for (MachineBasicBlock::iterator + I = BB->begin(), E = BB->end(); I != E; ) { + MachineInstr &MI = *I++; + + // Try hoisting the instruction out of the loop. We can only do this if + // all of the operands of the instruction are loop invariant and if it is + // safe to hoist the instruction. + if (Hoist(MI)) + // Hoisting was successful! Remove bothersome instruction now. + MI.getParent()->remove(&MI); + } + + const std::vector &Children = N->getChildren(); + + for (unsigned I = 0, E = Children.size(); I != E; ++I) + HoistRegion(Children[I]); +} + +/// isLoopInvariantInst - Returns true if the instruction is loop +/// invariant. I.e., all virtual register operands are defined outside of the +/// loop, physical registers aren't accessed (explicitly or implicitly), and the +/// instruction is hoistable. +/// +bool MachineLICM::isLoopInvariantInst(MachineInstr &I) { + const TargetInstrDescriptor *TID = I.getInstrDescriptor(); + + // Don't hoist if this instruction implicitly reads physical registers or + // doesn't take any operands. + if (TID->ImplicitUses || !I.getNumOperands()) return false; + + if (!CanHoistInst(I)) return false; + + // The instruction is loop invariant if all of its operands are loop-invariant + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { + const MachineOperand &MO = I.getOperand(i); + + if (!MO.isRegister() || !MO.isUse()) + continue; + + unsigned Reg = MO.getReg(); + + // Don't hoist instructions that access physical registers. + if (!MRegisterInfo::isVirtualRegister(Reg)) + return false; + + assert(VRegDefs[Reg] && "Machine instr not mapped for this vreg?!"); + + // If the loop contains the definition of an operand, then the instruction + // isn't loop invariant. + if (CurLoop->contains(VRegDefs[Reg]->getParent())) + return false; + } + + // If we got this far, the instruction is loop invariant! + return true; +} + +/// Hoist - When an instruction is found to only use loop invariant operands +/// that is safe to hoist, this instruction is called to do the dirty work. +/// +bool MachineLICM::Hoist(MachineInstr &MI) { + if (!isLoopInvariantInst(MI)) return false; + + std::vector Preds; + + // Non-back-edge predecessors. + FindPredecessors(Preds); + if (Preds.empty()) return false; + + // Check that the predecessors are qualified to take the hoisted + // instruction. I.e., there is only one edge from each predecessor, and it's + // to the loop header. + for (std::vector::iterator + I = Preds.begin(), E = Preds.end(); I != E; ++I) { + MachineBasicBlock *MBB = *I; + + // FIXME: We are assuming at first that the basic blocks coming into this + // loop have only one successor each. This isn't the case in general because + // we haven't broken critical edges or added preheaders. + if (MBB->succ_size() != 1) return false; + assert(*MBB->succ_begin() == CurLoop->getHeader() && + "The predecessor doesn't feed directly into the loop header!"); + } + + // Now move the instructions to the predecessors. + for (std::vector::iterator + I = Preds.begin(), E = Preds.end(); I != E; ++I) + MoveInstToBlock(*I, MI.clone()); + + Changed = true; + return true; +} Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=44687&r1=44686&r2=44687&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Fri Dec 7 15:42:31 2007 @@ -684,12 +684,15 @@ def SUBFIC : DForm_2< 8, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "subfic $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (subc immSExt16:$imm, GPRC:$rA))]>; -def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), - "li $rD, $imm", IntGeneral, - [(set GPRC:$rD, immSExt16:$imm)]>; -def LIS : DForm_2_r0<15, (outs GPRC:$rD), (ins symbolHi:$imm), - "lis $rD, $imm", IntGeneral, - [(set GPRC:$rD, imm16ShiftedSExt:$imm)]>; + +let isReMaterializable = 1 in { + def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), + "li $rD, $imm", IntGeneral, + [(set GPRC:$rD, immSExt16:$imm)]>; + def LIS : DForm_2_r0<15, (outs GPRC:$rD), (ins symbolHi:$imm), + "lis $rD, $imm", IntGeneral, + [(set GPRC:$rD, imm16ShiftedSExt:$imm)]>; +} } let PPC970_Unit = 1 in { // FXU Operations. From clattner at apple.com Fri Dec 7 16:24:37 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Dec 2007 14:24:37 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> Message-ID: <68D7F125-2C31-491E-BCF4-DC9B04BDC777@apple.com> On Dec 7, 2007, at 1:42 PM, Bill Wendling wrote: > Author: void > Date: Fri Dec 7 15:42:31 2007 > New Revision: 44687 > > URL: http://llvm.org/viewvc/llvm-project?rev=44687&view=rev > Log: > Initial commit of the machine code LICM pass. It successfully > hoists this: > > _foo: > li r2, 0 > LBB1_1: ; bb > li r5, 0 > stw r5, 0(r3) > addi r2, r2, 1 > addi r3, r3, 4 > cmplw cr0, r2, r4 > bne cr0, LBB1_1 ; bb > LBB1_2: ; return > blr > > to: > > _foo: > li r2, 0 > li r5, 0 > LBB1_1: ; bb > stw r5, 0(r3) > addi r2, r2, 1 > addi r3, r3, 4 > cmplw cr0, r2, r4 > bne cr0, LBB1_1 ; bb > LBB1_2: ; return > blr > > ZOMG!! :-) I know you're kidding, but have you benchmarked this on the G5? In this specific case, "foo" is probably MUCH faster because the loop is one dispatch group instead of two (I think). :) -Chris From isanbard at gmail.com Fri Dec 7 18:34:58 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 7 Dec 2007 16:34:58 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <68D7F125-2C31-491E-BCF4-DC9B04BDC777@apple.com> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> <68D7F125-2C31-491E-BCF4-DC9B04BDC777@apple.com> Message-ID: <16e5fdf90712071634h1c12b265y190ff4ceb23ef589@mail.gmail.com> On Dec 7, 2007 2:24 PM, Chris Lattner wrote: > > I know you're kidding, but have you benchmarked this on the G5? In > this specific case, "foo" is probably MUCH faster because the loop is > one dispatch group instead of two (I think). :) > It made this program slower: $ cat t.c #include #define SIZE 100000 int arr[SIZE]; __attribute__((noinline)) void foo(int *arr, unsigned size) { unsigned i = 0; do { arr[i++] = 0; } while (i < size); } int main() { int i; for (i = 0; i < SIZE; ++i) foo(arr, SIZE); return 0; } $ time ./t.old real 0m15.107s user 0m15.095s sys 0m0.012s $ time ./t.new real 0m20.088s user 0m20.075s sys 0m0.013s But when I set the alignment of the loop in main to 8, it got slightly faster: $ time ./t.new real 0m15.090s user 0m15.079s sys 0m0.010s So there's some type of alignment thing that's getting in the way, but it's encouraging for an initial pass that moved 3 instructions total. :-) -bw From isanbard at gmail.com Fri Dec 7 18:39:05 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 08 Dec 2007 00:39:05 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r44689 - /llvm-gcc-4.0/trunk/build_gcc Message-ID: <200712080039.lB80d5j0006167@zion.cs.uiuc.edu> Author: void Date: Fri Dec 7 18:39:04 2007 New Revision: 44689 URL: http://llvm.org/viewvc/llvm-project?rev=44689&view=rev Log: Backport driver-driver linkage hack from 4.2 Modified: llvm-gcc-4.0/trunk/build_gcc Modified: llvm-gcc-4.0/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/build_gcc?rev=44689&r1=44688&r2=44689&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/build_gcc (original) +++ llvm-gcc-4.0/trunk/build_gcc Fri Dec 7 18:39:04 2007 @@ -511,11 +511,17 @@ ln -s -f ../../../$DEST_ROOT/bin/llvm-gcc-$MAJ_VERS llvm-gcc-$MAJ_VERS || exit 1 ln -s -f ../../../$DEST_ROOT/bin/llvm-g++-$MAJ_VERS llvm-g++-$MAJ_VERS || exit 1 - # Copy one of the libllvmgcc.dylib's up to libexec/gcc. +# FIXME: This is a hack to get things working. +for h in $HOSTS ; do + ln -s -f ../../../$DEST_ROOT/bin/$h-apple-darwin$DARWIN_VERS-llvm-gcc-$MAJ_VERS $h-apple-darwin$DARWIN_VERS-llvm-gcc-$MAJ_VERS || exit 1 + ln -s -f ../../../$DEST_ROOT/bin/$h-apple-darwin$DARWIN_VERS-llvm-g++-$MAJ_VERS $h-apple-darwin$DARWIN_VERS-llvm-g++-$MAJ_VERS || exit 1 +done + +# Copy one of the libllvmgcc.dylib's up to libexec/gcc. cp $DEST_DIR/$DEST_ROOT/libexec/gcc/$BUILD-apple-darwin$DARWIN_VERS/$VERS/libllvmgcc.dylib \ $DEST_DIR/$DEST_ROOT/libexec/gcc/ - # Replace the installed ones with symlinks to the common one. +# Replace the installed ones with symlinks to the common one. for t in $TARGETS ; do cd $DEST_DIR/$DEST_ROOT/libexec/gcc/$t-apple-darwin$DARWIN_VERS/$VERS/ rm libllvmgcc.dylib From evan.cheng at apple.com Fri Dec 7 18:42:59 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 7 Dec 2007 16:42:59 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> Message-ID: On Dec 7, 2007, at 1:42 PM, Bill Wendling wrote: > > > _foo: > li r2, 0 > LBB1_1: ; bb > li r5, 0 > stw r5, 0(r3) > addi r2, r2, 1 > addi r3, r3, 4 > cmplw cr0, r2, r4 > bne cr0, LBB1_1 ; bb > LBB1_2: ; return > blr > > to: > > _foo: > li r2, 0 > li r5, 0 > LBB1_1: ; bb > stw r5, 0(r3) > addi r2, r2, 1 > addi r3, r3, 4 > cmplw cr0, r2, r4 > bne cr0, LBB1_1 ; bb > LBB1_2: ; return > blr > > ZOMG!! :-) Nicely done! > > + > +#define DEBUG_TYPE "machine-licm" > +#include "llvm/ADT/SmallVector.h" > +#include "llvm/ADT/Statistic.h" > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineDominators.h" > +#include "llvm/CodeGen/MachineInstr.h" > +#include "llvm/CodeGen/MachineLoopInfo.h" > +#include "llvm/CodeGen/Passes.h" > +#include "llvm/Target/TargetInstrInfo.h" > +#include "llvm/Support/CFG.h" > +#include "llvm/Support/CommandLine.h" > +#include "llvm/Support/Compiler.h" > +#include "llvm/Support/Debug.h" > +#include "llvm/Target/MRegisterInfo.h" > +#include "llvm/Target/TargetMachine.h" > +#include > + > +using namespace llvm; > + > +namespace { > + // Hidden options to help debugging > + cl::opt > + PerformLICM("machine-licm", > + cl::init(false), cl::Hidden); > +} > + > +namespace { > + class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { > + // Various analyses that we use... > + MachineLoopInfo *LI; // Current MachineLoopInfo > + MachineDominatorTree *DT; // Machine dominator tree for the > current Loop > + > + const TargetInstrInfo *TII; > + > + // State that is updated as we process loops > + bool Changed; // True if a loop is changed. > + MachineLoop *CurLoop; // The current loop we are working > on. > + > + // Map the def of a virtual register to the machine instruction. > + std::map VRegDefs; Consider using IndexedMap. > > + public: > + static char ID; // Pass identification, replacement for typeid > + MachineLICM() : MachineFunctionPass((intptr_t)&ID) {} > + > + virtual bool runOnMachineFunction(MachineFunction &MF); > + > + /// FIXME: Loop preheaders? > + /// > + virtual void getAnalysisUsage(AnalysisUsage &AU) const { > + AU.setPreservesCFG(); > + AU.addRequired(); > + AU.addRequired(); > + } > + private: > + /// GatherAllLoops - Get all loops in depth first order. > + /// > + void GatherAllLoops(MachineLoop *L, > SmallVectorImpl &Loops) { > + const std::vector &SubLoops = L->getSubLoops(); > + > + for (MachineLoop::iterator > + I = SubLoops.begin(), E = SubLoops.end(); I != E; ++I) > + GatherAllLoops(*I, Loops); > + > + Loops.push_back(L); > + } > + > + /// MapVirtualRegisterDefs - Create a map of which machine > instruction > + /// defines a virtual register. > + /// > + void MapVirtualRegisterDefs(const MachineFunction &MF); > + > + /// isInSubLoop - A little predicate that returns true if the > specified > + /// basic block is in a subloop of the current one, not the > current one > + /// itself. > + /// > + bool isInSubLoop(MachineBasicBlock *BB) { > + assert(CurLoop->contains(BB) && "Only valid if BB is IN the > loop"); > + > + for (MachineLoop::iterator > + I = CurLoop->begin(), E = CurLoop->end(); I != E; ++I) > + if ((*I)->contains(BB)) > + return true; // A subloop actually contains this block! > + > + return false; > + } > + > + /// CanHoistInst - Checks that this instructions is one that > can be hoisted > + /// out of the loop. I.e., it has no side effects, isn't a > control flow > + /// instr, etc. > + /// > + bool CanHoistInst(MachineInstr &I) const { > + const TargetInstrDescriptor *TID = I.getInstrDescriptor(); > + MachineOpCode Opcode = TID->Opcode; > + > + return TII->isTriviallyReMaterializable(&I) && > + // FIXME: Below necessary? > + !(TII->isReturn(Opcode) || > + TII->isTerminatorInstr(Opcode) || > + TII->isBranch(Opcode) || > + TII->isIndirectBranch(Opcode) || > + TII->isBarrier(Opcode) || > + TII->isCall(Opcode) || > + TII->isLoad(Opcode) || // TODO: Do loads and stores. > + TII->isStore(Opcode)); > + } Since you are touching this... When you have a chance, please rename it to something like hasNoSideEffect(). > > + > + /// isLoopInvariantInst - Returns true if the instruction is loop > + /// invariant. I.e., all virtual register operands are defined > outside of > + /// the loop, physical registers aren't accessed (explicitly or > implicitly), > + /// and the instruction is hoistable. > + /// > + bool isLoopInvariantInst(MachineInstr &I); > + > + /// FindPredecessors - Get all of the predecessors of the loop > that are not > + /// back-edges. > + /// > + void FindPredecessors(std::vector &Preds){ > + const MachineBasicBlock *Header = CurLoop->getHeader(); > + > + for (MachineBasicBlock::const_pred_iterator > + I = Header->pred_begin(), E = Header->pred_end(); I != > E; ++I) > + if (!CurLoop->contains(*I)) > + Preds.push_back(*I); > + } > + > + /// MoveInstToBlock - Moves the machine instruction to the > bottom of the > + /// predecessor basic block (but before the terminator > instructions). > + /// > + void MoveInstToBlock(MachineBasicBlock *MBB, MachineInstr *MI) { > + MachineBasicBlock::iterator Iter = MBB->getFirstTerminator(); > + MBB->insert(Iter, MI); > + } Poorly named. :-) MoveInstToEndOfBlock? > > + > + /// HoistRegion - Walk the specified region of the CFG (defined > by all > + /// blocks dominated by the specified block, and that are in > the current > + /// loop) in depth first order w.r.t the DominatorTree. This > allows us to > + /// visit definitions before uses, allowing us to hoist a loop > body in one > + /// pass without iteration. > + /// > + void HoistRegion(MachineDomTreeNode *N); > > + > + /// Hoist - When an instruction is found to only use loop > invariant operands > + /// that is safe to hoist, this instruction is called to do the > dirty work. > + /// > + bool Hoist(MachineInstr &MI); > + }; > + > + char MachineLICM::ID = 0; > + RegisterPass X("machine-licm", > + "Machine Loop Invariant Code Motion"); > +} // end anonymous namespace > + > +FunctionPass *llvm::createMachineLICMPass() { return new > MachineLICM(); } > + > +/// Hoist expressions out of the specified loop. Note, alias info > for inner loop > +/// is not preserved so it is not a good idea to run LICM multiple > times on one > +/// loop. > +/// > +bool MachineLICM::runOnMachineFunction(MachineFunction &MF) { > + if (!PerformLICM) return false; // For debugging. > + > + Changed = false; > + TII = MF.getTarget().getInstrInfo(); > + > + // Get our Loop information... > + LI = &getAnalysis(); > + DT = &getAnalysis(); > + > + for (MachineLoopInfo::iterator > + I = LI->begin(), E = LI->end(); I != E; ++I) { > + MachineLoop *L = *I; > + CurLoop = L; > + > + // Visit all of the instructions of the loop. We want to visit > the subloops > + // first, though, so that we can hoist their invariants first > into their > + // containing loop before we process that loop. > + SmallVector Loops; > + GatherAllLoops(L, Loops); Seems to me this can be smarter. When you are gathering the loops, put loops of greater depth in the front of the queue then HoistRegion won't have to check if the BB is in the current loop level? > > + > + for (SmallVector::iterator > + II = Loops.begin(), IE = Loops.end(); II != IE; ++II) { > + L = *II; > + > + // Traverse the body of the loop in depth first order on the > dominator > + // tree so that we are guaranteed to see definitions before > we see uses. > + HoistRegion(DT->getNode(L->getHeader())); > + } > + } > + > + return Changed; > +} > + > +/// MapVirtualRegisterDefs - Create a map of which machine > instruction defines a > +/// virtual register. > +/// > +void MachineLICM::MapVirtualRegisterDefs(const MachineFunction &MF) { > + for (MachineFunction::const_iterator > + I = MF.begin(), E = MF.end(); I != E; ++I) { > + const MachineBasicBlock &MBB = *I; > + > + for (MachineBasicBlock::const_iterator > + II = MBB.begin(), IE = MBB.end(); II != IE; ++II) { > + const MachineInstr &MI = *II; > + > + if (MI.getNumOperands() > 0) { > + const MachineOperand &MO = MI.getOperand(0); This is not right. You are assuming only one def and it must be the first operand. Neither is necessarily true. > > + > + if (MO.isRegister() && MO.isDef() && > + MRegisterInfo::isVirtualRegister(MO.getReg())) > + VRegDefs[MO.getReg()] = &MI; > + } > + } > + } > +} > + > +/// HoistRegion - Walk the specified region of the CFG (defined by > all blocks > +/// dominated by the specified block, and that are in the current > loop) in depth > +/// first order w.r.t the DominatorTree. This allows us to visit > definitions > +/// before uses, allowing us to hoist a loop body in one pass > without iteration. > +/// > +void MachineLICM::HoistRegion(MachineDomTreeNode *N) { > + assert(N != 0 && "Null dominator tree node?"); > + MachineBasicBlock *BB = N->getBlock(); > + > + // If this subregion is not in the top level loop at all, exit. > + if (!CurLoop->contains(BB)) return; > + > + // Only need to process the contents of this block if it is not > part of a > + // subloop (which would already have been processed). > + if (!isInSubLoop(BB)) Like I said earlier, I think this check can be eliminated if we visit the inner most loops first (and perhaps keep track which BB has been processed?) > > + for (MachineBasicBlock::iterator > + I = BB->begin(), E = BB->end(); I != E; ) { > + MachineInstr &MI = *I++; > + > + // Try hoisting the instruction out of the loop. We can only > do this if > + // all of the operands of the instruction are loop invariant > and if it is > + // safe to hoist the instruction. > + if (Hoist(MI)) > + // Hoisting was successful! Remove bothersome instruction > now. > + MI.getParent()->remove(&MI); Why not have Hoist remove the MI? > > + } > + > + const std::vector &Children = N- > >getChildren(); > + > + for (unsigned I = 0, E = Children.size(); I != E; ++I) > + HoistRegion(Children[I]); > +} > + > +/// isLoopInvariantInst - Returns true if the instruction is loop > +/// invariant. I.e., all virtual register operands are defined > outside of the > +/// loop, physical registers aren't accessed (explicitly or > implicitly), and the > +/// instruction is hoistable. > +/// > +bool MachineLICM::isLoopInvariantInst(MachineInstr &I) { > + const TargetInstrDescriptor *TID = I.getInstrDescriptor(); > + > + // Don't hoist if this instruction implicitly reads physical > registers or > + // doesn't take any operands. > + if (TID->ImplicitUses || !I.getNumOperands()) return false; The comment is wrong. It's ok to lift something that has no uses but produces result(s), right? "doesn't take any operands" to me means something that doesn't have any uses. > > + > + if (!CanHoistInst(I)) return false; Perhaps fold the earlier check into CanHoistInst()? > > + > + // The instruction is loop invariant if all of its operands are > loop-invariant > + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { > + const MachineOperand &MO = I.getOperand(i); > + > + if (!MO.isRegister() || !MO.isUse()) > + continue; > + > + unsigned Reg = MO.getReg(); > + > + // Don't hoist instructions that access physical registers. > + if (!MRegisterInfo::isVirtualRegister(Reg)) > + return false; > + > + assert(VRegDefs[Reg] && "Machine instr not mapped for this > vreg?!"); > + > + // If the loop contains the definition of an operand, then the > instruction > + // isn't loop invariant. > + if (CurLoop->contains(VRegDefs[Reg]->getParent())) > + return false; Hmmm. I am not sure about this. What if the definition is in the preheader? Does contains() returns true? Chris, Owen? Also, I fear this might be slow. When you are creating the VReg -> MI map, perhaps you should create a VReg -> loop map as well? > > + } > + > + // If we got this far, the instruction is loop invariant! > + return true; > +} > + > +/// Hoist - When an instruction is found to only use loop invariant > operands > +/// that is safe to hoist, this instruction is called to do the > dirty work. > +/// > +bool MachineLICM::Hoist(MachineInstr &MI) { > + if (!isLoopInvariantInst(MI)) return false; > + > + std::vector Preds; > + > + // Non-back-edge predecessors. > + FindPredecessors(Preds); Consider caching some of these info? > > + if (Preds.empty()) return false; > > + > + // Check that the predecessors are qualified to take the hoisted > + // instruction. I.e., there is only one edge from each > predecessor, and it's > + // to the loop header. > + for (std::vector::iterator > + I = Preds.begin(), E = Preds.end(); I != E; ++I) { > + MachineBasicBlock *MBB = *I; > + > + // FIXME: We are assuming at first that the basic blocks coming > into this > + // loop have only one successor each. This isn't the case in > general because > + // we haven't broken critical edges or added preheaders. > + if (MBB->succ_size() != 1) return false; > + assert(*MBB->succ_begin() == CurLoop->getHeader() && > + "The predecessor doesn't feed directly into the loop > header!"); > + } Are we going to create a preheader to hoist LICM to? Then we won't need to do all these checking? I am entirely sure about it. Someone please chime in. > > + > + // Now move the instructions to the predecessors. > + for (std::vector::iterator > + I = Preds.begin(), E = Preds.end(); I != E; ++I) > + MoveInstToBlock(*I, MI.clone()); This will create multiple copies, it seems bad. Again, this should be fixable with a loop preheader? Very nice first cut! Evan > > + > + Changed = true; > + return true; > +} > > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=44687&r1=44686&r2=44687&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Fri Dec 7 > 15:42:31 2007 > @@ -684,12 +684,15 @@ > def SUBFIC : DForm_2< 8, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), > "subfic $rD, $rA, $imm", IntGeneral, > [(set GPRC:$rD, (subc immSExt16:$imm, GPRC: > $rA))]>; > -def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), > - "li $rD, $imm", IntGeneral, > - [(set GPRC:$rD, immSExt16:$imm)]>; > -def LIS : DForm_2_r0<15, (outs GPRC:$rD), (ins symbolHi:$imm), > - "lis $rD, $imm", IntGeneral, > - [(set GPRC:$rD, imm16ShiftedSExt:$imm)]>; > + > +let isReMaterializable = 1 in { > + def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), > + "li $rD, $imm", IntGeneral, > + [(set GPRC:$rD, immSExt16:$imm)]>; > + def LIS : DForm_2_r0<15, (outs GPRC:$rD), (ins symbolHi:$imm), > + "lis $rD, $imm", IntGeneral, > + [(set GPRC:$rD, imm16ShiftedSExt:$imm)]>; > +} > } > > let PPC970_Unit = 1 in { // FXU Operations. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From cfr at adobe.com Fri Dec 7 18:53:13 2007 From: cfr at adobe.com (Chuck Rose III) Date: Sat, 08 Dec 2007 00:53:13 -0000 Subject: [llvm-commits] [llvm] r44690 - /llvm/trunk/win32/CodeGen/CodeGen.vcproj Message-ID: <200712080053.lB80rDMV007106@zion.cs.uiuc.edu> Author: cfr Date: Fri Dec 7 18:53:13 2007 New Revision: 44690 URL: http://llvm.org/viewvc/llvm-project?rev=44690&view=rev Log: Adding MachineLoopInfo.h,.cpp and MachineLICP.cpp to VStudio build Modified: llvm/trunk/win32/CodeGen/CodeGen.vcproj Modified: llvm/trunk/win32/CodeGen/CodeGen.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/CodeGen/CodeGen.vcproj?rev=44690&r1=44689&r2=44690&view=diff ============================================================================== --- llvm/trunk/win32/CodeGen/CodeGen.vcproj (original) +++ llvm/trunk/win32/CodeGen/CodeGen.vcproj Fri Dec 7 18:53:13 2007 @@ -377,6 +377,14 @@ > + + + + @@ -603,6 +611,10 @@ > + + From evan.cheng at apple.com Fri Dec 7 19:00:21 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 08 Dec 2007 01:00:21 -0000 Subject: [llvm-commits] [llvm] r44691 - /llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Message-ID: <200712080100.lB810MlY007859@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 7 19:00:21 2007 New Revision: 44691 URL: http://llvm.org/viewvc/llvm-project?rev=44691&view=rev Log: Fix a compilation warning. Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=44691&r1=44690&r2=44691&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Fri Dec 7 19:00:21 2007 @@ -615,7 +615,7 @@ bool PPCRegisterInfo::canFoldMemoryOperand(MachineInstr *MI, SmallVectorImpl &Ops) const { - if (Ops.size() != 1) return NULL; + if (Ops.size() != 1) return false; // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because // it takes more than one instruction to store it. From evan.cheng at apple.com Fri Dec 7 19:00:31 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 08 Dec 2007 01:00:31 -0000 Subject: [llvm-commits] [llvm] r44692 - /llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Message-ID: <200712080100.lB810VdA007880@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 7 19:00:31 2007 New Revision: 44692 URL: http://llvm.org/viewvc/llvm-project?rev=44692&view=rev Log: Fix a compilation warning. Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=44692&r1=44691&r2=44692&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Fri Dec 7 19:00:31 2007 @@ -429,7 +429,7 @@ bool ARMRegisterInfo::canFoldMemoryOperand(MachineInstr *MI, SmallVectorImpl &Ops) const { - if (Ops.size() != 1) return NULL; + if (Ops.size() != 1) return 0; unsigned OpNum = Ops[0]; unsigned Opc = MI->getOpcode(); From evan.cheng at apple.com Fri Dec 7 19:01:07 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 08 Dec 2007 01:01:07 -0000 Subject: [llvm-commits] [llvm] r44694 - /llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Message-ID: <200712080101.lB8117QX007927@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 7 19:01:07 2007 New Revision: 44694 URL: http://llvm.org/viewvc/llvm-project?rev=44694&view=rev Log: Doh Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=44694&r1=44693&r2=44694&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Fri Dec 7 19:01:07 2007 @@ -429,7 +429,7 @@ bool ARMRegisterInfo::canFoldMemoryOperand(MachineInstr *MI, SmallVectorImpl &Ops) const { - if (Ops.size() != 1) return 0; + if (Ops.size() != 1) return false; unsigned OpNum = Ops[0]; unsigned Opc = MI->getOpcode(); From clattner at apple.com Fri Dec 7 19:01:22 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Dec 2007 17:01:22 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> Message-ID: <0E5C8FDD-9976-4C00-85AB-858812940BE5@apple.com> >> + // Visit all of the instructions of the loop. We want to visit >> the subloops >> + // first, though, so that we can hoist their invariants first >> into their >> + // containing loop before we process that loop. >> + SmallVector Loops; >> + GatherAllLoops(L, Loops); > > Seems to me this can be smarter. When you are gathering the loops, put > loops of greater depth in the front of the queue then HoistRegion > won't have to check if the BB is in the current loop level? This should do a simple postorder traversal of the loop nest, there is no need to make a vector of the loops. This ensures you visit inner loops before outer loops etc. >> + // If the loop contains the definition of an operand, then the >> instruction >> + // isn't loop invariant. >> + if (CurLoop->contains(VRegDefs[Reg]->getParent())) >> + return false; > > Hmmm. I am not sure about this. What if the definition is in the > preheader? Does contains() returns true? Chris, Owen? a preheader is outside the loop. The header is the "top" of the loop. >> + // FIXME: We are assuming at first that the basic blocks coming >> into this >> + // loop have only one successor each. This isn't the case in >> general because >> + // we haven't broken critical edges or added preheaders. >> + if (MBB->succ_size() != 1) return false; >> + assert(*MBB->succ_begin() == CurLoop->getHeader() && >> + "The predecessor doesn't feed directly into the loop >> header!"); >> + } > > Are we going to create a preheader to hoist LICM to? Then we won't > need to do all these checking? I am entirely sure about it. Someone > please chime in. Step #0 is to only work with simple loop forms. Going forward, bill will generalize this to handle more cases. >> >> + >> + // Now move the instructions to the predecessors. >> + for (std::vector::iterator >> + I = Preds.begin(), E = Preds.end(); I != E; ++I) >> + MoveInstToBlock(*I, MI.clone()); > > This will create multiple copies, it seems bad. Again, this should be > fixable with a loop preheader? Furthermore, this won't work, you'd have to insert phi nodes etc. You really really really don't want to do this bill. Only handle loops that have a header with one predecessor that is outside the loop plz, Very nice bill! -Chris From clattner at apple.com Fri Dec 7 19:02:31 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 7 Dec 2007 17:02:31 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <16e5fdf90712071634h1c12b265y190ff4ceb23ef589@mail.gmail.com> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> <68D7F125-2C31-491E-BCF4-DC9B04BDC777@apple.com> <16e5fdf90712071634h1c12b265y190ff4ceb23ef589@mail.gmail.com> Message-ID: > But when I set the alignment of the loop in main to 8, it got > slightly faster: > > $ time ./t.new > > real 0m15.090s > user 0m15.079s > sys 0m0.010s > > So there's some type of alignment thing that's getting in the way, but > it's encouraging for an initial pass that moved 3 instructions total. > :-) Ah right, to get stable performance and measure just the instruction change, you should align the loop top to 16 for each (just for measurment purposes) -chris From isanbard at gmail.com Fri Dec 7 19:21:54 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 7 Dec 2007 17:21:54 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <0E5C8FDD-9976-4C00-85AB-858812940BE5@apple.com> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> <0E5C8FDD-9976-4C00-85AB-858812940BE5@apple.com> Message-ID: <16e5fdf90712071721n4b70dedemec4432a4d08700e9@mail.gmail.com> On Dec 7, 2007 5:01 PM, Chris Lattner wrote: > >> + // Visit all of the instructions of the loop. We want to visit > >> the subloops > >> + // first, though, so that we can hoist their invariants first > >> into their > >> + // containing loop before we process that loop. > >> + SmallVector Loops; > >> + GatherAllLoops(L, Loops); > > > > Seems to me this can be smarter. When you are gathering the loops, put > > loops of greater depth in the front of the queue then HoistRegion > > won't have to check if the BB is in the current loop level? > > This should do a simple postorder traversal of the loop nest, there > is no need to make a vector of the loops. This ensures you visit > inner loops before outer loops etc. > Doh! Yeah, it's easier to just do it without the vector. > >> + // Now move the instructions to the predecessors. > >> + for (std::vector::iterator > >> + I = Preds.begin(), E = Preds.end(); I != E; ++I) > >> + MoveInstToBlock(*I, MI.clone()); > > > > This will create multiple copies, it seems bad. Again, this should be > > fixable with a loop preheader? > > Furthermore, this won't work, you'd have to insert phi nodes etc. > You really really really don't want to do this bill. Only handle > loops that have a header with one predecessor that is outside the > loop plz, > Ah! Good point. When there's pre-headers, I'll be able to handle this much nicer. In the meantime, I'll make sure that there's only one predecessor. -bw From resistor at mac.com Fri Dec 7 19:37:09 2007 From: resistor at mac.com (Owen Anderson) Date: Sat, 08 Dec 2007 01:37:09 -0000 Subject: [llvm-commits] [llvm] r44695 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp Message-ID: <200712080137.lB81b9B5010382@zion.cs.uiuc.edu> Author: resistor Date: Fri Dec 7 19:37:09 2007 New Revision: 44695 URL: http://llvm.org/viewvc/llvm-project?rev=44695&view=rev Log: Fix several cache coherence bugs in MemDep/GVN that were found. Also add some (disabled) debugging code to make such problems easier to diagnose in the future, written by Duncan Sands. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=44695&r1=44694&r2=44695&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Dec 7 19:37:09 2007 @@ -52,6 +52,8 @@ reverseDepMapType reverseDepNonLocal; public: + void ping(Instruction* D); + // Special marker indicating that the query has no dependency // in the specified block. static Instruction* const NonLocal; Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=44695&r1=44694&r2=44695&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Dec 7 19:37:09 2007 @@ -40,6 +40,31 @@ static RegisterPass X("memdep", "Memory Dependence Analysis"); +void MemoryDependenceAnalysis::ping(Instruction *D) { + for (depMapType::iterator I = depGraphLocal.begin(), E = depGraphLocal.end(); + I != E; ++I) { + assert(I->first != D); + assert(I->second.first != D); + } + + for (nonLocalDepMapType::iterator I = depGraphNonLocal.begin(), E = depGraphNonLocal.end(); + I != E; ++I) { + assert(I->first != D); + } + + for (reverseDepMapType::iterator I = reverseDep.begin(), E = reverseDep.end(); + I != E; ++I) + for (SmallPtrSet::iterator II = I->second.begin(), EE = I->second.end(); + II != EE; ++II) + assert(*II != D); + + for (reverseDepMapType::iterator I = reverseDepNonLocal.begin(), E = reverseDepNonLocal.end(); + I != E; ++I) + for (SmallPtrSet::iterator II = I->second.begin(), EE = I->second.end(); + II != EE; ++II) + assert(*II != D); +} + /// getAnalysisUsage - Does not modify anything. It uses Alias Analysis. /// void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { @@ -54,6 +79,8 @@ Instruction* start, BasicBlock* block) { + std::pair& cachedResult = + depGraphLocal[C.getInstruction()]; AliasAnalysis& AA = getAnalysis(); TargetData& TD = getAnalysis(); BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin(); @@ -100,8 +127,8 @@ if (result != AliasAnalysis::DoesNotAccessMemory && result != AliasAnalysis::OnlyReadsMemory) { if (!start && !block) { - depGraphLocal.insert(std::make_pair(C.getInstruction(), - std::make_pair(QI, true))); + cachedResult.first = QI; + cachedResult.second = true; reverseDep[QI].insert(C.getInstruction()); } return QI; @@ -113,8 +140,8 @@ if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) { if (!start && !block) { - depGraphLocal.insert(std::make_pair(C.getInstruction(), - std::make_pair(QI, true))); + cachedResult.first = QI; + cachedResult.second = true; reverseDep[QI].insert(C.getInstruction()); } return QI; @@ -122,8 +149,8 @@ } // No dependence found - depGraphLocal.insert(std::make_pair(C.getInstruction(), - std::make_pair(NonLocal, true))); + cachedResult.first = NonLocal; + cachedResult.second = true; reverseDep[NonLocal].insert(C.getInstruction()); return NonLocal; } @@ -265,13 +292,15 @@ BasicBlock::iterator QI = query; // Check for a cached result - std::pair cachedResult = depGraphLocal[query]; + std::pair& cachedResult = depGraphLocal[query]; // If we have a _confirmed_ cached entry, return it - if (cachedResult.second) - return cachedResult.first; - else if (cachedResult.first && cachedResult.first != NonLocal) - // If we have an unconfirmed cached entry, we can start our search from there - QI = cachedResult.first; + if (!block && !start) { + if (cachedResult.second) + return cachedResult.first; + else if (cachedResult.first && cachedResult.first != NonLocal) + // If we have an unconfirmed cached entry, we can start our search from there + QI = cachedResult.first; + } if (start) QI = start; @@ -322,7 +351,8 @@ // All volatile loads/stores depend on each other if (queryIsVolatile && S->isVolatile()) { if (!start && !block) { - depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true))); + cachedResult.first = S; + cachedResult.second = true; reverseDep[S].insert(query); } @@ -335,7 +365,8 @@ // All volatile loads/stores depend on each other if (queryIsVolatile && L->isVolatile()) { if (!start && !block) { - depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true))); + cachedResult.first = L; + cachedResult.second = true; reverseDep[L].insert(query); } @@ -370,8 +401,8 @@ continue; if (!start && !block) { - depGraphLocal.insert(std::make_pair(query, - std::make_pair(QI, true))); + cachedResult.first = QI; + cachedResult.second = true; reverseDep[QI].insert(query); } @@ -393,8 +424,8 @@ continue; if (!start && !block) { - depGraphLocal.insert(std::make_pair(query, - std::make_pair(QI, true))); + cachedResult.first = QI; + cachedResult.second = true; reverseDep[QI].insert(query); } @@ -405,8 +436,8 @@ // If we found nothing, return the non-local flag if (!start && !block) { - depGraphLocal.insert(std::make_pair(query, - std::make_pair(NonLocal, true))); + cachedResult.first = NonLocal; + cachedResult.second = true; reverseDep[NonLocal].insert(query); } @@ -420,6 +451,14 @@ // Figure out the new dep for things that currently depend on rem Instruction* newDep = NonLocal; + reverseDep[depGraphLocal[rem].first].erase(rem); + + for (DenseMap::iterator DI = + depGraphNonLocal[rem].begin(), DE = depGraphNonLocal[rem].end(); + DI != DE; ++DI) + if (DI->second != None) + reverseDepNonLocal[DI->second].erase(rem); + depMapType::iterator depGraphEntry = depGraphLocal.find(rem); if (depGraphEntry != depGraphLocal.end()) { @@ -449,10 +488,11 @@ // Mark it as unconfirmed as long as it is not the non-local flag depGraphLocal[*I] = std::make_pair(newDep, !newDep); } - - reverseDep.erase(rem); } + depGraphLocal.erase(rem); + reverseDep.erase(rem); + if (reverseDepNonLocal.count(rem)) { SmallPtrSet& set = reverseDepNonLocal[rem]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); @@ -463,8 +503,12 @@ if (DI->second == rem) DI->second = Dirty; - reverseDepNonLocal.erase(rem); } + + reverseDepNonLocal.erase(rem); + nonLocalDepMapType::iterator I = depGraphNonLocal.find(rem); + if (I != depGraphNonLocal.end()) + depGraphNonLocal.erase(I); getAnalysis().deleteValue(rem); } Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=44695&r1=44694&r2=44695&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Dec 7 19:37:09 2007 @@ -1062,6 +1062,10 @@ } } + // Remove it! + MemoryDependenceAnalysis& MD = getAnalysis(); + MD.removeInstruction(I); + VN.erase(I); I->replaceAllUsesWith(repl); toErase.push_back(I); @@ -1128,11 +1132,11 @@ // Avoid iterator invalidation ++BI; - + for (SmallVector::iterator I = toErase.begin(), E = toErase.end(); I != E; ++I) (*I)->eraseFromParent(); - + toErase.clear(); } } From isanbard at gmail.com Fri Dec 7 19:43:02 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 7 Dec 2007 17:43:02 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> Message-ID: <16e5fdf90712071743p3eeb6e44sf09cff45c50aa159@mail.gmail.com> On Dec 7, 2007 4:42 PM, Evan Cheng wrote: > > Nicely done! > Thx! :-) > > + // Map the def of a virtual register to the machine instruction. > > + std::map VRegDefs; > > Consider using IndexedMap. > Okay. > > + bool CanHoistInst(MachineInstr &I) const { > > + const TargetInstrDescriptor *TID = I.getInstrDescriptor(); > > + MachineOpCode Opcode = TID->Opcode; > > + > > + return TII->isTriviallyReMaterializable(&I) && > > + // FIXME: Below necessary? > > + !(TII->isReturn(Opcode) || > > + TII->isTerminatorInstr(Opcode) || > > + TII->isBranch(Opcode) || > > + TII->isIndirectBranch(Opcode) || > > + TII->isBarrier(Opcode) || > > + TII->isCall(Opcode) || > > + TII->isLoad(Opcode) || // TODO: Do loads and stores. > > + TII->isStore(Opcode)); > > + } > > Since you are touching this... When you have a chance, please rename > it to something like hasNoSideEffect(). > Okay. I'll do it in a future patch. > > + void MoveInstToBlock(MachineBasicBlock *MBB, MachineInstr *MI) { > > + MachineBasicBlock::iterator Iter = MBB->getFirstTerminator(); > > + MBB->insert(Iter, MI); > > + } > > Poorly named. :-) MoveInstToEndOfBlock? > Sounds good. > > + // Visit all of the instructions of the loop. We want to visit > > the subloops > > + // first, though, so that we can hoist their invariants first > > into their > > + // containing loop before we process that loop. > > + SmallVector Loops; > > + GatherAllLoops(L, Loops); > > Seems to me this can be smarter. When you are gathering the loops, put > loops of greater depth in the front of the queue then HoistRegion > won't have to check if the BB is in the current loop level? > > > + for (MachineBasicBlock::const_iterator > > + II = MBB.begin(), IE = MBB.end(); II != IE; ++II) { > > + const MachineInstr &MI = *II; > > + > > + if (MI.getNumOperands() > 0) { > > + const MachineOperand &MO = MI.getOperand(0); > > This is not right. You are assuming only one def and it must be the > first operand. Neither is necessarily true. > Okay. > > + // If this subregion is not in the top level loop at all, exit. > > + if (!CurLoop->contains(BB)) return; > > + > > + // Only need to process the contents of this block if it is not > > part of a > > + // subloop (which would already have been processed). > > + if (!isInSubLoop(BB)) > > Like I said earlier, I think this check can be eliminated if we visit > the inner most loops first (and perhaps keep track which BB has been > processed?) > I'm not sure I understand. I was under the impression that MachineDomTreeNode would give blocks from the loop and its subloops. If we keep track of those visited, I suppose we could simplify this check... > > + // Try hoisting the instruction out of the loop. We can only > > do this if > > + // all of the operands of the instruction are loop invariant > > and if it is > > + // safe to hoist the instruction. > > + if (Hoist(MI)) > > + // Hoisting was successful! Remove bothersome instruction > > now. > > + MI.getParent()->remove(&MI); > > Why not have Hoist remove the MI? > I had a bug earlier where I was invalidating an iterator. I think it's no longer the case, so this can be moved to Hoist instead. > > + // Don't hoist if this instruction implicitly reads physical > > registers or > > + // doesn't take any operands. > > + if (TID->ImplicitUses || !I.getNumOperands()) return false; > > The comment is wrong. It's ok to lift something that has no uses but > produces result(s), right? "doesn't take any operands" to me means > something that doesn't have any uses. > I was thinking about things like "emms" which don't seem to use anything, but have definite side effects. Or will this be picked up in the earlier check isTriviallyReMaterializable? > > + if (!CanHoistInst(I)) return false; > > Perhaps fold the earlier check into CanHoistInst()? > Okay. > > + // If the loop contains the definition of an operand, then the > > instruction > > + // isn't loop invariant. > > + if (CurLoop->contains(VRegDefs[Reg]->getParent())) > > + return false; > > Hmmm. I am not sure about this. What if the definition is in the > preheader? Does contains() returns true? Chris, Owen? > The preheader wouldn't be part of the loop, so it should be okay. > Also, I fear this might be slow. When you are creating the VReg -> MI > map, perhaps you should create a VReg -> loop map as well? > I'll see if a map will help things along. > > +bool MachineLICM::Hoist(MachineInstr &MI) { > > + if (!isLoopInvariantInst(MI)) return false; > > + > > + std::vector Preds; > > + > > + // Non-back-edge predecessors. > > + FindPredecessors(Preds); > > Consider caching some of these info? > Okay. > > + // FIXME: We are assuming at first that the basic blocks coming > > into this > > + // loop have only one successor each. This isn't the case in > > general because > > + // we haven't broken critical edges or added preheaders. > > + if (MBB->succ_size() != 1) return false; > > + assert(*MBB->succ_begin() == CurLoop->getHeader() && > > + "The predecessor doesn't feed directly into the loop > > header!"); > > + } > > Are we going to create a preheader to hoist LICM to? Then we won't > need to do all these checking? I am entirely sure about it. Someone > please chime in. > We want a pre-header. That will come at a later time. I just wanted to "walk" before running. :-) But, yes, a lot of the checks for predecessors will be simplified then. > > + // Now move the instructions to the predecessors. > > + for (std::vector::iterator > > + I = Preds.begin(), E = Preds.end(); I != E; ++I) > > + MoveInstToBlock(*I, MI.clone()); > > This will create multiple copies, it seems bad. Again, this should be > fixable with a loop preheader? > As Chris pointed out, it's filled with fail because of phi nodes, etc. I made it more strict wrt the predecessors. Now there can only be one (like in Highlander). Eventually, that one will be the pre-header. > Very nice first cut! > Thanks! :-) -bw From isanbard at gmail.com Fri Dec 7 19:47:03 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 08 Dec 2007 01:47:03 -0000 Subject: [llvm-commits] [llvm] r44696 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp Message-ID: <200712080147.lB81l3Ub010794@zion.cs.uiuc.edu> Author: void Date: Fri Dec 7 19:47:01 2007 New Revision: 44696 URL: http://llvm.org/viewvc/llvm-project?rev=44696&view=rev Log: Incorporated comments from Evan and Chris: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056043.html http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056048.html Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=44696&r1=44695&r2=44696&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Fri Dec 7 19:47:01 2007 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "machine-licm" +#include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineBasicBlock.h" @@ -27,7 +28,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetMachine.h" -#include using namespace llvm; @@ -35,9 +35,12 @@ // Hidden options to help debugging cl::opt PerformLICM("machine-licm", - cl::init(false), cl::Hidden); + cl::init(false), cl::Hidden, + cl::desc("Perform loop-invariant code motion on machine code")); } +STATISTIC(NumHoisted, "Number of machine instructions hoisted out of loop"); + namespace { class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { // Various analyses that we use... @@ -51,7 +54,7 @@ MachineLoop *CurLoop; // The current loop we are working on. // Map the def of a virtual register to the machine instruction. - std::map VRegDefs; + IndexedMap VRegDefs; public: static char ID; // Pass identification, replacement for typeid MachineLICM() : MachineFunctionPass((intptr_t)&ID) {} @@ -66,16 +69,23 @@ AU.addRequired(); } private: - /// GatherAllLoops - Get all loops in depth first order. + /// VisitAllLoops - Visit all of the loops in depth first order and try to + /// hoist invariant instructions from them. /// - void GatherAllLoops(MachineLoop *L, SmallVectorImpl &Loops) { + void VisitAllLoops(MachineLoop *L) { const std::vector &SubLoops = L->getSubLoops(); for (MachineLoop::iterator - I = SubLoops.begin(), E = SubLoops.end(); I != E; ++I) - GatherAllLoops(*I, Loops); + I = SubLoops.begin(), E = SubLoops.end(); I != E; ++I) { + MachineLoop *ML = *I; + + // Traverse the body of the loop in depth first order on the dominator + // tree so that we are guaranteed to see definitions before we see uses. + VisitAllLoops(ML); + HoistRegion(DT->getNode(ML->getHeader())); + } - Loops.push_back(L); + HoistRegion(DT->getNode(L->getHeader())); } /// MapVirtualRegisterDefs - Create a map of which machine instruction @@ -104,8 +114,12 @@ /// bool CanHoistInst(MachineInstr &I) const { const TargetInstrDescriptor *TID = I.getInstrDescriptor(); - MachineOpCode Opcode = TID->Opcode; + // Don't hoist if this instruction implicitly reads physical registers or + // doesn't take any operands. + if (TID->ImplicitUses || !I.getNumOperands()) return false; + + MachineOpCode Opcode = TID->Opcode; return TII->isTriviallyReMaterializable(&I) && // FIXME: Below necessary? !(TII->isReturn(Opcode) || @@ -137,12 +151,13 @@ Preds.push_back(*I); } - /// MoveInstToBlock - Moves the machine instruction to the bottom of the - /// predecessor basic block (but before the terminator instructions). + /// MoveInstToEndOfBlock - Moves the machine instruction to the bottom of + /// the predecessor basic block (but before the terminator instructions). /// - void MoveInstToBlock(MachineBasicBlock *MBB, MachineInstr *MI) { + void MoveInstToEndOfBlock(MachineBasicBlock *MBB, MachineInstr *MI) { MachineBasicBlock::iterator Iter = MBB->getFirstTerminator(); MBB->insert(Iter, MI); + ++NumHoisted; } /// HoistRegion - Walk the specified region of the CFG (defined by all @@ -156,7 +171,7 @@ /// Hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// - bool Hoist(MachineInstr &MI); + void Hoist(MachineInstr &MI); }; char MachineLICM::ID = 0; @@ -188,17 +203,7 @@ // Visit all of the instructions of the loop. We want to visit the subloops // first, though, so that we can hoist their invariants first into their // containing loop before we process that loop. - SmallVector Loops; - GatherAllLoops(L, Loops); - - for (SmallVector::iterator - II = Loops.begin(), IE = Loops.end(); II != IE; ++II) { - L = *II; - - // Traverse the body of the loop in depth first order on the dominator - // tree so that we are guaranteed to see definitions before we see uses. - HoistRegion(DT->getNode(L->getHeader())); - } + VisitAllLoops(L); } return Changed; @@ -216,7 +221,7 @@ II = MBB.begin(), IE = MBB.end(); II != IE; ++II) { const MachineInstr &MI = *II; - if (MI.getNumOperands() > 0) { + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI.getOperand(0); if (MO.isRegister() && MO.isDef() && @@ -249,9 +254,7 @@ // Try hoisting the instruction out of the loop. We can only do this if // all of the operands of the instruction are loop invariant and if it is // safe to hoist the instruction. - if (Hoist(MI)) - // Hoisting was successful! Remove bothersome instruction now. - MI.getParent()->remove(&MI); + Hoist(MI); } const std::vector &Children = N->getChildren(); @@ -266,12 +269,6 @@ /// instruction is hoistable. /// bool MachineLICM::isLoopInvariantInst(MachineInstr &I) { - const TargetInstrDescriptor *TID = I.getInstrDescriptor(); - - // Don't hoist if this instruction implicitly reads physical registers or - // doesn't take any operands. - if (TID->ImplicitUses || !I.getNumOperands()) return false; - if (!CanHoistInst(I)) return false; // The instruction is loop invariant if all of its operands are loop-invariant @@ -287,7 +284,7 @@ if (!MRegisterInfo::isVirtualRegister(Reg)) return false; - assert(VRegDefs[Reg] && "Machine instr not mapped for this vreg?!"); + assert(VRegDefs[Reg] && "Machine instr not mapped for this vreg?"); // If the loop contains the definition of an operand, then the instruction // isn't loop invariant. @@ -302,35 +299,34 @@ /// Hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// -bool MachineLICM::Hoist(MachineInstr &MI) { - if (!isLoopInvariantInst(MI)) return false; +void MachineLICM::Hoist(MachineInstr &MI) { + if (!isLoopInvariantInst(MI)) return; std::vector Preds; // Non-back-edge predecessors. FindPredecessors(Preds); - if (Preds.empty()) return false; - // Check that the predecessors are qualified to take the hoisted - // instruction. I.e., there is only one edge from each predecessor, and it's - // to the loop header. - for (std::vector::iterator - I = Preds.begin(), E = Preds.end(); I != E; ++I) { - MachineBasicBlock *MBB = *I; - - // FIXME: We are assuming at first that the basic blocks coming into this - // loop have only one successor each. This isn't the case in general because - // we haven't broken critical edges or added preheaders. - if (MBB->succ_size() != 1) return false; - assert(*MBB->succ_begin() == CurLoop->getHeader() && - "The predecessor doesn't feed directly into the loop header!"); - } + // Either we don't have any predecessors(?!) or we have more than one, which + // is forbidden. + if (Preds.empty() || Preds.size() != 1) return; + + // Check that the predecessor is qualified to take the hoisted + // instruction. I.e., there is only one edge from the predecessor, and it's to + // the loop header. + MachineBasicBlock *MBB = Preds.front(); + + // FIXME: We are assuming at first that the basic blocks coming into this loop + // have only one successor each. This isn't the case in general because we + // haven't broken critical edges or added preheaders. + if (MBB->succ_size() != 1) return; + assert(*MBB->succ_begin() == CurLoop->getHeader() && + "The predecessor doesn't feed directly into the loop header!"); - // Now move the instructions to the predecessors. - for (std::vector::iterator - I = Preds.begin(), E = Preds.end(); I != E; ++I) - MoveInstToBlock(*I, MI.clone()); + // Now move the instructions to the predecessor. + MoveInstToEndOfBlock(MBB, MI.clone()); + // Hoisting was successful! Remove bothersome instruction now. + MI.getParent()->remove(&MI); Changed = true; - return true; } From sabre at nondot.org Fri Dec 7 22:37:53 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 04:37:53 -0000 Subject: [llvm-commits] [llvm] r44697 - /llvm/trunk/include/llvm/InstrTypes.h Message-ID: <200712080437.lB84brVJ019760@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 7 22:37:52 2007 New Revision: 44697 URL: http://llvm.org/viewvc/llvm-project?rev=44697&view=rev Log: Implement correct isa, problem reported by "ST". Modified: llvm/trunk/include/llvm/InstrTypes.h Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=44697&r1=44696&r2=44697&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Fri Dec 7 22:37:52 2007 @@ -108,6 +108,20 @@ Op = Val; } unsigned getNumOperands() const { return 1; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const UnaryInstruction *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Malloc || + I->getOpcode() == Instruction::Alloca || + I->getOpcode() == Instruction::Free || + I->getOpcode() == Instruction::Load || + I->getOpcode() == Instruction::VAArg || + (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd); + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } }; //===----------------------------------------------------------------------===// From sabre at nondot.org Fri Dec 7 23:00:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 05:00:58 -0000 Subject: [llvm-commits] [test-suite] r44698 - /test-suite/trunk/Makefile.programs Message-ID: <200712080500.lB850w7K020773@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 7 23:00:57 2007 New Revision: 44698 URL: http://llvm.org/viewvc/llvm-project?rev=44698&view=rev Log: Enable machine-licm for ppc beta. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=44698&r1=44697&r2=44698&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Fri Dec 7 23:00:57 2007 @@ -209,7 +209,7 @@ endif#DISABLE_DIFFS ifeq ($(ARCH),PowerPC) -LLCBETAOPTION := -new-coalescer-heuristic=true +LLCBETAOPTION := -machine-licm #--enable-tail-merge #--enable-ppc-preinc #-regalloc=local -fast From sabre at nondot.org Sat Dec 8 00:39:12 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 06:39:12 -0000 Subject: [llvm-commits] [llvm] r44699 - in /llvm/trunk/lib/Target/PowerPC: PPCMachineFunctionInfo.h PPCRegisterInfo.cpp PPCRegisterInfo.h Message-ID: <200712080639.lB86dCmh025396@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 00:39:11 2007 New Revision: 44699 URL: http://llvm.org/viewvc/llvm-project?rev=44699&view=rev Log: refactor some code to avoid overloading the name 'usesLR' in different places to mean different things. Document what the one in PPCFunctionInfo means and when it is valid. Modified: llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Modified: llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h?rev=44699&r1=44698&r2=44699&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h Sat Dec 8 00:39:11 2007 @@ -39,8 +39,12 @@ int getFramePointerSaveIndex() const { return FramePointerSaveIndex; } void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; } + /// UsesLR - This is set when the prolog/epilog inserter does its initial scan + /// of the function, it is true if the LR/LR8 register is ever explicitly + /// accessed/clobbered in the machine function (e.g. by calls and movpctolr, + /// which is used in PIC generation). void setUsesLR(bool U) { UsesLR = U; } - bool usesLR() { return UsesLR; } + bool usesLR() const { return UsesLR; } }; Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=44699&r1=44698&r2=44699&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Sat Dec 8 00:39:11 2007 @@ -645,11 +645,13 @@ return MFI->getStackSize() && needsFP(MF); } -/// usesLR - Returns if the link registers (LR) has been used in the function. -/// -bool PPCRegisterInfo::usesLR(MachineFunction &MF) const { - PPCFunctionInfo *FI = MF.getInfo(); - return FI->usesLR(); +/// MustSaveLR - Return true if this function requires that we save the LR +/// register onto the stack in the prolog and restore it in the epilog of the function. +static bool MustSaveLR(const MachineFunction &MF) { + return MF.getInfo()->usesLR() || + // FIXME: Anything that has a call should clobber the LR register, + // isn't this redundant?? + MF.getFrameInfo()->hasCalls(); } void PPCRegisterInfo:: @@ -1062,7 +1064,7 @@ // Get operating system bool IsMachoABI = Subtarget.isMachoABI(); // Check if the link register (LR) has been used. - bool UsesLR = MFI->hasCalls() || usesLR(MF); + bool UsesLR = MustSaveLR(MF); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF) && FrameSize; @@ -1226,7 +1228,7 @@ // Get operating system bool IsMachoABI = Subtarget.isMachoABI(); // Check if the link register (LR) has been used. - bool UsesLR = MFI->hasCalls() || usesLR(MF); + bool UsesLR = MustSaveLR(MF); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF) && FrameSize; Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=44699&r1=44698&r2=44699&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Sat Dec 8 00:39:11 2007 @@ -96,10 +96,6 @@ MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; - /// usesLR - Returns if the link registers (LR) has been used in the function. - /// - bool usesLR(MachineFunction &MF) const; - void lowerDynamicAlloc(MachineBasicBlock::iterator II) const; void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, RegScavenger *RS = NULL) const; From sabre at nondot.org Sat Dec 8 01:00:00 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 07:00:00 -0000 Subject: [llvm-commits] [llvm] r44700 - in /llvm/trunk: lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/PowerPC/PPCMachineFunctionInfo.h lib/Target/PowerPC/PPCRegisterInfo.cpp lib/Target/PowerPC/README.txt test/CodeGen/PowerPC/retaddr.ll Message-ID: <200712080700.lB8700uT026173@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 00:59:59 2007 New Revision: 44700 URL: http://llvm.org/viewvc/llvm-project?rev=44700&view=rev Log: implement __builtin_return_addr(0) on ppc. Added: llvm/trunk/test/CodeGen/PowerPC/retaddr.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/lib/Target/PowerPC/README.txt Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=44700&r1=44699&r2=44700&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Sat Dec 8 00:59:59 2007 @@ -3036,8 +3036,8 @@ case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG); case ISD::MUL: return LowerMUL(Op, DAG); - // Frame & Return address. Currently unimplemented - case ISD::RETURNADDR: break; + // Frame & Return address. + case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); } return SDOperand(); @@ -3576,8 +3576,36 @@ return false; } -SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) -{ +SDOperand PPCTargetLowering::LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG) { + // Depths > 0 not supported yet! + if (cast(Op.getOperand(0))->getValue() > 0) + return SDOperand(); + + MachineFunction &MF = DAG.getMachineFunction(); + PPCFunctionInfo *FuncInfo = MF.getInfo(); + int RAIdx = FuncInfo->getReturnAddrSaveIndex(); + if (RAIdx == 0) { + bool isPPC64 = PPCSubTarget.isPPC64(); + int Offset = + PPCFrameInfo::getReturnSaveOffset(isPPC64, PPCSubTarget.isMachoABI()); + + // Set up a frame object for the return address. + RAIdx = MF.getFrameInfo()->CreateFixedObject(isPPC64 ? 8 : 4, Offset); + + // Remember it for next time. + FuncInfo->setReturnAddrSaveIndex(RAIdx); + + // Make sure the function really does not optimize away the store of the RA + // to the stack. + FuncInfo->setLRStoreRequired(); + } + + // Just load the return address off the stack. + SDOperand RetAddrFI = DAG.getFrameIndex(RAIdx, getPointerTy()); + return DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI, NULL, 0); +} + +SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) { // Depths > 0 not supported yet! if (cast(Op.getOperand(0))->getValue() > 0) return SDOperand(); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=44700&r1=44699&r2=44700&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Sat Dec 8 00:59:59 2007 @@ -288,6 +288,7 @@ /// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; + SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG); }; } Modified: llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h?rev=44700&r1=44699&r2=44700&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCMachineFunctionInfo.h Sat Dec 8 00:59:59 2007 @@ -27,18 +27,29 @@ /// when using frame pointers (dyna_add, dyna_sub.) int FramePointerSaveIndex; - /// UsesLR - Indicates whether LR is used in the current function. + /// ReturnAddrSaveIndex - Frame index of where the return address is stored. /// + int ReturnAddrSaveIndex; + + /// UsesLR - Indicates whether LR is used in the current function. This is + /// only valid after the initial scan of the function by PEI. bool UsesLR; + /// LRStoreRequired - The bool indicates whether there is some explicit use of + /// the LR/LR8 stack slot that is not obvious from scanning the code. This + /// requires that the code generator produce a store of LR to the stack on + /// entry, even though LR may otherwise apparently not be used. + bool LRStoreRequired; public: - PPCFunctionInfo(MachineFunction& MF) - : FramePointerSaveIndex(0) - {} + PPCFunctionInfo(MachineFunction &MF) + : FramePointerSaveIndex(0), ReturnAddrSaveIndex(0), LRStoreRequired(false){} int getFramePointerSaveIndex() const { return FramePointerSaveIndex; } void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; } + int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; } + void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; } + /// UsesLR - This is set when the prolog/epilog inserter does its initial scan /// of the function, it is true if the LR/LR8 register is ever explicitly /// accessed/clobbered in the machine function (e.g. by calls and movpctolr, @@ -46,6 +57,9 @@ void setUsesLR(bool U) { UsesLR = U; } bool usesLR() const { return UsesLR; } + void setLRStoreRequired() { LRStoreRequired = true; } + bool isLRStoreRequired() const { return LRStoreRequired; } + }; } // end of namespace llvm Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=44700&r1=44699&r2=44700&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Sat Dec 8 00:59:59 2007 @@ -646,9 +646,14 @@ } /// MustSaveLR - Return true if this function requires that we save the LR -/// register onto the stack in the prolog and restore it in the epilog of the function. +/// register onto the stack in the prolog and restore it in the epilog of the +/// function. static bool MustSaveLR(const MachineFunction &MF) { - return MF.getInfo()->usesLR() || + const PPCFunctionInfo *MFI = MF.getInfo(); + + // We need an save/restore of LR if there is any use/def of LR explicitly, or + // if there is some use of the LR stack slot (e.g. for builtin_return_address. + return MFI->usesLR() || MFI->isLRStoreRequired() || // FIXME: Anything that has a call should clobber the LR register, // isn't this redundant?? MF.getFrameInfo()->hasCalls(); Modified: llvm/trunk/lib/Target/PowerPC/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/README.txt?rev=44700&r1=44699&r2=44700&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/README.txt (original) +++ llvm/trunk/lib/Target/PowerPC/README.txt Sat Dec 8 00:59:59 2007 @@ -3,7 +3,6 @@ TODO: * gpr0 allocation * implement do-loop -> bdnz transform -* __builtin_return_address not supported on PPC ===-------------------------------------------------------------------------=== Added: llvm/trunk/test/CodeGen/PowerPC/retaddr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/retaddr.ll?rev=44700&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/retaddr.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/retaddr.ll Sat Dec 8 00:59:59 2007 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc -march=ppc32 | grep mflr +; RUN: llvm-as < %s | llc -march=ppc32 | grep lwz + +target triple = "powerpc-apple-darwin8" + +define void @foo(i8** %X) { +entry: + %tmp = tail call i8* @llvm.returnaddress( i32 0 ) ; [#uses=1] + store i8* %tmp, i8** %X, align 4 + ret void +} + +declare i8* @llvm.returnaddress(i32) + From sabre at nondot.org Sat Dec 8 01:04:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 07:04:58 -0000 Subject: [llvm-commits] [llvm] r44701 - in /llvm/trunk: lib/Target/PowerPC/PPCRegisterInfo.cpp test/CodeGen/PowerPC/retaddr.ll Message-ID: <200712080704.lB874wn6026344@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 01:04:58 2007 New Revision: 44701 URL: http://llvm.org/viewvc/llvm-project?rev=44701&view=rev Log: Fix a significant code quality regression I introduced on PPC64 quite a while ago. We now produce: _foo: mflr r0 std r0, 16(r1) ld r2, 16(r1) std r2, 0(r3) ld r0, 16(r1) mtlr r0 blr instead of: _foo: mflr r0 std r0, 16(r1) lis r0, 0 ori r0, r0, 16 ldx r2, r1, r0 std r2, 0(r3) ld r0, 16(r1) mtlr r0 blr for: void foo(void **X) { *X = __builtin_return_address(0); } on ppc64. Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp llvm/trunk/test/CodeGen/PowerPC/retaddr.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=44701&r1=44700&r2=44701&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Sat Dec 8 01:04:58 2007 @@ -817,7 +817,7 @@ // clear can be encoded. This is extremely uncommon, because normally you // only "std" to a stack slot that is at least 4-byte aligned, but it can // happen in invalid code. - if (isInt16(Offset) && (!isIXAddr || (isIXAddr & 3) == 0)) { + if (isInt16(Offset) && (!isIXAddr || (Offset & 3) == 0)) { if (isIXAddr) Offset >>= 2; // The actual encoded value has the low two bits zero. MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset); Modified: llvm/trunk/test/CodeGen/PowerPC/retaddr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/retaddr.ll?rev=44701&r1=44700&r2=44701&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/retaddr.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/retaddr.ll Sat Dec 8 01:04:58 2007 @@ -1,5 +1,6 @@ ; RUN: llvm-as < %s | llc -march=ppc32 | grep mflr ; RUN: llvm-as < %s | llc -march=ppc32 | grep lwz +; RUN: llvm-as < %s | llc -march=ppc64 | grep {ld r., 16(r1)} target triple = "powerpc-apple-darwin8" From isanbard at gmail.com Sat Dec 8 01:17:56 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 08 Dec 2007 07:17:56 -0000 Subject: [llvm-commits] [llvm] r44702 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineLICM.cpp lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h Message-ID: <200712080717.lB87Hu3F026865@zion.cs.uiuc.edu> Author: void Date: Sat Dec 8 01:17:56 2007 New Revision: 44702 URL: http://llvm.org/viewvc/llvm-project?rev=44702&view=rev Log: Renaming: isTriviallyReMaterializable -> hasNoSideEffects isReallyTriviallyReMaterializable -> isTriviallyReMaterializable Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=44702&r1=44701&r2=44702&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Sat Dec 8 01:17:56 2007 @@ -288,24 +288,24 @@ return get(Opcode).Flags & M_HAS_OPTIONAL_DEF; } - /// isTriviallyReMaterializable - Return true if the instruction is trivially + /// hasNoSideEffects - Return true if the instruction is trivially /// rematerializable, meaning it has no side effects and requires no operands /// that aren't always available. - bool isTriviallyReMaterializable(MachineInstr *MI) const { + bool hasNoSideEffects(MachineInstr *MI) const { return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) && - isReallyTriviallyReMaterializable(MI); + isTriviallyReMaterializable(MI); } protected: - /// isReallyTriviallyReMaterializable - For instructions with opcodes for - /// which the M_REMATERIALIZABLE flag is set, this function tests whether the - /// instruction itself is actually trivially rematerializable, considering - /// its operands. This is used for targets that have instructions that are - /// only trivially rematerializable for specific uses. This predicate must - /// return false if the instruction has any side effects other than - /// producing a value, or if it requres any address registers that are not - /// always available. - virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const { + /// isTriviallyReMaterializable - For instructions with opcodes for which the + /// M_REMATERIALIZABLE flag is set, this function tests whether the + /// instruction itself is actually trivially rematerializable, considering its + /// operands. This is used for targets that have instructions that are only + /// trivially rematerializable for specific uses. This predicate must return + /// false if the instruction has any side effects other than producing a + /// value, or if it requres any address registers that are not always + /// available. + virtual bool isTriviallyReMaterializable(MachineInstr *MI) const { return true; } Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44702&r1=44701&r2=44702&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Sat Dec 8 01:17:56 2007 @@ -613,7 +613,7 @@ return false; isLoad = false; - if (tii_->isTriviallyReMaterializable(MI)) { + if (tii_->hasNoSideEffects(MI)) { isLoad = MI->getInstrDescriptor()->Flags & M_LOAD_FLAG; return true; } Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=44702&r1=44701&r2=44702&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Sat Dec 8 01:17:56 2007 @@ -120,7 +120,7 @@ if (TID->ImplicitUses || !I.getNumOperands()) return false; MachineOpCode Opcode = TID->Opcode; - return TII->isTriviallyReMaterializable(&I) && + return TII->hasNoSideEffects(&I) && // FIXME: Below necessary? !(TII->isReturn(Opcode) || TII->isTerminatorInstr(Opcode) || Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=44702&r1=44701&r2=44702&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Dec 8 01:17:56 2007 @@ -116,7 +116,7 @@ } -bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const { +bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const { switch (MI->getOpcode()) { default: break; case X86::MOV8rm: Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=44702&r1=44701&r2=44702&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Sat Dec 8 01:17:56 2007 @@ -239,7 +239,7 @@ unsigned& destReg) const; unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; - bool isReallyTriviallyReMaterializable(MachineInstr *MI) const; + bool isTriviallyReMaterializable(MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target From sabre at nondot.org Sat Dec 8 01:22:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 07:22:58 -0000 Subject: [llvm-commits] [llvm] r44703 - /llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200712080722.lB87Mws8027057@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 01:22:58 2007 New Revision: 44703 URL: http://llvm.org/viewvc/llvm-project?rev=44703&view=rev Log: aesthetic changes, no functionality change. Evan, it's not clear what 'Available' is, please add a comment near it and rename it if appropriate. Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=44703&r1=44702&r2=44703&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Sat Dec 8 01:22:58 2007 @@ -562,7 +562,7 @@ /// MatchAddress - Add the specified node to the specified addressing mode, /// returning true if it cannot be done. This just pattern matches for the -/// addressing mode +/// addressing mode. bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, bool isRoot, unsigned Depth) { // Limit recursion. @@ -653,33 +653,35 @@ break; case ISD::SHL: - if (!Available && AM.IndexReg.Val == 0 && AM.Scale == 1) - if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) { - unsigned Val = CN->getValue(); - if (Val == 1 || Val == 2 || Val == 3) { - AM.Scale = 1 << Val; - SDOperand ShVal = N.Val->getOperand(0); - - // Okay, we know that we have a scale by now. However, if the scaled - // value is an add of something and a constant, we can fold the - // constant into the disp field here. - if (ShVal.Val->getOpcode() == ISD::ADD && ShVal.hasOneUse() && - isa(ShVal.Val->getOperand(1))) { - AM.IndexReg = ShVal.Val->getOperand(0); - ConstantSDNode *AddVal = - cast(ShVal.Val->getOperand(1)); - uint64_t Disp = AM.Disp + (AddVal->getValue() << Val); - if (isInt32(Disp)) - AM.Disp = Disp; - else - AM.IndexReg = ShVal; - } else { + if (Available || AM.IndexReg.Val != 0 || AM.Scale != 1) + break; + + if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) { + unsigned Val = CN->getValue(); + if (Val == 1 || Val == 2 || Val == 3) { + AM.Scale = 1 << Val; + SDOperand ShVal = N.Val->getOperand(0); + + // Okay, we know that we have a scale by now. However, if the scaled + // value is an add of something and a constant, we can fold the + // constant into the disp field here. + if (ShVal.Val->getOpcode() == ISD::ADD && ShVal.hasOneUse() && + isa(ShVal.Val->getOperand(1))) { + AM.IndexReg = ShVal.Val->getOperand(0); + ConstantSDNode *AddVal = + cast(ShVal.Val->getOperand(1)); + uint64_t Disp = AM.Disp + (AddVal->getValue() << Val); + if (isInt32(Disp)) + AM.Disp = Disp; + else AM.IndexReg = ShVal; - } - return false; + } else { + AM.IndexReg = ShVal; } + return false; } break; + } case ISD::SMUL_LOHI: case ISD::UMUL_LOHI: @@ -738,22 +740,22 @@ case ISD::OR: // Handle "X | C" as "X + C" iff X is known to have C bits clear. - if (!Available) { - if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - X86ISelAddressMode Backup = AM; - // Start with the LHS as an addr mode. - if (!MatchAddress(N.getOperand(0), AM, false) && - // Address could not have picked a GV address for the displacement. - AM.GV == NULL && - // On x86-64, the resultant disp must fit in 32-bits. - isInt32(AM.Disp + CN->getSignExtended()) && - // Check to see if the LHS & C is zero. - CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) { - AM.Disp += CN->getValue(); - return false; - } - AM = Backup; + if (Available) break; + + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + X86ISelAddressMode Backup = AM; + // Start with the LHS as an addr mode. + if (!MatchAddress(N.getOperand(0), AM, false) && + // Address could not have picked a GV address for the displacement. + AM.GV == NULL && + // On x86-64, the resultant disp must fit in 32-bits. + isInt32(AM.Disp + CN->getSignExtended()) && + // Check to see if the LHS & C is zero. + CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) { + AM.Disp += CN->getValue(); + return false; } + AM = Backup; } break; } From baldrick at free.fr Sat Dec 8 02:33:06 2007 From: baldrick at free.fr (Duncan Sands) Date: Sat, 8 Dec 2007 09:33:06 +0100 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> Message-ID: <200712080933.07034.baldrick@free.fr> Hi Bill, presumably you are using alias analysis at the codegen level. I noticed some time ago that in several places code doing multiple stores to successive locations does not set the SVOffset value correctly: it used the same SVOffset for all the stores. Probably the same is true for loads. I think this can result in wrong alias analysis deductions. Probably someone should audit code for this... Ciao, Duncan. From gordonhenriksen at mac.com Sat Dec 8 10:55:45 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 08 Dec 2007 16:55:45 -0000 Subject: [llvm-commits] [llvm] r44704 - in /llvm/trunk/bindings/ocaml: analysis/analysis_ocaml.c llvm/llvm_ocaml.c Message-ID: <200712081655.lB8GtkPu028026@zion.cs.uiuc.edu> Author: gordon Date: Sat Dec 8 10:55:43 2007 New Revision: 44704 URL: http://llvm.org/viewvc/llvm-project?rev=44704&view=rev Log: Fix bug in constructing Ocaml option types in the bindings. Modified: llvm/trunk/bindings/ocaml/analysis/analysis_ocaml.c llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Modified: llvm/trunk/bindings/ocaml/analysis/analysis_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/analysis/analysis_ocaml.c?rev=44704&r1=44703&r2=44704&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/analysis/analysis_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/analysis/analysis_ocaml.c Sat Dec 8 10:55:43 2007 @@ -32,7 +32,7 @@ if (0 == Result) { Option = Val_int(0); } else { - Option = alloc(1, 1); + Option = alloc(1, 0); String = copy_string(Message); Store_field(Option, 0, String); } Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c?rev=44704&r1=44703&r2=44704&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Sat Dec 8 10:55:43 2007 @@ -410,7 +410,7 @@ CAMLparam1(Name); LLVMValueRef GlobalVar; if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) { - value Option = alloc(1, 1); + value Option = alloc(1, 0); Field(Option, 0) = (value) GlobalVar; CAMLreturn(Option); } @@ -487,7 +487,7 @@ CAMLparam1(Name); LLVMValueRef Fn; if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) { - value Option = alloc(1, 1); + value Option = alloc(1, 0); Field(Option, 0) = (value) Fn; CAMLreturn(Option); } From gordonhenriksen at mac.com Sat Dec 8 11:07:50 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 08 Dec 2007 17:07:50 -0000 Subject: [llvm-commits] [llvm] r44705 - in /llvm/trunk: include/llvm/Support/StringPool.h lib/Support/StringPool.cpp Message-ID: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> Author: gordon Date: Sat Dec 8 11:07:47 2007 New Revision: 44705 URL: http://llvm.org/viewvc/llvm-project?rev=44705&view=rev Log: Adding a StringPool data structure, which GC will use. Added: llvm/trunk/include/llvm/Support/StringPool.h llvm/trunk/lib/Support/StringPool.cpp Added: llvm/trunk/include/llvm/Support/StringPool.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringPool.h?rev=44705&view=auto ============================================================================== --- llvm/trunk/include/llvm/Support/StringPool.h (added) +++ llvm/trunk/include/llvm/Support/StringPool.h Sat Dec 8 11:07:47 2007 @@ -0,0 +1,135 @@ +//===-- StringPool.h - Interned string pool -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Gordon Henriksen and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares an interned string pool, which helps reduce the cost of +// strings by using the same storage for identical strings. +// +// To intern a string: +// +// StringPool Pool; +// PooledStringPtr Str = Pool.intern("wakka wakka"); +// +// To use the value of an interned string, use operator bool and operator*: +// +// if (Str) +// cerr << "the string is" << *Str << "\n"; +// +// Pooled strings are immutable, but you can change a PooledStringPtr to point +// to another instance. So that interned strings can eventually be freed, +// strings in the string pool are reference-counted (automatically). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_STRINGPOOL_H +#define LLVM_SUPPORT_STRINGPOOL_H + +#include +#include +#include + +namespace llvm { + + class PooledStringPtr; + + /// StringPool - An interned string pool. Use the intern method to add a + /// string. Strings are removed automatically as PooledStringPtrs are + /// destroyed. + class StringPool { + struct PooledString { + StringPool *Pool; ///< So the string can remove itself. + unsigned Refcount; ///< Number of referencing PooledStringPtrs. + + public: + PooledString() : Pool(0), Refcount(0) { } + }; + + friend class PooledStringPtr; + + typedef StringMap table_t; + typedef StringMapEntry entry_t; + table_t InternTable; + + public: + StringPool(); + ~StringPool(); + + PooledStringPtr intern(const char *Begin, const char *End); + inline PooledStringPtr intern(const char *Str); + }; + + /// PooledStringPtr - A pointer to an interned string. Use operator bool to + /// test whether the pointer is valid, and operator * to get the string if so. + /// This is a lightweight value class with storage requirements equivalent to + /// a single pointer, but it does have reference-counting overhead when + /// copied. + class PooledStringPtr { + typedef StringPool::entry_t entry_t; + entry_t *S; + + public: + PooledStringPtr() : S(0) {} + + explicit PooledStringPtr(entry_t *E) : S(E) { + if (S) ++S->getValue().Refcount; + } + + PooledStringPtr(const PooledStringPtr &That) : S(That.S) { + if (S) ++S->getValue().Refcount; + } + + PooledStringPtr &operator=(const PooledStringPtr &That) { + if (S != That.S) { + clear(); + S = That.S; + if (S) ++S->getValue().Refcount; + } + return *this; + } + + void clear() { + if (!S) + return; + if (--S->getValue().Refcount == 0) { + S->getValue().Pool->InternTable.remove(S); + delete S; + } + S = 0; + } + + ~PooledStringPtr() { clear(); } + + inline const char *begin() const { + assert(*this && "Attempt to dereference empty PooledStringPtr!"); + return S->getKeyData(); + } + + inline const char *end() const { + assert(*this && "Attempt to dereference empty PooledStringPtr!"); + return S->getKeyData() + S->getKeyLength(); + } + + inline unsigned size() const { + assert(*this && "Attempt to dereference empty PooledStringPtr!"); + return S->getKeyLength(); + } + + inline const char *operator*() const { return begin(); } + inline operator bool() const { return S != 0; } + + inline bool operator==(const PooledStringPtr &That) { return S == That.S; } + inline bool operator!=(const PooledStringPtr &That) { return S != That.S; } + }; + + PooledStringPtr StringPool::intern(const char *Str) { + return intern(Str, Str + strlen(Str)); + } + +} // End llvm namespace + +#endif Added: llvm/trunk/lib/Support/StringPool.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringPool.cpp?rev=44705&view=auto ============================================================================== --- llvm/trunk/lib/Support/StringPool.cpp (added) +++ llvm/trunk/lib/Support/StringPool.cpp Sat Dec 8 11:07:47 2007 @@ -0,0 +1,35 @@ +//===-- StringPool.cpp - Interned string pool -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Gordon Henriksen and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the StringPool class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/StringPool.h" +#include "llvm/Support/Streams.h" + +using namespace llvm; + +StringPool::StringPool() {} + +StringPool::~StringPool() { + assert(InternTable.empty() && "PooledStringPtr leaked!"); +} + +PooledStringPtr StringPool::intern(const char *Begin, const char *End) { + table_t::iterator I = InternTable.find(Begin, End); + if (I != InternTable.end()) + return PooledStringPtr(&*I); + + entry_t *S = entry_t::Create(Begin, End); + S->getValue().Pool = this; + InternTable.insert(S); + + return PooledStringPtr(S); +} From gordonhenriksen at mac.com Sat Dec 8 11:53:02 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 08 Dec 2007 17:53:02 -0000 Subject: [llvm-commits] [llvm] r44706 - /llvm/trunk/lib/Target/CellSPU/ Message-ID: <200712081753.lB8Hr3oQ031195@zion.cs.uiuc.edu> Author: gordon Date: Sat Dec 8 11:53:01 2007 New Revision: 44706 URL: http://llvm.org/viewvc/llvm-project?rev=44706&view=rev Log: Ignoring generated files. Modified: llvm/trunk/lib/Target/CellSPU/ (props changed) Propchange: llvm/trunk/lib/Target/CellSPU/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sat Dec 8 11:53:01 2007 @@ -0,0 +1,3 @@ +*.inc +Debug +Release From sabre at nondot.org Sat Dec 8 13:00:04 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 19:00:04 -0000 Subject: [llvm-commits] [llvm] r44707 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200712081900.lB8J04Lt002141@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 13:00:03 2007 New Revision: 44707 URL: http://llvm.org/viewvc/llvm-project?rev=44707&view=rev Log: proper #include order. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=44707&r1=44706&r2=44707&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Sat Dec 8 13:00:03 2007 @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/APFloat.h" #include #include -#include "llvm/ADT/APFloat.h" #include "llvm/Support/MathExtras.h" using namespace llvm; From sabre at nondot.org Sat Dec 8 13:00:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 19:00:38 -0000 Subject: [llvm-commits] [llvm] r44708 - /llvm/trunk/include/llvm/ADT/APFloat.h Message-ID: <200712081900.lB8J0cw2002173@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 13:00:38 2007 New Revision: 44708 URL: http://llvm.org/viewvc/llvm-project?rev=44708&view=rev Log: remove dead #include, APInt.h already has the needed forward decls. Modified: llvm/trunk/include/llvm/ADT/APFloat.h Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=44708&r1=44707&r2=44708&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Sat Dec 8 13:00:38 2007 @@ -102,7 +102,6 @@ // APInt contains static functions implementing bignum arithmetic. #include "llvm/ADT/APInt.h" -#include "llvm/Bitcode/SerializationFwd.h" #include "llvm/CodeGen/ValueTypes.h" namespace llvm { From sabre at nondot.org Sat Dec 8 13:01:44 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 19:01:44 -0000 Subject: [llvm-commits] [llvm] r44709 - /llvm/trunk/include/llvm/ADT/APInt.h Message-ID: <200712081901.lB8J1imH002216@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 13:01:44 2007 New Revision: 44709 URL: http://llvm.org/viewvc/llvm-project?rev=44709&view=rev Log: eliminate dependency on Bitcode headers. Modified: llvm/trunk/include/llvm/ADT/APInt.h Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=44709&r1=44708&r2=44709&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Sat Dec 8 13:01:44 2007 @@ -16,14 +16,15 @@ #define LLVM_APINT_H #include "llvm/Support/DataTypes.h" -#include "llvm/Bitcode/SerializationFwd.h" #include #include #define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1] namespace llvm { - + class Serializer; + class Deserializer; + /* An unsigned host type used as a single part of a multi-part bignum. */ typedef uint64_t integerPart; From sabre at nondot.org Sat Dec 8 13:03:31 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 19:03:31 -0000 Subject: [llvm-commits] [llvm] r44710 - /llvm/trunk/lib/AsmParser/LLLexer.cpp Message-ID: <200712081903.lB8J3VQF002293@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 13:03:30 2007 New Revision: 44710 URL: http://llvm.org/viewvc/llvm-project?rev=44710&view=rev Log: add #include Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=44710&r1=44709&r2=44710&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Sat Dec 8 13:03:30 2007 @@ -14,6 +14,7 @@ #include "LLLexer.h" #include "ParserInternals.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MathExtras.h" #include #include "llvmAsmParser.h" From sabre at nondot.org Sat Dec 8 13:06:22 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 19:06:22 -0000 Subject: [llvm-commits] [llvm] r44711 - /llvm/trunk/include/llvm/ADT/APFloat.h Message-ID: <200712081906.lB8J6Mjs002400@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 13:06:21 2007 New Revision: 44711 URL: http://llvm.org/viewvc/llvm-project?rev=44711&view=rev Log: remove dead #include. Modified: llvm/trunk/include/llvm/ADT/APFloat.h Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=44711&r1=44710&r2=44711&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Sat Dec 8 13:06:21 2007 @@ -102,7 +102,6 @@ // APInt contains static functions implementing bignum arithmetic. #include "llvm/ADT/APInt.h" -#include "llvm/CodeGen/ValueTypes.h" namespace llvm { From rspencer at reidspencer.com Sat Dec 8 13:43:57 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Sat, 08 Dec 2007 11:43:57 -0800 Subject: [llvm-commits] [llvm] r44705 - in /llvm/trunk: include/llvm/Support/StringPool.h lib/Support/StringPool.cpp In-Reply-To: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> References: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> Message-ID: <1197143037.3143.92.camel@bashful.x10sys.com> Hi Gordon, Nice addition. Some minor feedback for you below ... On Sat, 2007-12-08 at 17:07 +0000, Gordon Henriksen wrote: > Author: gordon > Date: Sat Dec 8 11:07:47 2007 > New Revision: 44705 > > URL: http://llvm.org/viewvc/llvm-project?rev=44705&view=rev > Log: > Adding a StringPool data structure, which GC will use. > > Added: > llvm/trunk/include/llvm/Support/StringPool.h > llvm/trunk/lib/Support/StringPool.cpp > > Added: llvm/trunk/include/llvm/Support/StringPool.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringPool.h?rev=44705&view=auto > > ============================================================================== > --- llvm/trunk/include/llvm/Support/StringPool.h (added) > +++ llvm/trunk/include/llvm/Support/StringPool.h Sat Dec 8 11:07:47 2007 > @@ -0,0 +1,135 @@ > +//===-- StringPool.h - Interned string pool -------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file was developed by Gordon Henriksen and is distributed under the > +// University of Illinois Open Source License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file declares an interned string pool, which helps reduce the cost of > +// strings by using the same storage for identical strings. > +// > +// To intern a string: > +// > +// StringPool Pool; > +// PooledStringPtr Str = Pool.intern("wakka wakka"); > +// > +// To use the value of an interned string, use operator bool and operator*: > +// > +// if (Str) > +// cerr << "the string is" << *Str << "\n"; > +// > +// Pooled strings are immutable, but you can change a PooledStringPtr to point > +// to another instance. So that interned strings can eventually be freed, > +// strings in the string pool are reference-counted (automatically). > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_SUPPORT_STRINGPOOL_H > +#define LLVM_SUPPORT_STRINGPOOL_H > + > +#include > +#include > +#include > + > +namespace llvm { > + > + class PooledStringPtr; > + > + /// StringPool - An interned string pool. Use the intern method to add a > + /// string. Strings are removed automatically as PooledStringPtrs are > + /// destroyed. > + class StringPool { > + struct PooledString { > + StringPool *Pool; ///< So the string can remove itself. > + unsigned Refcount; ///< Number of referencing PooledStringPtrs. > + > + public: > + PooledString() : Pool(0), Refcount(0) { } > + }; Since you have added doxygen comments for the structure's data members, why not document the structure itself as well? This will lead to less confusing documentation. > + > + friend class PooledStringPtr; > + > + typedef StringMap table_t; > + typedef StringMapEntry entry_t; > + table_t InternTable; > + > + public: > + StringPool(); > + ~StringPool(); > + > + PooledStringPtr intern(const char *Begin, const char *End); > + inline PooledStringPtr intern(const char *Str); These two methods are primary interfaces to the StringPool, aren't they? Shouldn't they be documented with doxygen comments? > + }; > + > + /// PooledStringPtr - A pointer to an interned string. Use operator bool to > + /// test whether the pointer is valid, and operator * to get the string if so. > + /// This is a lightweight value class with storage requirements equivalent to > + /// a single pointer, but it does have reference-counting overhead when > + /// copied. > + class PooledStringPtr { > + typedef StringPool::entry_t entry_t; > + entry_t *S; > + > + public: > + PooledStringPtr() : S(0) {} > + > + explicit PooledStringPtr(entry_t *E) : S(E) { > + if (S) ++S->getValue().Refcount; > + } > + > + PooledStringPtr(const PooledStringPtr &That) : S(That.S) { > + if (S) ++S->getValue().Refcount; > + } > + > + PooledStringPtr &operator=(const PooledStringPtr &That) { > + if (S != That.S) { > + clear(); > + S = That.S; > + if (S) ++S->getValue().Refcount; > + } > + return *this; > + } > + > + void clear() { > + if (!S) > + return; > + if (--S->getValue().Refcount == 0) { > + S->getValue().Pool->InternTable.remove(S); > + delete S; > + } > + S = 0; > + } > + > + ~PooledStringPtr() { clear(); } > + > + inline const char *begin() const { > + assert(*this && "Attempt to dereference empty PooledStringPtr!"); > + return S->getKeyData(); > + } > + > + inline const char *end() const { > + assert(*this && "Attempt to dereference empty PooledStringPtr!"); > + return S->getKeyData() + S->getKeyLength(); > + } > + > + inline unsigned size() const { > + assert(*this && "Attempt to dereference empty PooledStringPtr!"); > + return S->getKeyLength(); > + } > + > + inline const char *operator*() const { return begin(); } > + inline operator bool() const { return S != 0; } > + > + inline bool operator==(const PooledStringPtr &That) { return S == That.S; } > + inline bool operator!=(const PooledStringPtr &That) { return S != That.S; } > + }; > + > + PooledStringPtr StringPool::intern(const char *Str) { > + return intern(Str, Str + strlen(Str)); Maybe use strnlen(3) here to guard against Str not being null terminated ? > + } > + > +} // End llvm namespace > + > +#endif > > Added: llvm/trunk/lib/Support/StringPool.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringPool.cpp?rev=44705&view=auto > > ============================================================================== > --- llvm/trunk/lib/Support/StringPool.cpp (added) > +++ llvm/trunk/lib/Support/StringPool.cpp Sat Dec 8 11:07:47 2007 > @@ -0,0 +1,35 @@ > +//===-- StringPool.cpp - Interned string pool -----------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file was developed by Gordon Henriksen and is distributed under the > +// University of Illinois Open Source License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the StringPool class. > +// > +//===----------------------------------------------------------------------===// > + > +#include "llvm/Support/StringPool.h" > +#include "llvm/Support/Streams.h" > + > +using namespace llvm; > + > +StringPool::StringPool() {} > + > +StringPool::~StringPool() { > + assert(InternTable.empty() && "PooledStringPtr leaked!"); > +} > + > +PooledStringPtr StringPool::intern(const char *Begin, const char *End) { > + table_t::iterator I = InternTable.find(Begin, End); > + if (I != InternTable.end()) > + return PooledStringPtr(&*I); > + > + entry_t *S = entry_t::Create(Begin, End); > + S->getValue().Pool = this; > + InternTable.insert(S); > + > + return PooledStringPtr(S); > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gordonhenriksen at mac.com Sat Dec 8 13:57:18 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 8 Dec 2007 14:57:18 -0500 Subject: [llvm-commits] [llvm] r44705 - in /llvm/trunk: include/llvm/Support/StringPool.h lib/Support/StringPool.cpp In-Reply-To: <1197143037.3143.92.camel@bashful.x10sys.com> References: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> <1197143037.3143.92.camel@bashful.x10sys.com> Message-ID: <5D42B979-F77B-4EBF-BA69-DE86538718EA@mac.com> Hi Reid. Nice to hear from you. On 2007-12-08, at 14:43, Reid Spencer wrote: > Hi Gordon, > > Nice addition. Thanks. > Some minor feedback for you below ... > > On Sat, 2007-12-08 at 17:07 +0000, Gordon Henriksen wrote: > >> + struct PooledString { >> + StringPool *Pool; ///< So the string can remove itself. >> + unsigned Refcount; ///< Number of referencing >> PooledStringPtrs. >> + >> + public: >> + PooledString() : Pool(0), Refcount(0) { } >> + }; > > Since you have added doxygen comments for the structure's data > members, > why not document the structure itself as well? This will lead to less > confusing documentation. Okay. >> + >> + friend class PooledStringPtr; >> + >> + typedef StringMap table_t; >> + typedef StringMapEntry entry_t; >> + table_t InternTable; >> + >> + public: >> + StringPool(); >> + ~StringPool(); >> + >> + PooledStringPtr intern(const char *Begin, const char *End); >> + inline PooledStringPtr intern(const char *Str); > > These two methods are primary interfaces to the StringPool, aren't > they? > Shouldn't they be documented with doxygen comments? Okay. >> + PooledStringPtr StringPool::intern(const char *Str) { >> + return intern(Str, Str + strlen(Str)); > > Maybe use strnlen(3) That function is sufficiently nonstandard to not exist on Darwin. > here to guard against Str not being null terminated ? This is a convenience specifically for null-terminated strings, so I'm not sure how defensive programming here is useful. ? Gordon From gordonhenriksen at mac.com Sat Dec 8 14:10:43 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 08 Dec 2007 20:10:43 -0000 Subject: [llvm-commits] [llvm] r44713 - /llvm/trunk/include/llvm/Support/StringPool.h Message-ID: <200712082010.lB8KAhrD006766@zion.cs.uiuc.edu> Author: gordon Date: Sat Dec 8 14:10:40 2007 New Revision: 44713 URL: http://llvm.org/viewvc/llvm-project?rev=44713&view=rev Log: Incorporating review feedback from Reid. Modified: llvm/trunk/include/llvm/Support/StringPool.h Modified: llvm/trunk/include/llvm/Support/StringPool.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringPool.h?rev=44713&r1=44712&r2=44713&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StringPool.h (original) +++ llvm/trunk/include/llvm/Support/StringPool.h Sat Dec 8 14:10:40 2007 @@ -41,6 +41,8 @@ /// string. Strings are removed automatically as PooledStringPtrs are /// destroyed. class StringPool { + /// PooledString - This is the value of an entry in the pool's interning + /// table. struct PooledString { StringPool *Pool; ///< So the string can remove itself. unsigned Refcount; ///< Number of referencing PooledStringPtrs. @@ -59,7 +61,14 @@ StringPool(); ~StringPool(); + /// intern - Adds a string to the pool and returns a reference-counted + /// pointer to it. No additional memory is allocated if the string already + /// exists in the pool. PooledStringPtr intern(const char *Begin, const char *End); + + /// intern - Adds a null-terminated string to the pool and returns a + /// reference-counted pointer to it. No additional memory is allocated if + /// the string already exists in the pool. inline PooledStringPtr intern(const char *Str); }; From sabre at nondot.org Sat Dec 8 14:16:06 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 20:16:06 -0000 Subject: [llvm-commits] [llvm] r44714 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeDAGTypes.cpp LegalizeTypes.h Message-ID: <200712082016.lB8KG6KT007151@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 14:16:06 2007 New Revision: 44714 URL: http://llvm.org/viewvc/llvm-project?rev=44714&view=rev Log: Split the class definition of DAGTypeLegalizer out into a header. Leave it visibility hidden, but not in an anon namespace. Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44714&r1=44713&r2=44714&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Sat Dec 8 14:16:06 2007 @@ -12,246 +12,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "legalize-types" -#include "llvm/CodeGen/SelectionDAG.h" +#include "LegalizeTypes.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" using namespace llvm; -//===----------------------------------------------------------------------===// -/// DAGTypeLegalizer - This takes an arbitrary SelectionDAG as input and -/// hacks on it until the target machine can handle it. This involves -/// eliminating value sizes the machine cannot handle (promoting small sizes to -/// large sizes or splitting up large values into small values) as well as -/// eliminating operations the machine cannot handle. -/// -/// This code also does a small amount of optimization and recognition of idioms -/// as part of its processing. For example, if a target does not support a -/// 'setcc' instruction efficiently, but does support 'brcc' instruction, this -/// will attempt merge setcc and brc instructions into brcc's. -/// -namespace { -class VISIBILITY_HIDDEN DAGTypeLegalizer { - TargetLowering &TLI; - SelectionDAG &DAG; - - // NodeIDFlags - This pass uses the NodeID on the SDNodes to hold information - // about the state of the node. The enum has all the values. - enum NodeIDFlags { - /// ReadyToProcess - All operands have been processed, so this node is ready - /// to be handled. - ReadyToProcess = 0, - - /// NewNode - This is a new node that was created in the process of - /// legalizing some other node. - NewNode = -1, - - /// Processed - This is a node that has already been processed. - Processed = -2 - - // 1+ - This is a node which has this many unlegalized operands. - }; - - enum LegalizeAction { - Legal, // The target natively supports this type. - Promote, // This type should be executed in a larger type. - Expand // This type should be split into two types of half the size. - }; - - /// ValueTypeActions - This is a bitvector that contains two bits for each - /// simple value type, where the two bits correspond to the LegalizeAction - /// enum. This can be queried with "getTypeAction(VT)". - TargetLowering::ValueTypeActionImpl ValueTypeActions; - - /// getTypeAction - Return how we should legalize values of this type, either - /// it is already legal or we need to expand it into multiple registers of - /// smaller integer type, or we need to promote it to a larger type. - LegalizeAction getTypeAction(MVT::ValueType VT) const { - return (LegalizeAction)ValueTypeActions.getTypeAction(VT); - } - - /// isTypeLegal - Return true if this type is legal on this target. - /// - bool isTypeLegal(MVT::ValueType VT) const { - return getTypeAction(VT) == Legal; - } - - SDOperand getIntPtrConstant(uint64_t Val) { - return DAG.getConstant(Val, TLI.getPointerTy()); - } - - /// PromotedNodes - For nodes that are below legal width, this map indicates - /// what promoted value to use. - DenseMap PromotedNodes; - - /// ExpandedNodes - For nodes that need to be expanded this map indicates - /// which operands are the expanded version of the input. - DenseMap > ExpandedNodes; - - /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the - /// scalar value of type 'ty' to use. - DenseMap ScalarizedNodes; - - /// ReplacedNodes - For nodes that have been replaced with another, - /// indicates the replacement node to use. - DenseMap ReplacedNodes; - - /// Worklist - This defines a worklist of nodes to process. In order to be - /// pushed onto this worklist, all operands of a node must have already been - /// processed. - SmallVector Worklist; - -public: - explicit DAGTypeLegalizer(SelectionDAG &dag) - : TLI(dag.getTargetLoweringInfo()), DAG(dag), - ValueTypeActions(TLI.getValueTypeActions()) { - assert(MVT::LAST_VALUETYPE <= 32 && - "Too many value types for ValueTypeActions to hold!"); - } - - void run(); - -private: - void MarkNewNodes(SDNode *N); - - void ReplaceValueWith(SDOperand From, SDOperand To); - void ReplaceNodeWith(SDNode *From, SDNode *To); - - void RemapNode(SDOperand &N); - - SDOperand GetPromotedOp(SDOperand Op) { - SDOperand &PromotedOp = PromotedNodes[Op]; - RemapNode(PromotedOp); - assert(PromotedOp.Val && "Operand wasn't promoted?"); - return PromotedOp; - } - void SetPromotedOp(SDOperand Op, SDOperand Result); - - /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final - /// size. - SDOperand GetPromotedZExtOp(SDOperand Op) { - MVT::ValueType OldVT = Op.getValueType(); - Op = GetPromotedOp(Op); - return DAG.getZeroExtendInReg(Op, OldVT); - } - - void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); - void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi); - - SDOperand GetScalarizedOp(SDOperand Op) { - SDOperand &ScalarOp = ScalarizedNodes[Op]; - RemapNode(ScalarOp); - assert(ScalarOp.Val && "Operand wasn't scalarized?"); - return ScalarOp; - } - void SetScalarizedOp(SDOperand Op, SDOperand Result); - - // Common routines. - SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); - SDOperand HandleMemIntrinsic(SDNode *N); - void SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); - - // Result Promotion. - void PromoteResult(SDNode *N, unsigned ResNo); - SDOperand PromoteResult_UNDEF(SDNode *N); - SDOperand PromoteResult_Constant(SDNode *N); - SDOperand PromoteResult_TRUNCATE(SDNode *N); - SDOperand PromoteResult_INT_EXTEND(SDNode *N); - SDOperand PromoteResult_FP_ROUND(SDNode *N); - SDOperand PromoteResult_FP_TO_XINT(SDNode *N); - SDOperand PromoteResult_SETCC(SDNode *N); - SDOperand PromoteResult_LOAD(LoadSDNode *N); - SDOperand PromoteResult_SimpleIntBinOp(SDNode *N); - SDOperand PromoteResult_SDIV(SDNode *N); - SDOperand PromoteResult_UDIV(SDNode *N); - SDOperand PromoteResult_SHL(SDNode *N); - SDOperand PromoteResult_SRA(SDNode *N); - SDOperand PromoteResult_SRL(SDNode *N); - SDOperand PromoteResult_SELECT (SDNode *N); - SDOperand PromoteResult_SELECT_CC(SDNode *N); - - // Result Expansion. - void ExpandResult(SDNode *N, unsigned ResNo); - void ExpandResult_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); - - void ExpandResult_Logical (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_BSWAP (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_ADDSUBC (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_ADDSUBE (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandResult_Shift (SDNode *N, SDOperand &Lo, SDOperand &Hi); - - void ExpandShiftByConstant(SDNode *N, unsigned Amt, - SDOperand &Lo, SDOperand &Hi); - bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi); - - // Result Vector Scalarization: <1 x ty> -> ty. - void ScalarizeResult(SDNode *N, unsigned OpNo); - SDOperand ScalarizeRes_UNDEF(SDNode *N); - SDOperand ScalarizeRes_LOAD(LoadSDNode *N); - SDOperand ScalarizeRes_BinOp(SDNode *N); - SDOperand ScalarizeRes_UnaryOp(SDNode *N); - SDOperand ScalarizeRes_FPOWI(SDNode *N); - SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N); - SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N); - SDOperand ScalarizeRes_SELECT(SDNode *N); - - // Operand Promotion. - bool PromoteOperand(SDNode *N, unsigned OperandNo); - SDOperand PromoteOperand_ANY_EXTEND(SDNode *N); - SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N); - SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N); - SDOperand PromoteOperand_TRUNCATE(SDNode *N); - SDOperand PromoteOperand_FP_EXTEND(SDNode *N); - SDOperand PromoteOperand_FP_ROUND(SDNode *N); - SDOperand PromoteOperand_INT_TO_FP(SDNode *N); - SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo); - - void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code); - - // Operand Expansion. - bool ExpandOperand(SDNode *N, unsigned OperandNo); - SDOperand ExpandOperand_TRUNCATE(SDNode *N); - SDOperand ExpandOperand_BIT_CONVERT(SDNode *N); - SDOperand ExpandOperand_UINT_TO_FP(SDOperand Source, MVT::ValueType DestTy); - SDOperand ExpandOperand_SINT_TO_FP(SDOperand Source, MVT::ValueType DestTy); - SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N); - SDOperand ExpandOperand_SETCC(SDNode *N); - SDOperand ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo); - - void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, - ISD::CondCode &CCCode); - - // Operand Vector Scalarization: <1 x ty> -> ty. - bool ScalarizeOperand(SDNode *N, unsigned OpNo); - SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); - -}; -} // end anonymous namespace - - - /// run - This is the main entry point for the type legalizer. This does a /// top-down traversal of the dag, legalizing types as it goes. void DAGTypeLegalizer::run() { Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44714&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (added) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 14:16:06 2007 @@ -0,0 +1,255 @@ +//===-- LegalizeTypes.h - Definition of the DAG Type Legalizer class ------===// +// +// 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 the DAGTypeLegalizer class. This is a private interface +// shared between the code that implements the SelectionDAG::LegalizeTypes +// method. +// +//===----------------------------------------------------------------------===// + +#ifndef SELECTIONDAG_LEGALIZETYPES_H +#define SELECTIONDAG_LEGALIZETYPES_H + +#define DEBUG_TYPE "legalize-types" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// DAGTypeLegalizer - This takes an arbitrary SelectionDAG as input and +/// hacks on it until the target machine can handle it. This involves +/// eliminating value sizes the machine cannot handle (promoting small sizes to +/// large sizes or splitting up large values into small values) as well as +/// eliminating operations the machine cannot handle. +/// +/// This code also does a small amount of optimization and recognition of idioms +/// as part of its processing. For example, if a target does not support a +/// 'setcc' instruction efficiently, but does support 'brcc' instruction, this +/// will attempt merge setcc and brc instructions into brcc's. +/// +class VISIBILITY_HIDDEN DAGTypeLegalizer { + TargetLowering &TLI; + SelectionDAG &DAG; + + // NodeIDFlags - This pass uses the NodeID on the SDNodes to hold information + // about the state of the node. The enum has all the values. + enum NodeIDFlags { + /// ReadyToProcess - All operands have been processed, so this node is ready + /// to be handled. + ReadyToProcess = 0, + + /// NewNode - This is a new node that was created in the process of + /// legalizing some other node. + NewNode = -1, + + /// Processed - This is a node that has already been processed. + Processed = -2 + + // 1+ - This is a node which has this many unlegalized operands. + }; + + enum LegalizeAction { + Legal, // The target natively supports this type. + Promote, // This type should be executed in a larger type. + Expand // This type should be split into two types of half the size. + }; + + /// ValueTypeActions - This is a bitvector that contains two bits for each + /// simple value type, where the two bits correspond to the LegalizeAction + /// enum. This can be queried with "getTypeAction(VT)". + TargetLowering::ValueTypeActionImpl ValueTypeActions; + + /// getTypeAction - Return how we should legalize values of this type, either + /// it is already legal or we need to expand it into multiple registers of + /// smaller integer type, or we need to promote it to a larger type. + LegalizeAction getTypeAction(MVT::ValueType VT) const { + return (LegalizeAction)ValueTypeActions.getTypeAction(VT); + } + + /// isTypeLegal - Return true if this type is legal on this target. + /// + bool isTypeLegal(MVT::ValueType VT) const { + return getTypeAction(VT) == Legal; + } + + SDOperand getIntPtrConstant(uint64_t Val) { + return DAG.getConstant(Val, TLI.getPointerTy()); + } + + /// PromotedNodes - For nodes that are below legal width, this map indicates + /// what promoted value to use. + DenseMap PromotedNodes; + + /// ExpandedNodes - For nodes that need to be expanded this map indicates + /// which operands are the expanded version of the input. + DenseMap > ExpandedNodes; + + /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the + /// scalar value of type 'ty' to use. + DenseMap ScalarizedNodes; + + /// ReplacedNodes - For nodes that have been replaced with another, + /// indicates the replacement node to use. + DenseMap ReplacedNodes; + + /// Worklist - This defines a worklist of nodes to process. In order to be + /// pushed onto this worklist, all operands of a node must have already been + /// processed. + SmallVector Worklist; + +public: + explicit DAGTypeLegalizer(SelectionDAG &dag) + : TLI(dag.getTargetLoweringInfo()), DAG(dag), + ValueTypeActions(TLI.getValueTypeActions()) { + assert(MVT::LAST_VALUETYPE <= 32 && + "Too many value types for ValueTypeActions to hold!"); + } + + void run(); + +private: + void MarkNewNodes(SDNode *N); + + void ReplaceValueWith(SDOperand From, SDOperand To); + void ReplaceNodeWith(SDNode *From, SDNode *To); + + void RemapNode(SDOperand &N); + + SDOperand GetPromotedOp(SDOperand Op) { + SDOperand &PromotedOp = PromotedNodes[Op]; + RemapNode(PromotedOp); + assert(PromotedOp.Val && "Operand wasn't promoted?"); + return PromotedOp; + } + void SetPromotedOp(SDOperand Op, SDOperand Result); + + /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final + /// size. + SDOperand GetPromotedZExtOp(SDOperand Op) { + MVT::ValueType OldVT = Op.getValueType(); + Op = GetPromotedOp(Op); + return DAG.getZeroExtendInReg(Op, OldVT); + } + + void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); + void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi); + + SDOperand GetScalarizedOp(SDOperand Op) { + SDOperand &ScalarOp = ScalarizedNodes[Op]; + RemapNode(ScalarOp); + assert(ScalarOp.Val && "Operand wasn't scalarized?"); + return ScalarOp; + } + void SetScalarizedOp(SDOperand Op, SDOperand Result); + + // Common routines. + SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); + SDOperand HandleMemIntrinsic(SDNode *N); + void SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); + + // Result Promotion. + void PromoteResult(SDNode *N, unsigned ResNo); + SDOperand PromoteResult_UNDEF(SDNode *N); + SDOperand PromoteResult_Constant(SDNode *N); + SDOperand PromoteResult_TRUNCATE(SDNode *N); + SDOperand PromoteResult_INT_EXTEND(SDNode *N); + SDOperand PromoteResult_FP_ROUND(SDNode *N); + SDOperand PromoteResult_FP_TO_XINT(SDNode *N); + SDOperand PromoteResult_SETCC(SDNode *N); + SDOperand PromoteResult_LOAD(LoadSDNode *N); + SDOperand PromoteResult_SimpleIntBinOp(SDNode *N); + SDOperand PromoteResult_SDIV(SDNode *N); + SDOperand PromoteResult_UDIV(SDNode *N); + SDOperand PromoteResult_SHL(SDNode *N); + SDOperand PromoteResult_SRA(SDNode *N); + SDOperand PromoteResult_SRL(SDNode *N); + SDOperand PromoteResult_SELECT (SDNode *N); + SDOperand PromoteResult_SELECT_CC(SDNode *N); + + // Result Expansion. + void ExpandResult(SDNode *N, unsigned ResNo); + void ExpandResult_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); + + void ExpandResult_Logical (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_BSWAP (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_ADDSUBC (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_ADDSUBE (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_Shift (SDNode *N, SDOperand &Lo, SDOperand &Hi); + + void ExpandShiftByConstant(SDNode *N, unsigned Amt, + SDOperand &Lo, SDOperand &Hi); + bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi); + + // Result Vector Scalarization: <1 x ty> -> ty. + void ScalarizeResult(SDNode *N, unsigned OpNo); + SDOperand ScalarizeRes_UNDEF(SDNode *N); + SDOperand ScalarizeRes_LOAD(LoadSDNode *N); + SDOperand ScalarizeRes_BinOp(SDNode *N); + SDOperand ScalarizeRes_UnaryOp(SDNode *N); + SDOperand ScalarizeRes_FPOWI(SDNode *N); + SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N); + SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N); + SDOperand ScalarizeRes_SELECT(SDNode *N); + + // Operand Promotion. + bool PromoteOperand(SDNode *N, unsigned OperandNo); + SDOperand PromoteOperand_ANY_EXTEND(SDNode *N); + SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N); + SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N); + SDOperand PromoteOperand_TRUNCATE(SDNode *N); + SDOperand PromoteOperand_FP_EXTEND(SDNode *N); + SDOperand PromoteOperand_FP_ROUND(SDNode *N); + SDOperand PromoteOperand_INT_TO_FP(SDNode *N); + SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo); + + void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code); + + // Operand Expansion. + bool ExpandOperand(SDNode *N, unsigned OperandNo); + SDOperand ExpandOperand_TRUNCATE(SDNode *N); + SDOperand ExpandOperand_BIT_CONVERT(SDNode *N); + SDOperand ExpandOperand_UINT_TO_FP(SDOperand Source, MVT::ValueType DestTy); + SDOperand ExpandOperand_SINT_TO_FP(SDOperand Source, MVT::ValueType DestTy); + SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N); + SDOperand ExpandOperand_SETCC(SDNode *N); + SDOperand ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo); + + void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, + ISD::CondCode &CCCode); + + // Operand Vector Scalarization: <1 x ty> -> ty. + bool ScalarizeOperand(SDNode *N, unsigned OpNo); + SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); + +}; + +} // end namespace llvm. + +#endif From sabre at nondot.org Sat Dec 8 14:17:14 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 20:17:14 -0000 Subject: [llvm-commits] [llvm] r44715 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeDAGTypes.cpp LegalizeTypes.cpp Message-ID: <200712082017.lB8KHEjj007246@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 14:17:13 2007 New Revision: 44715 URL: http://llvm.org/viewvc/llvm-project?rev=44715&view=rev Log: Rename LegalizeDAGTypes.cpp -> LegalizeTypes.cpp Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp - copied, changed from r44714, llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44714&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (removed) @@ -1,2217 +0,0 @@ -//===-- LegalizeDAGTypes.cpp - Implement SelectionDAG::LegalizeTypes ------===// -// -// 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 the SelectionDAG::LegalizeTypes method. It transforms -// an arbitrary well-formed SelectionDAG to only consist of legal types. -// -//===----------------------------------------------------------------------===// - -#include "LegalizeTypes.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" -using namespace llvm; - -/// run - This is the main entry point for the type legalizer. This does a -/// top-down traversal of the dag, legalizing types as it goes. -void DAGTypeLegalizer::run() { - // Create a dummy node (which is not added to allnodes), that adds a reference - // to the root node, preventing it from being deleted, and tracking any - // changes of the root. - HandleSDNode Dummy(DAG.getRoot()); - - // The root of the dag may dangle to deleted nodes until the type legalizer is - // done. Set it to null to avoid confusion. - DAG.setRoot(SDOperand()); - - // Walk all nodes in the graph, assigning them a NodeID of 'ReadyToProcess' - // (and remembering them) if they are leaves and assigning 'NewNode' if - // non-leaves. - for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), - E = DAG.allnodes_end(); I != E; ++I) { - if (I->getNumOperands() == 0) { - I->setNodeId(ReadyToProcess); - Worklist.push_back(I); - } else { - I->setNodeId(NewNode); - } - } - - // Now that we have a set of nodes to process, handle them all. - while (!Worklist.empty()) { - SDNode *N = Worklist.back(); - Worklist.pop_back(); - assert(N->getNodeId() == ReadyToProcess && - "Node should be ready if on worklist!"); - - // Scan the values produced by the node, checking to see if any result - // types are illegal. - unsigned i = 0; - unsigned NumResults = N->getNumValues(); - do { - MVT::ValueType ResultVT = N->getValueType(i); - LegalizeAction Action = getTypeAction(ResultVT); - if (Action == Promote) { - PromoteResult(N, i); - goto NodeDone; - } else if (Action == Expand) { - // Expand can mean 1) split integer in half 2) scalarize single-element - // vector 3) split vector in half. - if (!MVT::isVector(ResultVT)) - ExpandResult(N, i); - else if (MVT::getVectorNumElements(ResultVT) == 1) - ScalarizeResult(N, i); // Scalarize the single-element vector. - else // Split the vector in half. - assert(0 && "Vector splitting not implemented"); - goto NodeDone; - } else { - assert(Action == Legal && "Unknown action!"); - } - } while (++i < NumResults); - - // Scan the operand list for the node, handling any nodes with operands that - // are illegal. - { - unsigned NumOperands = N->getNumOperands(); - bool NeedsRevisit = false; - for (i = 0; i != NumOperands; ++i) { - MVT::ValueType OpVT = N->getOperand(i).getValueType(); - LegalizeAction Action = getTypeAction(OpVT); - if (Action == Promote) { - NeedsRevisit = PromoteOperand(N, i); - break; - } else if (Action == Expand) { - // Expand can mean 1) split integer in half 2) scalarize single-element - // vector 3) split vector in half. - if (!MVT::isVector(OpVT)) { - NeedsRevisit = ExpandOperand(N, i); - } else if (MVT::getVectorNumElements(OpVT) == 1) { - // Scalarize the single-element vector. - NeedsRevisit = ScalarizeOperand(N, i); - } else { - // Split the vector in half. - assert(0 && "Vector splitting not implemented"); - } - break; - } else { - assert(Action == Legal && "Unknown action!"); - } - } - - // If the node needs revisiting, don't add all users to the worklist etc. - if (NeedsRevisit) - continue; - - if (i == NumOperands) - DEBUG(cerr << "Legally typed node: "; N->dump(&DAG); cerr << "\n"); - } -NodeDone: - - // If we reach here, the node was processed, potentially creating new nodes. - // Mark it as processed and add its users to the worklist as appropriate. - N->setNodeId(Processed); - - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); - UI != E; ++UI) { - SDNode *User = *UI; - int NodeID = User->getNodeId(); - assert(NodeID != ReadyToProcess && NodeID != Processed && - "Invalid node id for user of unprocessed node!"); - - // This node has two options: it can either be a new node or its Node ID - // may be a count of the number of operands it has that are not ready. - if (NodeID > 0) { - User->setNodeId(NodeID-1); - - // If this was the last use it was waiting on, add it to the ready list. - if (NodeID-1 == ReadyToProcess) - Worklist.push_back(User); - continue; - } - - // Otherwise, this node is new: this is the first operand of it that - // became ready. Its new NodeID is the number of operands it has minus 1 - // (as this node is now processed). - assert(NodeID == NewNode && "Unknown node ID!"); - User->setNodeId(User->getNumOperands()-1); - - // If the node only has a single operand, it is now ready. - if (User->getNumOperands() == 1) - Worklist.push_back(User); - } - } - - // If the root changed (e.g. it was a dead load, update the root). - DAG.setRoot(Dummy.getValue()); - - //DAG.viewGraph(); - - // Remove dead nodes. This is important to do for cleanliness but also before - // the checking loop below. Implicit folding by the DAG.getNode operators can - // cause unreachable nodes to be around with their flags set to new. - DAG.RemoveDeadNodes(); - - // In a debug build, scan all the nodes to make sure we found them all. This - // ensures that there are no cycles and that everything got processed. -#ifndef NDEBUG - for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), - E = DAG.allnodes_end(); I != E; ++I) { - if (I->getNodeId() == Processed) - continue; - cerr << "Unprocessed node: "; - I->dump(&DAG); cerr << "\n"; - - if (I->getNodeId() == NewNode) - cerr << "New node not 'noticed'?\n"; - else if (I->getNodeId() > 0) - cerr << "Operand not processed?\n"; - else if (I->getNodeId() == ReadyToProcess) - cerr << "Not added to worklist?\n"; - abort(); - } -#endif -} - -/// MarkNewNodes - The specified node is the root of a subtree of potentially -/// new nodes. Add the correct NodeId to mark it. -void DAGTypeLegalizer::MarkNewNodes(SDNode *N) { - // If this was an existing node that is already done, we're done. - if (N->getNodeId() != NewNode) - return; - - // Okay, we know that this node is new. Recursively walk all of its operands - // to see if they are new also. The depth of this walk is bounded by the size - // of the new tree that was constructed (usually 2-3 nodes), so we don't worry - // about revisiting of nodes. - // - // As we walk the operands, keep track of the number of nodes that are - // processed. If non-zero, this will become the new nodeid of this node. - unsigned NumProcessed = 0; - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - int OpId = N->getOperand(i).Val->getNodeId(); - if (OpId == NewNode) - MarkNewNodes(N->getOperand(i).Val); - else if (OpId == Processed) - ++NumProcessed; - } - - N->setNodeId(N->getNumOperands()-NumProcessed); - if (N->getNodeId() == ReadyToProcess) - Worklist.push_back(N); -} - -/// ReplaceValueWith - The specified value was legalized to the specified other -/// value. If they are different, update the DAG and NodeIDs replacing any uses -/// of From to use To instead. -void DAGTypeLegalizer::ReplaceValueWith(SDOperand From, SDOperand To) { - if (From == To) return; - - // If expansion produced new nodes, make sure they are properly marked. - if (To.Val->getNodeId() == NewNode) - MarkNewNodes(To.Val); - - // Anything that used the old node should now use the new one. Note that this - // can potentially cause recursive merging. - DAG.ReplaceAllUsesOfValueWith(From, To); - - // The old node may still be present in ExpandedNodes or PromotedNodes. - // Inform them about the replacement. - ReplacedNodes[From] = To; - - // Since we just made an unstructured update to the DAG, which could wreak - // general havoc on anything that once used From and now uses To, walk all - // users of the result, updating their flags. - for (SDNode::use_iterator I = To.Val->use_begin(), E = To.Val->use_end(); - I != E; ++I) { - SDNode *User = *I; - // If the node isn't already processed or in the worklist, mark it as new, - // then use MarkNewNodes to recompute its ID. - int NodeId = User->getNodeId(); - if (NodeId != ReadyToProcess && NodeId != Processed) { - User->setNodeId(NewNode); - MarkNewNodes(User); - } - } -} - -/// ReplaceNodeWith - Replace uses of the 'from' node's results with the 'to' -/// node's results. The from and to node must define identical result types. -void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) { - if (From == To) return; - assert(From->getNumValues() == To->getNumValues() && - "Node results don't match"); - - // If expansion produced new nodes, make sure they are properly marked. - if (To->getNodeId() == NewNode) - MarkNewNodes(To); - - // Anything that used the old node should now use the new one. Note that this - // can potentially cause recursive merging. - DAG.ReplaceAllUsesWith(From, To); - - // The old node may still be present in ExpandedNodes or PromotedNodes. - // Inform them about the replacement. - for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) { - assert(From->getValueType(i) == To->getValueType(i) && - "Node results don't match"); - ReplacedNodes[SDOperand(From, i)] = SDOperand(To, i); - } - - // Since we just made an unstructured update to the DAG, which could wreak - // general havoc on anything that once used From and now uses To, walk all - // users of the result, updating their flags. - for (SDNode::use_iterator I = To->use_begin(), E = To->use_end();I != E; ++I){ - SDNode *User = *I; - // If the node isn't already processed or in the worklist, mark it as new, - // then use MarkNewNodes to recompute its ID. - int NodeId = User->getNodeId(); - if (NodeId != ReadyToProcess && NodeId != Processed) { - User->setNodeId(NewNode); - MarkNewNodes(User); - } - } -} - - -/// RemapNode - If the specified value was already legalized to another value, -/// replace it by that value. -void DAGTypeLegalizer::RemapNode(SDOperand &N) { - DenseMap::iterator I = ReplacedNodes.find(N); - if (I != ReplacedNodes.end()) { - // Use path compression to speed up future lookups if values get multiply - // replaced with other values. - RemapNode(I->second); - N = I->second; - } -} - -void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) { - if (Result.Val->getNodeId() == NewNode) - MarkNewNodes(Result.Val); - - SDOperand &OpEntry = PromotedNodes[Op]; - assert(OpEntry.Val == 0 && "Node is already promoted!"); - OpEntry = Result; -} - -void DAGTypeLegalizer::SetScalarizedOp(SDOperand Op, SDOperand Result) { - if (Result.Val->getNodeId() == NewNode) - MarkNewNodes(Result.Val); - - SDOperand &OpEntry = ScalarizedNodes[Op]; - assert(OpEntry.Val == 0 && "Node is already scalarized!"); - OpEntry = Result; -} - - -void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo, - SDOperand &Hi) { - std::pair &Entry = ExpandedNodes[Op]; - RemapNode(Entry.first); - RemapNode(Entry.second); - assert(Entry.first.Val && "Operand isn't expanded"); - Lo = Entry.first; - Hi = Entry.second; -} - -void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, - SDOperand Hi) { - // Remember that this is the result of the node. - std::pair &Entry = ExpandedNodes[Op]; - assert(Entry.first.Val == 0 && "Node already expanded"); - Entry.first = Lo; - Entry.second = Hi; - - // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant. - if (Lo.Val->getNodeId() == NewNode) - MarkNewNodes(Lo.Val); - if (Hi.Val->getNodeId() == NewNode) - MarkNewNodes(Hi.Val); -} - -SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op, - MVT::ValueType DestVT) { - // Create the stack frame object. - SDOperand FIPtr = DAG.CreateStackTemporary(DestVT); - - // Emit a store to the stack slot. - SDOperand Store = DAG.getStore(DAG.getEntryNode(), Op, FIPtr, NULL, 0); - // Result is a load from the stack slot. - return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0); -} - -/// HandleMemIntrinsic - This handles memcpy/memset/memmove with invalid -/// operands. This promotes or expands the operands as required. -SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) { - // The chain and pointer [operands #0 and #1] are always valid types. - SDOperand Chain = N->getOperand(0); - SDOperand Ptr = N->getOperand(1); - SDOperand Op2 = N->getOperand(2); - - // Op #2 is either a value (memset) or a pointer. Promote it if required. - switch (getTypeAction(Op2.getValueType())) { - default: assert(0 && "Unknown action for pointer/value operand"); - case Legal: break; - case Promote: Op2 = GetPromotedOp(Op2); break; - } - - // The length could have any action required. - SDOperand Length = N->getOperand(3); - switch (getTypeAction(Length.getValueType())) { - default: assert(0 && "Unknown action for memop operand"); - case Legal: break; - case Promote: Length = GetPromotedZExtOp(Length); break; - case Expand: - SDOperand Dummy; // discard the high part. - GetExpandedOp(Length, Length, Dummy); - break; - } - - SDOperand Align = N->getOperand(4); - switch (getTypeAction(Align.getValueType())) { - default: assert(0 && "Unknown action for memop operand"); - case Legal: break; - case Promote: Align = GetPromotedZExtOp(Align); break; - } - - SDOperand AlwaysInline = N->getOperand(5); - switch (getTypeAction(AlwaysInline.getValueType())) { - default: assert(0 && "Unknown action for memop operand"); - case Legal: break; - case Promote: AlwaysInline = GetPromotedZExtOp(AlwaysInline); break; - } - - SDOperand Ops[] = { Chain, Ptr, Op2, Length, Align, AlwaysInline }; - return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6); -} - -/// SplitOp - Return the lower and upper halves of Op's bits in a value type -/// half the size of Op's. -void DAGTypeLegalizer::SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { - unsigned NVTBits = MVT::getSizeInBits(Op.getValueType())/2; - assert(MVT::getSizeInBits(Op.getValueType()) == 2*NVTBits && - "Cannot split odd sized integer type"); - MVT::ValueType NVT = MVT::getIntegerType(NVTBits); - Lo = DAG.getNode(ISD::TRUNCATE, NVT, Op); - Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, - DAG.getConstant(NVTBits, TLI.getShiftAmountTy())); - Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi); -} - - -//===----------------------------------------------------------------------===// -// Result Promotion -//===----------------------------------------------------------------------===// - -/// PromoteResult - This method is called when a result of a node is found to be -/// in need of promotion to a larger type. At this point, the node may also -/// have invalid operands or may have other results that need expansion, we just -/// know that (at least) one result needs promotion. -void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) { - DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n"); - SDOperand Result = SDOperand(); - - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "PromoteResult #" << ResNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator!"); - abort(); - case ISD::UNDEF: Result = PromoteResult_UNDEF(N); break; - case ISD::Constant: Result = PromoteResult_Constant(N); break; - - case ISD::TRUNCATE: Result = PromoteResult_TRUNCATE(N); break; - case ISD::SIGN_EXTEND: - case ISD::ZERO_EXTEND: - case ISD::ANY_EXTEND: Result = PromoteResult_INT_EXTEND(N); break; - case ISD::FP_ROUND: Result = PromoteResult_FP_ROUND(N); break; - case ISD::FP_TO_SINT: - case ISD::FP_TO_UINT: Result = PromoteResult_FP_TO_XINT(N); break; - case ISD::SETCC: Result = PromoteResult_SETCC(N); break; - case ISD::LOAD: Result = PromoteResult_LOAD(cast(N)); break; - - case ISD::AND: - case ISD::OR: - case ISD::XOR: - case ISD::ADD: - case ISD::SUB: - case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break; - - case ISD::SDIV: - case ISD::SREM: Result = PromoteResult_SDIV(N); break; - - case ISD::UDIV: - case ISD::UREM: Result = PromoteResult_UDIV(N); break; - - case ISD::SHL: Result = PromoteResult_SHL(N); break; - case ISD::SRA: Result = PromoteResult_SRA(N); break; - case ISD::SRL: Result = PromoteResult_SRL(N); break; - - case ISD::SELECT: Result = PromoteResult_SELECT(N); break; - case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break; - - } - - // If Result is null, the sub-method took care of registering the result. - if (Result.Val) - SetPromotedOp(SDOperand(N, ResNo), Result); -} - -SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0))); -} - -SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) { - MVT::ValueType VT = N->getValueType(0); - // Zero extend things like i1, sign extend everything else. It shouldn't - // matter in theory which one we pick, but this tends to give better code? - unsigned Opc = VT != MVT::i1 ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; - SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT), - SDOperand(N, 0)); - assert(isa(Result) && "Didn't constant fold ext?"); - return Result; -} - -SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) { - SDOperand Res; - - switch (getTypeAction(N->getOperand(0).getValueType())) { - default: assert(0 && "Unknown type action!"); - case Legal: - case Expand: - Res = N->getOperand(0); - break; - case Promote: - Res = GetPromotedOp(N->getOperand(0)); - break; - } - - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - assert(MVT::getSizeInBits(Res.getValueType()) >= MVT::getSizeInBits(NVT) && - "Truncation doesn't make sense!"); - if (Res.getValueType() == NVT) - return Res; - - // Truncate to NVT instead of VT - return DAG.getNode(ISD::TRUNCATE, NVT, Res); -} - -SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - - if (getTypeAction(N->getOperand(0).getValueType()) == Promote) { - SDOperand Res = GetPromotedOp(N->getOperand(0)); - assert(MVT::getSizeInBits(Res.getValueType()) <= MVT::getSizeInBits(NVT) && - "Extension doesn't make sense!"); - - // If the result and operand types are the same after promotion, simplify - // to an in-register extension. - if (NVT == Res.getValueType()) { - // The high bits are not guaranteed to be anything. Insert an extend. - if (N->getOpcode() == ISD::SIGN_EXTEND) - return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, - DAG.getValueType(N->getOperand(0).getValueType())); - if (N->getOpcode() == ISD::ZERO_EXTEND) - return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType()); - assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!"); - return Res; - } - } - - // Otherwise, just extend the original operand all the way to the larger type. - return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) { - // NOTE: Assumes input is legal. - return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(), - N->getOperand(0), DAG.getValueType(N->getValueType(0))); -} - -SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) { - SDOperand Op = N->getOperand(0); - // If the operand needed to be promoted, do so now. - if (getTypeAction(Op.getValueType()) == Promote) - // The input result is prerounded, so we don't have to do anything special. - Op = GetPromotedOp(Op); - - unsigned NewOpc = N->getOpcode(); - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - - // If we're promoting a UINT to a larger size, check to see if the new node - // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since - // we can use that instead. This allows us to generate better code for - // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not - // legal, such as PowerPC. - if (N->getOpcode() == ISD::FP_TO_UINT) { - if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && - (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || - TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)) - NewOpc = ISD::FP_TO_SINT; - } - - return DAG.getNode(NewOpc, NVT, Op); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) { - assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??"); - return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0), - N->getOperand(1), N->getOperand(2)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - ISD::LoadExtType ExtType = - ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); - SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(), - N->getSrcValue(), N->getSrcValueOffset(), - N->getLoadedVT(), N->isVolatile(), - N->getAlignment()); - - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Res.getValue(1)); - return Res; -} - -SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) { - // The input may have strange things in the top bits of the registers, but - // these operations don't care. They may have weird bits going out, but - // that too is okay if they are integer operations. - SDOperand LHS = GetPromotedOp(N->getOperand(0)); - SDOperand RHS = GetPromotedOp(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SDIV(SDNode *N) { - // Sign extend the input. - SDOperand LHS = GetPromotedOp(N->getOperand(0)); - SDOperand RHS = GetPromotedOp(N->getOperand(1)); - MVT::ValueType VT = N->getValueType(0); - LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS, - DAG.getValueType(VT)); - RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS, - DAG.getValueType(VT)); - - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_UDIV(SDNode *N) { - // Zero extend the input. - SDOperand LHS = GetPromotedOp(N->getOperand(0)); - SDOperand RHS = GetPromotedOp(N->getOperand(1)); - MVT::ValueType VT = N->getValueType(0); - LHS = DAG.getZeroExtendInReg(LHS, VT); - RHS = DAG.getZeroExtendInReg(RHS, VT); - - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SHL(SDNode *N) { - return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)), - GetPromotedOp(N->getOperand(0)), N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SRA(SDNode *N) { - // The input value must be properly sign extended. - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Res = GetPromotedOp(N->getOperand(0)); - Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT)); - return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SRL(SDNode *N) { - // The input value must be properly zero extended. - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Res = GetPromotedZExtOp(N->getOperand(0)); - return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) { - SDOperand LHS = GetPromotedOp(N->getOperand(1)); - SDOperand RHS = GetPromotedOp(N->getOperand(2)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) { - SDOperand LHS = GetPromotedOp(N->getOperand(2)); - SDOperand RHS = GetPromotedOp(N->getOperand(3)); - return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), - N->getOperand(1), LHS, RHS, N->getOperand(4)); -} - - -//===----------------------------------------------------------------------===// -// Result Expansion -//===----------------------------------------------------------------------===// - -/// ExpandResult - This method is called when the specified result of the -/// specified node is found to need expansion. At this point, the node may also -/// have invalid operands or may have other results that need promotion, we just -/// know that (at least) one result needs expansion. -void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) { - DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); - SDOperand Lo, Hi; - Lo = Hi = SDOperand(); - - // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } - - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ExpandResult #" << ResNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to expand the result of this operator!"); - abort(); - - case ISD::UNDEF: ExpandResult_UNDEF(N, Lo, Hi); break; - case ISD::Constant: ExpandResult_Constant(N, Lo, Hi); break; - case ISD::BUILD_PAIR: ExpandResult_BUILD_PAIR(N, Lo, Hi); break; - case ISD::MERGE_VALUES: ExpandResult_MERGE_VALUES(N, Lo, Hi); break; - case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break; - case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break; - case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break; - case ISD::BIT_CONVERT: ExpandResult_BIT_CONVERT(N, Lo, Hi); break; - case ISD::SIGN_EXTEND_INREG: ExpandResult_SIGN_EXTEND_INREG(N, Lo, Hi); break; - case ISD::LOAD: ExpandResult_LOAD(cast(N), Lo, Hi); break; - - case ISD::AND: - case ISD::OR: - case ISD::XOR: ExpandResult_Logical(N, Lo, Hi); break; - case ISD::BSWAP: ExpandResult_BSWAP(N, Lo, Hi); break; - case ISD::ADD: - case ISD::SUB: ExpandResult_ADDSUB(N, Lo, Hi); break; - case ISD::ADDC: - case ISD::SUBC: ExpandResult_ADDSUBC(N, Lo, Hi); break; - case ISD::ADDE: - case ISD::SUBE: ExpandResult_ADDSUBE(N, Lo, Hi); break; - case ISD::SELECT: ExpandResult_SELECT(N, Lo, Hi); break; - case ISD::SELECT_CC: ExpandResult_SELECT_CC(N, Lo, Hi); break; - case ISD::MUL: ExpandResult_MUL(N, Lo, Hi); break; - case ISD::SHL: - case ISD::SRA: - case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break; - } - - // If Lo/Hi is null, the sub-method took care of registering results etc. - if (Lo.Val) - SetExpandedOp(SDOperand(N, ResNo), Lo, Hi); -} - -void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - Lo = Hi = DAG.getNode(ISD::UNDEF, NVT); -} - -void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - uint64_t Cst = cast(N)->getValue(); - Lo = DAG.getConstant(Cst, NVT); - Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT); -} - -void DAGTypeLegalizer::ExpandResult_BUILD_PAIR(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Return the operands. - Lo = N->getOperand(0); - Hi = N->getOperand(1); -} - -void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // A MERGE_VALUES node can produce any number of values. We know that the - // first illegal one needs to be expanded into Lo/Hi. - unsigned i; - - // The string of legal results gets turns into the input operands, which have - // the same type. - for (i = 0; isTypeLegal(N->getValueType(i)); ++i) - ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); - - // The first illegal result must be the one that needs to be expanded. - GetExpandedOp(N->getOperand(i), Lo, Hi); - - // Legalize the rest of the results into the input operands whether they are - // legal or not. - unsigned e = N->getNumValues(); - for (++i; i != e; ++i) - ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); -} - -void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Op = N->getOperand(0); - if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { - // The low part is any extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op); - Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined. - } else { - // For example, extension of an i48 to an i64. The operand type necessarily - // promotes to the result type, so will end up being expanded too. - assert(getTypeAction(Op.getValueType()) == Promote && - "Don't know how to expand this result!"); - SDOperand Res = GetPromotedOp(Op); - assert(Res.getValueType() == N->getValueType(0) && - "Operand over promoted?"); - // Split the promoted operand. This will simplify when it is expanded. - SplitOp(Res, Lo, Hi); - } -} - -void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Op = N->getOperand(0); - if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { - // The low part is zero extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); - Hi = DAG.getConstant(0, NVT); // The high part is just a zero. - } else { - // For example, extension of an i48 to an i64. The operand type necessarily - // promotes to the result type, so will end up being expanded too. - assert(getTypeAction(Op.getValueType()) == Promote && - "Don't know how to expand this result!"); - SDOperand Res = GetPromotedOp(Op); - assert(Res.getValueType() == N->getValueType(0) && - "Operand over promoted?"); - // Split the promoted operand. This will simplify when it is expanded. - SplitOp(Res, Lo, Hi); - unsigned ExcessBits = - MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); - Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits)); - } -} - -void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Op = N->getOperand(0); - if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { - // The low part is sign extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); - // The high part is obtained by SRA'ing all but one of the bits of low part. - unsigned LoSize = MVT::getSizeInBits(NVT); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); - } else { - // For example, extension of an i48 to an i64. The operand type necessarily - // promotes to the result type, so will end up being expanded too. - assert(getTypeAction(Op.getValueType()) == Promote && - "Don't know how to expand this result!"); - SDOperand Res = GetPromotedOp(Op); - assert(Res.getValueType() == N->getValueType(0) && - "Operand over promoted?"); - // Split the promoted operand. This will simplify when it is expanded. - SplitOp(Res, Lo, Hi); - unsigned ExcessBits = - MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); - Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, - DAG.getValueType(MVT::getIntegerType(ExcessBits))); - } -} - -void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Lower the bit-convert to a store/load from the stack, then expand the load. - SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); - ExpandResult_LOAD(cast(Op.Val), Lo, Hi); -} - -void DAGTypeLegalizer:: -ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - GetExpandedOp(N->getOperand(0), Lo, Hi); - MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); - - if (MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(Lo.getValueType())) { - // sext_inreg the low part if needed. - Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo, - N->getOperand(1)); - - // The high part gets the sign extension from the lo-part. This handles - // things like sextinreg V:i64 from i8. - Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo, - DAG.getConstant(MVT::getSizeInBits(Hi.getValueType())-1, - TLI.getShiftAmountTy())); - } else { - // For example, extension of an i48 to an i64. Leave the low part alone, - // sext_inreg the high part. - unsigned ExcessBits = - MVT::getSizeInBits(EVT) - MVT::getSizeInBits(Lo.getValueType()); - Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, - DAG.getValueType(MVT::getIntegerType(ExcessBits))); - } -} - -void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Ch = N->getChain(); // Legalize the chain. - SDOperand Ptr = N->getBasePtr(); // Legalize the pointer. - ISD::LoadExtType ExtType = N->getExtensionType(); - int SVOffset = N->getSrcValueOffset(); - unsigned Alignment = N->getAlignment(); - bool isVolatile = N->isVolatile(); - - assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); - - if (ExtType == ISD::NON_EXTLOAD) { - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - - // Handle endianness of the load. - if (!TLI.isLittleEndian()) - std::swap(Lo, Hi); - } else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) { - MVT::ValueType EVT = N->getLoadedVT(); - - Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT, - isVolatile, Alignment); - - // Remember the chain. - Ch = Lo.getValue(1); - - if (ExtType == ISD::SEXTLOAD) { - // The high part is obtained by SRA'ing all but one of the bits of the - // lo part. - unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); - } else if (ExtType == ISD::ZEXTLOAD) { - // The high part is just a zero. - Hi = DAG.getConstant(0, NVT); - } else { - assert(ExtType == ISD::EXTLOAD && "Unknown extload!"); - // The high part is undefined. - Hi = DAG.getNode(ISD::UNDEF, NVT); - } - } else if (TLI.isLittleEndian()) { - // Little-endian - low bits are at low addresses. - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - - unsigned ExcessBits = - MVT::getSizeInBits(N->getLoadedVT()) - MVT::getSizeInBits(NVT); - MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); - - // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, NEVT, - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - } else { - // Big-endian - high bits are at low addresses. Favor aligned loads at - // the cost of some bit-fiddling. - MVT::ValueType EVT = N->getLoadedVT(); - unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - unsigned ExcessBits = (EBytes - IncrementSize)*8; - - // Load both the high bits and maybe some of the low bits. - Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits), - isVolatile, Alignment); - - // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - // Load the rest of the low bits. - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits), - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - - if (ExcessBits < MVT::getSizeInBits(NVT)) { - // Transfer low bits from the bottom of Hi to the top of Lo. - Lo = DAG.getNode(ISD::OR, NVT, Lo, - DAG.getNode(ISD::SHL, NVT, Hi, - DAG.getConstant(ExcessBits, - TLI.getShiftAmountTy()))); - // Move high bits to the right position in Hi. - Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi, - DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, - TLI.getShiftAmountTy())); - } - } - - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Ch); -} - -void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(0), LL, LH); - GetExpandedOp(N->getOperand(1), RL, RH); - Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL); - Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH); -} - -void DAGTypeLegalizer::ExpandResult_BSWAP(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - GetExpandedOp(N->getOperand(0), Hi, Lo); // Note swapped operands. - Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo); - Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi); -} - -void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(1), LL, LH); - GetExpandedOp(N->getOperand(2), RL, RH); - Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL); - - assert(N->getOperand(0).getValueType() != MVT::f32 && - "FIXME: softfp shouldn't use expand!"); - Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH); -} - -void DAGTypeLegalizer::ExpandResult_SELECT_CC(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(2), LL, LH); - GetExpandedOp(N->getOperand(3), RL, RH); - Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), - N->getOperand(1), LL, RL, N->getOperand(4)); - - assert(N->getOperand(0).getValueType() != MVT::f32 && - "FIXME: softfp shouldn't use expand!"); - Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), - N->getOperand(1), LH, RH, N->getOperand(4)); -} - -void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Expand the subcomponents. - SDOperand LHSL, LHSH, RHSL, RHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - GetExpandedOp(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); - SDOperand LoOps[2] = { LHSL, RHSL }; - SDOperand HiOps[3] = { LHSH, RHSH }; - - if (N->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); - } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); - } -} - -void DAGTypeLegalizer::ExpandResult_ADDSUBC(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Expand the subcomponents. - SDOperand LHSL, LHSH, RHSL, RHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - GetExpandedOp(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); - SDOperand LoOps[2] = { LHSL, RHSL }; - SDOperand HiOps[3] = { LHSH, RHSH }; - - if (N->getOpcode() == ISD::ADDC) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); - } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); - } - - // Legalized the flag result - switch anything that used the old flag to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); -} - -void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Expand the subcomponents. - SDOperand LHSL, LHSH, RHSL, RHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - GetExpandedOp(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); - SDOperand LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; - SDOperand HiOps[3] = { LHSH, RHSH }; - - Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3); - - // Legalized the flag result - switch anything that used the old flag to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); -} - -void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - - bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT); - bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT); - bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT); - bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT); - if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(0), LL, LH); - GetExpandedOp(N->getOperand(1), RL, RH); - unsigned BitSize = MVT::getSizeInBits(NVT); - unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0)); - unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1)); - - // FIXME: generalize this to handle other bit sizes - if (LHSSB == 32 && RHSSB == 32 && - DAG.MaskedValueIsZero(N->getOperand(0), 0xFFFFFFFF00000000ULL) && - DAG.MaskedValueIsZero(N->getOperand(1), 0xFFFFFFFF00000000ULL)) { - // The inputs are both zero-extended. - if (HasUMUL_LOHI) { - // We can emit a umul_lohi. - Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); - Hi = SDOperand(Lo.Val, 1); - return; - } - if (HasMULHU) { - // We can emit a mulhu+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); - return; - } - } - if (LHSSB > BitSize && RHSSB > BitSize) { - // The input values are both sign-extended. - if (HasSMUL_LOHI) { - // We can emit a smul_lohi. - Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); - Hi = SDOperand(Lo.Val, 1); - return; - } - if (HasMULHS) { - // We can emit a mulhs+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); - return; - } - } - if (HasUMUL_LOHI) { - // Lo,Hi = umul LHS, RHS. - SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, - DAG.getVTList(NVT, NVT), LL, RL); - Lo = UMulLOHI; - Hi = UMulLOHI.getValue(1); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); - return; - } - } - - abort(); -#if 0 // FIXME! - // If nothing else, we can make a libcall. - Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), N, - false/*sign irrelevant*/, Hi); -#endif -} - - -void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType VT = N->getValueType(0); - - // If we can emit an efficient shift operation, do so now. Check to see if - // the RHS is a constant. - if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) - return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi); - - // If we can determine that the high bit of the shift is zero or one, even if - // the low bits are variable, emit this shift in an optimized form. - if (ExpandShiftWithKnownAmountBit(N, Lo, Hi)) - return; - - // If this target supports shift_PARTS, use it. First, map to the _PARTS opc. - unsigned PartsOpc; - if (N->getOpcode() == ISD::SHL) - PartsOpc = ISD::SHL_PARTS; - else if (N->getOpcode() == ISD::SRL) - PartsOpc = ISD::SRL_PARTS; - else { - assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); - PartsOpc = ISD::SRA_PARTS; - } - - // Next check to see if the target supports this SHL_PARTS operation or if it - // will custom expand it. - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT); - if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || - Action == TargetLowering::Custom) { - // Expand the subcomponents. - SDOperand LHSL, LHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - - SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) }; - MVT::ValueType VT = LHSL.getValueType(); - Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); - Hi = Lo.getValue(1); - return; - } - - abort(); -#if 0 // FIXME! - // Otherwise, emit a libcall. - unsigned RuntimeCode = ; // SRL -> SRL_I64 etc. - bool Signed = ; - Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SRL_I64), N, - false/*lshr is unsigned*/, Hi); -#endif -} - - -/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded, -/// and the shift amount is a constant 'Amt'. Expand the operation. -void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, - SDOperand &Lo, SDOperand &Hi) { - // Expand the incoming operand to be shifted, so that we have its parts - SDOperand InL, InH; - GetExpandedOp(N->getOperand(0), InL, InH); - - MVT::ValueType NVT = InL.getValueType(); - unsigned VTBits = MVT::getSizeInBits(N->getValueType(0)); - unsigned NVTBits = MVT::getSizeInBits(NVT); - MVT::ValueType ShTy = N->getOperand(1).getValueType(); - - if (N->getOpcode() == ISD::SHL) { - if (Amt > VTBits) { - Lo = Hi = DAG.getConstant(0, NVT); - } else if (Amt > NVTBits) { - Lo = DAG.getConstant(0, NVT); - Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); - } else if (Amt == NVTBits) { - Lo = DAG.getConstant(0, NVT); - Hi = InL; - } else { - Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy)); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SHL, NVT, InH, - DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SRL, NVT, InL, - DAG.getConstant(NVTBits-Amt, ShTy))); - } - return; - } - - if (N->getOpcode() == ISD::SRL) { - if (Amt > VTBits) { - Lo = DAG.getConstant(0, NVT); - Hi = DAG.getConstant(0, NVT); - } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); - Hi = DAG.getConstant(0, NVT); - } else if (Amt == NVTBits) { - Lo = InH; - Hi = DAG.getConstant(0, NVT); - } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, - DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, - DAG.getConstant(NVTBits-Amt, ShTy))); - Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy)); - } - return; - } - - assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); - if (Amt > VTBits) { - Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(NVTBits-1, ShTy)); - } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(Amt-NVTBits, ShTy)); - Hi = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(NVTBits-1, ShTy)); - } else if (Amt == NVTBits) { - Lo = InH; - Hi = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(NVTBits-1, ShTy)); - } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, - DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, - DAG.getConstant(NVTBits-Amt, ShTy))); - Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy)); - } -} - -/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify -/// this shift based on knowledge of the high bit of the shift amount. If we -/// can tell this, we know that it is >= 32 or < 32, without knowing the actual -/// shift amount. -bool DAGTypeLegalizer:: -ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - unsigned NVTBits = MVT::getSizeInBits(NVT); - assert(!(NVTBits & (NVTBits - 1)) && - "Expanded integer type size not a power of two!"); - - uint64_t HighBitMask = NVTBits, KnownZero, KnownOne; - DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne); - - // If we don't know anything about the high bit, exit. - if (((KnownZero|KnownOne) & HighBitMask) == 0) - return false; - - // Get the incoming operand to be shifted. - SDOperand InL, InH; - GetExpandedOp(N->getOperand(0), InL, InH); - SDOperand Amt = N->getOperand(1); - - // If we know that the high bit of the shift amount is one, then we can do - // this as a couple of simple shifts. - if (KnownOne & HighBitMask) { - // Mask out the high bit, which we know is set. - Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt, - DAG.getConstant(NVTBits-1, Amt.getValueType())); - - switch (N->getOpcode()) { - default: assert(0 && "Unknown shift"); - case ISD::SHL: - Lo = DAG.getConstant(0, NVT); // Low part is zero. - Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part. - return true; - case ISD::SRL: - Hi = DAG.getConstant(0, NVT); // Hi part is zero. - Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part. - return true; - case ISD::SRA: - Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part. - DAG.getConstant(NVTBits-1, Amt.getValueType())); - Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part. - return true; - } - } - - // If we know that the high bit of the shift amount is zero, then we can do - // this as a couple of simple shifts. - assert((KnownZero & HighBitMask) && "Bad mask computation above"); - - // Compute 32-amt. - SDOperand Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(), - DAG.getConstant(NVTBits, Amt.getValueType()), - Amt); - unsigned Op1, Op2; - switch (N->getOpcode()) { - default: assert(0 && "Unknown shift"); - case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break; - case ISD::SRL: - case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break; - } - - Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(Op1, NVT, InH, Amt), - DAG.getNode(Op2, NVT, InL, Amt2)); - return true; -} - -//===----------------------------------------------------------------------===// -// Result Vector Scalarization: <1 x ty> -> ty. -//===----------------------------------------------------------------------===// - - -void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { - DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); - cerr << "\n"); - SDOperand R = SDOperand(); - - // FIXME: Custom lowering for scalarization? -#if 0 - // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } -#endif - - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ScalarizeResult #" << ResNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to scalarize the result of this operator!"); - abort(); - - case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; - case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; - case ISD::ADD: - case ISD::FADD: - case ISD::SUB: - case ISD::FSUB: - case ISD::MUL: - case ISD::FMUL: - case ISD::SDIV: - case ISD::UDIV: - case ISD::FDIV: - case ISD::SREM: - case ISD::UREM: - case ISD::FREM: - case ISD::FPOW: - case ISD::AND: - case ISD::OR: - case ISD::XOR: R = ScalarizeRes_BinOp(N); break; - case ISD::FNEG: - case ISD::FABS: - case ISD::FSQRT: - case ISD::FSIN: - case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; - case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; - case ISD::BUILD_VECTOR: R = N->getOperand(0); break; - case ISD::INSERT_VECTOR_ELT: R = N->getOperand(1); break; - case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break; - case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break; - case ISD::SELECT: R = ScalarizeRes_SELECT(N); break; - } - - // If R is null, the sub-method took care of registering the resul. - if (R.Val) - SetScalarizedOp(SDOperand(N, ResNo), R); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(N->getValueType(0))); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { - SDOperand Result = DAG.getLoad(MVT::getVectorElementType(N->getValueType(0)), - N->getChain(), N->getBasePtr(), - N->getSrcValue(), N->getSrcValueOffset(), - N->isVolatile(), N->getAlignment()); - - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Result.getValue(1)); - return Result; -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) { - SDOperand LHS = GetScalarizedOp(N->getOperand(0)); - SDOperand RHS = GetScalarizedOp(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) { - SDOperand Op = GetScalarizedOp(N->getOperand(0)); - return DAG.getNode(N->getOpcode(), Op.getValueType(), Op); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) { - SDOperand Op = GetScalarizedOp(N->getOperand(0)); - return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) { - // Figure out if the scalar is the LHS or RHS and return it. - SDOperand EltNum = N->getOperand(2).getOperand(0); - unsigned Op = cast(EltNum)->getValue() != 0; - return GetScalarizedOp(N->getOperand(Op)); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) { - MVT::ValueType NewVT = MVT::getVectorElementType(N->getValueType(0)); - return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) { - SDOperand LHS = GetScalarizedOp(N->getOperand(1)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS, - GetScalarizedOp(N->getOperand(2))); -} - - -//===----------------------------------------------------------------------===// -// Operand Promotion -//===----------------------------------------------------------------------===// - -/// PromoteOperand - This method is called when the specified operand of the -/// specified node is found to need promotion. At this point, all of the result -/// types of the node are known to be legal, but other operands of the node may -/// need promotion or expansion as well as the specified one. -bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) { - DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res; - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "PromoteOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator's operand!"); - abort(); - - case ISD::ANY_EXTEND: Res = PromoteOperand_ANY_EXTEND(N); break; - case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break; - case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break; - case ISD::TRUNCATE: Res = PromoteOperand_TRUNCATE(N); break; - case ISD::FP_EXTEND: Res = PromoteOperand_FP_EXTEND(N); break; - case ISD::FP_ROUND: Res = PromoteOperand_FP_ROUND(N); break; - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: Res = PromoteOperand_INT_TO_FP(N); break; - - case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break; - case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break; - case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break; - case ISD::SETCC: Res = PromoteOperand_SETCC(N, OpNo); break; - - case ISD::STORE: Res = PromoteOperand_STORE(cast(N), - OpNo); break; - case ISD::MEMSET: - case ISD::MEMCPY: - case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; - } - - // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; - // If the result is N, the sub-method updated N in place. - if (Res.Val == N) { - // Mark N as new and remark N and its operands. This allows us to correctly - // revisit N if it needs another step of promotion and allows us to visit - // any new operands to N. - N->setNodeId(NewNode); - MarkNewNodes(N); - return true; - } - - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && - "Invalid operand expansion"); - - ReplaceValueWith(SDOperand(N, 0), Res); - return false; -} - -SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); - return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType()); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); - return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), - Op, DAG.getValueType(N->getOperand(0).getValueType())); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_TRUNCATE(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) { - SDOperand In = GetPromotedOp(N->getOperand(0)); - MVT::ValueType OpVT = N->getOperand(0).getValueType(); - if (N->getOpcode() == ISD::UINT_TO_FP) - In = DAG.getZeroExtendInReg(In, OpVT); - else - In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), - In, DAG.getValueType(OpVT)); - - return DAG.UpdateNodeOperands(SDOperand(N, 0), In); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) { - assert(OpNo == 0 && "Only know how to promote condition"); - SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition. - - // The top bits of the promoted condition are not necessarily zero, ensure - // that the value is properly zero extended. - if (!DAG.MaskedValueIsZero(Cond, - MVT::getIntVTBitMask(Cond.getValueType())^1)) { - Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); - MarkNewNodes(Cond.Val); - } - - // The chain (Op#0) and basic block destination (Op#2) are always legal types. - return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1), - N->getOperand(2)); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) { - assert(OpNo == 1 && "only know how to promote condition"); - SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition. - - // The top bits of the promoted condition are not necessarily zero, ensure - // that the value is properly zero extended. - if (!DAG.MaskedValueIsZero(Cond, - MVT::getIntVTBitMask(Cond.getValueType())^1)) { - Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); - MarkNewNodes(Cond.Val); - } - - // The chain (Op#0) and basic block destination (Op#2) are always legal types. - return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond, - N->getOperand(2)); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) { - assert(OpNo == 2 && "Don't know how to promote this operand"); - - SDOperand LHS = N->getOperand(2); - SDOperand RHS = N->getOperand(3); - PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(1))->get()); - - // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always - // legal types. - return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), - N->getOperand(1), LHS, RHS, N->getOperand(4)); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) { - assert(OpNo == 0 && "Don't know how to promote this operand"); - - SDOperand LHS = N->getOperand(0); - SDOperand RHS = N->getOperand(1); - PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(2))->get()); - - // The CC (#2) is always legal. - return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2)); -} - -/// PromoteSetCCOperands - Promote the operands of a comparison. This code is -/// shared among BR_CC, SELECT_CC, and SETCC handlers. -void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS, - ISD::CondCode CCCode) { - MVT::ValueType VT = NewLHS.getValueType(); - - // Get the promoted values. - NewLHS = GetPromotedOp(NewLHS); - NewRHS = GetPromotedOp(NewRHS); - - // If this is an FP compare, the operands have already been extended. - if (!MVT::isInteger(NewLHS.getValueType())) - return; - - // Otherwise, we have to insert explicit sign or zero extends. Note - // that we could insert sign extends for ALL conditions, but zero extend - // is cheaper on many machines (an AND instead of two shifts), so prefer - // it. - switch (CCCode) { - default: assert(0 && "Unknown integer comparison!"); - case ISD::SETEQ: - case ISD::SETNE: - case ISD::SETUGE: - case ISD::SETUGT: - case ISD::SETULE: - case ISD::SETULT: - // ALL of these operations will work if we either sign or zero extend - // the operands (including the unsigned comparisons!). Zero extend is - // usually a simpler/cheaper operation, so prefer it. - NewLHS = DAG.getZeroExtendInReg(NewLHS, VT); - NewRHS = DAG.getZeroExtendInReg(NewRHS, VT); - return; - case ISD::SETGE: - case ISD::SETGT: - case ISD::SETLT: - case ISD::SETLE: - NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS, - DAG.getValueType(VT)); - NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS, - DAG.getValueType(VT)); - return; - } -} - -SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){ - SDOperand Ch = N->getChain(), Ptr = N->getBasePtr(); - int SVOffset = N->getSrcValueOffset(); - unsigned Alignment = N->getAlignment(); - bool isVolatile = N->isVolatile(); - - SDOperand Val = GetPromotedOp(N->getValue()); // Get promoted value. - - assert(!N->isTruncatingStore() && "Cannot promote this store operand!"); - - // Truncate the value and store the result. - return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(), - SVOffset, N->getStoredVT(), - isVolatile, Alignment); -} - - -//===----------------------------------------------------------------------===// -// Operand Expansion -//===----------------------------------------------------------------------===// - -/// ExpandOperand - This method is called when the specified operand of the -/// specified node is found to need expansion. At this point, all of the result -/// types of the node are known to be legal, but other operands of the node may -/// need promotion or expansion as well as the specified one. -bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) { - DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res(0, 0); - - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); - - if (Res.Val == 0) { - switch (N->getOpcode()) { - default: - #ifndef NDEBUG - cerr << "ExpandOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; - #endif - assert(0 && "Do not know how to expand this operator's operand!"); - abort(); - - case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break; - case ISD::BIT_CONVERT: Res = ExpandOperand_BIT_CONVERT(N); break; - - case ISD::SINT_TO_FP: - Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0)); - break; - case ISD::UINT_TO_FP: - Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); - break; - case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break; - case ISD::SETCC: Res = ExpandOperand_SETCC(N); break; - - case ISD::STORE: - Res = ExpandOperand_STORE(cast(N), OpNo); - break; - case ISD::MEMSET: - case ISD::MEMCPY: - case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; - } - } - - // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; - // If the result is N, the sub-method updated N in place. Check to see if any - // operands are new, and if so, mark them. - if (Res.Val == N) { - // Mark N as new and remark N and its operands. This allows us to correctly - // revisit N if it needs another step of promotion and allows us to visit - // any new operands to N. - N->setNodeId(NewNode); - MarkNewNodes(N); - return true; - } - - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && - "Invalid operand expansion"); - - ReplaceValueWith(SDOperand(N, 0), Res); - return false; -} - -SDOperand DAGTypeLegalizer::ExpandOperand_TRUNCATE(SDNode *N) { - SDOperand InL, InH; - GetExpandedOp(N->getOperand(0), InL, InH); - // Just truncate the low part of the source. - return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) { - return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source, - MVT::ValueType DestTy) { - // We know the destination is legal, but that the input needs to be expanded. - assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); - - // Check to see if the target has a custom way to lower this. If so, use it. - switch (TLI.getOperationAction(ISD::SINT_TO_FP, Source.getValueType())) { - default: assert(0 && "This action not implemented for this operation!"); - case TargetLowering::Legal: - case TargetLowering::Expand: - break; // This case is handled below. - case TargetLowering::Custom: - SDOperand NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy, - Source), DAG); - if (NV.Val) return NV; - break; // The target lowered this. - } - - RTLIB::Libcall LC; - if (DestTy == MVT::f32) - LC = RTLIB::SINTTOFP_I64_F32; - else { - assert(DestTy == MVT::f64 && "Unknown fp value type!"); - LC = RTLIB::SINTTOFP_I64_F64; - } - - assert(0 && "FIXME: no libcalls yet!"); - abort(); -#if 0 - assert(TLI.getLibcallName(LC) && "Don't know how to expand this SINT_TO_FP!"); - Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source); - SDOperand UnusedHiPart; - return ExpandLibCall(TLI.getLibcallName(LC), Source.Val, true, UnusedHiPart); -#endif -} - -SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source, - MVT::ValueType DestTy) { - // We know the destination is legal, but that the input needs to be expanded. - assert(getTypeAction(Source.getValueType()) == Expand && - "This is not an expansion!"); - assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); - - // If this is unsigned, and not supported, first perform the conversion to - // signed, then adjust the result if the sign bit is set. - SDOperand SignedConv = ExpandOperand_SINT_TO_FP(Source, DestTy); - - // The 64-bit value loaded will be incorrectly if the 'sign bit' of the - // incoming integer is set. To handle this, we dynamically test to see if - // it is set, and, if so, add a fudge factor. - SDOperand Lo, Hi; - GetExpandedOp(Source, Lo, Hi); - - SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi, - DAG.getConstant(0, Hi.getValueType()), - ISD::SETLT); - SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); - SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), - SignSet, Four, Zero); - uint64_t FF = 0x5f800000ULL; - if (TLI.isLittleEndian()) FF <<= 32; - Constant *FudgeFactor = ConstantInt::get(Type::Int64Ty, FF); - - SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); - CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); - SDOperand FudgeInReg; - if (DestTy == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0); - else if (MVT::getSizeInBits(DestTy) > MVT::getSizeInBits(MVT::f32)) - // FIXME: Avoid the extend by construction the right constantpool? - FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(), - CPIdx, NULL, 0, MVT::f32); - else - assert(0 && "Unexpected conversion"); - - return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) { - SDOperand Lo, Hi; - GetExpandedOp(N->getOperand(0), Lo, Hi); - return cast(N->getOperand(1))->getValue() ? Hi : Lo; -} - -SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) { - SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); - ISD::CondCode CCCode = cast(N->getOperand(2))->get(); - ExpandSetCCOperands(NewLHS, NewRHS, CCCode); - - // If ExpandSetCCOperands returned a scalar, use it. - if (NewRHS.Val == 0) return NewLHS; - - // Otherwise, update N to have the operands specified. - return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS, - DAG.getCondCode(CCCode)); -} - -/// ExpandSetCCOperands - Expand the operands of a comparison. This code is -/// shared among BR_CC, SELECT_CC, and SETCC handlers. -void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, - ISD::CondCode &CCCode) { - SDOperand LHSLo, LHSHi, RHSLo, RHSHi; - GetExpandedOp(NewLHS, LHSLo, LHSHi); - GetExpandedOp(NewRHS, RHSLo, RHSHi); - - MVT::ValueType VT = NewLHS.getValueType(); - if (VT == MVT::f32 || VT == MVT::f64) { - assert(0 && "FIXME: softfp not implemented yet! should be promote not exp"); - } - - if (VT == MVT::ppcf128) { - // FIXME: This generated code sucks. We want to generate - // FCMP crN, hi1, hi2 - // BNE crN, L: - // FCMP crN, lo1, lo2 - // The following can be improved, but not that much. - SDOperand Tmp1, Tmp2, Tmp3; - Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, CCCode); - Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETNE); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, CCCode); - Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); - NewRHS = SDOperand(); // LHS is the result, not a compare. - return; - } - - - if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) { - if (RHSLo == RHSHi) - if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) - if (RHSCST->isAllOnesValue()) { - // Equality comparison to -1. - NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); - NewRHS = RHSLo; - return; - } - - NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); - NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); - NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS); - NewRHS = DAG.getConstant(0, NewLHS.getValueType()); - return; - } - - // If this is a comparison of the sign bit, just look at the top part. - // X > -1, x < 0 - if (ConstantSDNode *CST = dyn_cast(NewRHS)) - if ((CCCode == ISD::SETLT && CST->getValue() == 0) || // X < 0 - (CCCode == ISD::SETGT && CST->isAllOnesValue())) { // X > -1 - NewLHS = LHSHi; - NewRHS = RHSHi; - return; - } - - // FIXME: This generated code sucks. - ISD::CondCode LowCC; - switch (CCCode) { - default: assert(0 && "Unknown integer setcc!"); - case ISD::SETLT: - case ISD::SETULT: LowCC = ISD::SETULT; break; - case ISD::SETGT: - case ISD::SETUGT: LowCC = ISD::SETUGT; break; - case ISD::SETLE: - case ISD::SETULE: LowCC = ISD::SETULE; break; - case ISD::SETGE: - case ISD::SETUGE: LowCC = ISD::SETUGE; break; - } - - // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison - // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands - // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; - - // NOTE: on targets without efficient SELECT of bools, we can always use - // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) - TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL); - SDOperand Tmp1, Tmp2; - Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC, - false, DagCombineInfo); - if (!Tmp1.Val) - Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC); - Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, - CCCode, false, DagCombineInfo); - if (!Tmp2.Val) - Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, - DAG.getCondCode(CCCode)); - - ConstantSDNode *Tmp1C = dyn_cast(Tmp1.Val); - ConstantSDNode *Tmp2C = dyn_cast(Tmp2.Val); - if ((Tmp1C && Tmp1C->getValue() == 0) || - (Tmp2C && Tmp2C->getValue() == 0 && - (CCCode == ISD::SETLE || CCCode == ISD::SETGE || - CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) || - (Tmp2C && Tmp2C->getValue() == 1 && - (CCCode == ISD::SETLT || CCCode == ISD::SETGT || - CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) { - // low part is known false, returns high part. - // For LE / GE, if high part is known false, ignore the low part. - // For LT / GT, if high part is known true, ignore the low part. - NewLHS = Tmp2; - NewRHS = SDOperand(); - return; - } - - NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, - ISD::SETEQ, false, DagCombineInfo); - if (!NewLHS.Val) - NewLHS = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); - NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), - NewLHS, Tmp1, Tmp2); - NewRHS = SDOperand(); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) { - assert(OpNo == 1 && "Can only expand the stored value so far"); - - MVT::ValueType VT = N->getOperand(1).getValueType(); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Ch = N->getChain(); - SDOperand Ptr = N->getBasePtr(); - int SVOffset = N->getSrcValueOffset(); - unsigned Alignment = N->getAlignment(); - bool isVolatile = N->isVolatile(); - SDOperand Lo, Hi; - - assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); - - if (!N->isTruncatingStore()) { - unsigned IncrementSize = 0; - - // If this is a vector type, then we have to calculate the increment as - // the product of the element size in bytes, and the number of elements - // in the high half of the vector. - if (MVT::isVector(N->getValue().getValueType())) { - assert(0 && "Vectors not supported yet"); - #if 0 - SDNode *InVal = ST->getValue().Val; - unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); - MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); - - // Figure out if there is a simple type corresponding to this Vector - // type. If so, convert to the vector type. - MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems); - if (TLI.isTypeLegal(TVT)) { - // Turn this into a normal store of the vector type. - Tmp3 = LegalizeOp(Node->getOperand(1)); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - Result = LegalizeOp(Result); - break; - } else if (NumElems == 1) { - // Turn this into a normal store of the scalar type. - Tmp3 = ScalarizeVectorOp(Node->getOperand(1)); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - // The scalarized value type may not be legal, e.g. it might require - // promotion or expansion. Relegalize the scalar store. - return LegalizeOp(Result); - } else { - SplitVectorOp(Node->getOperand(1), Lo, Hi); - IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8; - } - #endif - } else { - GetExpandedOp(N->getValue(), Lo, Hi); - IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0; - - if (!TLI.isLittleEndian()) - std::swap(Lo, Hi); - } - - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), - SVOffset, isVolatile, Alignment); - - assert(Hi.Val && "FIXME: int <-> float should be handled with promote!"); - #if 0 - if (Hi.Val == NULL) { - // Must be int <-> float one-to-one expansion. - return Lo; - } - #endif - - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); - Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } else if (MVT::getSizeInBits(N->getStoredVT()) <= MVT::getSizeInBits(NVT)) { - GetExpandedOp(N->getValue(), Lo, Hi); - return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, - N->getStoredVT(), isVolatile, Alignment); - } else if (TLI.isLittleEndian()) { - // Little-endian - low bits are at low addresses. - GetExpandedOp(N->getValue(), Lo, Hi); - - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - - unsigned ExcessBits = - MVT::getSizeInBits(N->getStoredVT()) - MVT::getSizeInBits(NVT); - MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); - - // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, NEVT, - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } else { - // Big-endian - high bits are at low addresses. Favor aligned stores at - // the cost of some bit-fiddling. - GetExpandedOp(N->getValue(), Lo, Hi); - - MVT::ValueType EVT = N->getStoredVT(); - unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - unsigned ExcessBits = (EBytes - IncrementSize)*8; - MVT::ValueType HiVT = - MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits); - - if (ExcessBits < MVT::getSizeInBits(NVT)) { - // Transfer high bits from the top of Lo to the bottom of Hi. - Hi = DAG.getNode(ISD::SHL, NVT, Hi, - DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, - TLI.getShiftAmountTy())); - Hi = DAG.getNode(ISD::OR, NVT, Hi, - DAG.getNode(ISD::SRL, NVT, Lo, - DAG.getConstant(ExcessBits, - TLI.getShiftAmountTy()))); - } - - // Store both the high bits and maybe some of the low bits. - Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), - SVOffset, HiVT, isVolatile, Alignment); - - // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - // Store the lowest ExcessBits bits in the second half. - Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, - MVT::getIntegerType(ExcessBits), - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } -} - -//===----------------------------------------------------------------------===// -// Operand Vector Scalarization <1 x ty> -> ty. -//===----------------------------------------------------------------------===// - -bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { - DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG); - cerr << "\n"); - SDOperand Res(0, 0); - - // FIXME: Should we support custom lowering for scalarization? -#if 0 - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); -#endif - - if (Res.Val == 0) { - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ScalarizeOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to scalarize this operator's operand!"); - abort(); - - case ISD::EXTRACT_VECTOR_ELT: - Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N, OpNo); - break; - } - } - - // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; - - // If the result is N, the sub-method updated N in place. Check to see if any - // operands are new, and if so, mark them. - if (Res.Val == N) { - // Mark N as new and remark N and its operands. This allows us to correctly - // revisit N if it needs another step of promotion and allows us to visit - // any new operands to N. - N->setNodeId(NewNode); - MarkNewNodes(N); - return true; - } - - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && - "Invalid operand expansion"); - - ReplaceValueWith(SDOperand(N, 0), Res); - return false; -} - -/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be -/// scalarized, it must be <1 x ty>, just return the operand, ignoring the -/// index. -SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, - unsigned OpNo) { - return GetScalarizedOp(N->getOperand(0)); -} - - -//===----------------------------------------------------------------------===// -// Entry Point -//===----------------------------------------------------------------------===// - -/// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that -/// only uses types natively supported by the target. -/// -/// Note that this is an involved process that may invalidate pointers into -/// the graph. -void SelectionDAG::LegalizeTypes() { - DAGTypeLegalizer(*this).run(); -} Copied: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (from r44714, llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?p2=llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp&r1=44714&r2=44715&rev=44715&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sat Dec 8 14:17:13 2007 @@ -15,7 +15,6 @@ #include "LegalizeTypes.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" using namespace llvm; From sabre at nondot.org Sat Dec 8 14:24:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 20:24:38 -0000 Subject: [llvm-commits] [llvm] r44716 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypesPromote.cpp Message-ID: <200712082024.lB8KOcNC007974@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 14:24:38 2007 New Revision: 44716 URL: http://llvm.org/viewvc/llvm-project?rev=44716&view=rev Log: Split promotion support out to its own file. Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=44716&r1=44715&r2=44716&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sat Dec 8 14:24:38 2007 @@ -1,4 +1,4 @@ -//===-- LegalizeDAGTypes.cpp - Implement SelectionDAG::LegalizeTypes ------===// +//===-- LegalizeTypes.cpp - Common code for DAG type legalizer ------------===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// // // This file implements the SelectionDAG::LegalizeTypes method. It transforms -// an arbitrary well-formed SelectionDAG to only consist of legal types. +// an arbitrary well-formed SelectionDAG to only consist of legal types. This +// is common code shared among the LegalizeTypes*.cpp files. // //===----------------------------------------------------------------------===// @@ -406,252 +407,6 @@ //===----------------------------------------------------------------------===// -// Result Promotion -//===----------------------------------------------------------------------===// - -/// PromoteResult - This method is called when a result of a node is found to be -/// in need of promotion to a larger type. At this point, the node may also -/// have invalid operands or may have other results that need expansion, we just -/// know that (at least) one result needs promotion. -void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) { - DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n"); - SDOperand Result = SDOperand(); - - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "PromoteResult #" << ResNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator!"); - abort(); - case ISD::UNDEF: Result = PromoteResult_UNDEF(N); break; - case ISD::Constant: Result = PromoteResult_Constant(N); break; - - case ISD::TRUNCATE: Result = PromoteResult_TRUNCATE(N); break; - case ISD::SIGN_EXTEND: - case ISD::ZERO_EXTEND: - case ISD::ANY_EXTEND: Result = PromoteResult_INT_EXTEND(N); break; - case ISD::FP_ROUND: Result = PromoteResult_FP_ROUND(N); break; - case ISD::FP_TO_SINT: - case ISD::FP_TO_UINT: Result = PromoteResult_FP_TO_XINT(N); break; - case ISD::SETCC: Result = PromoteResult_SETCC(N); break; - case ISD::LOAD: Result = PromoteResult_LOAD(cast(N)); break; - - case ISD::AND: - case ISD::OR: - case ISD::XOR: - case ISD::ADD: - case ISD::SUB: - case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break; - - case ISD::SDIV: - case ISD::SREM: Result = PromoteResult_SDIV(N); break; - - case ISD::UDIV: - case ISD::UREM: Result = PromoteResult_UDIV(N); break; - - case ISD::SHL: Result = PromoteResult_SHL(N); break; - case ISD::SRA: Result = PromoteResult_SRA(N); break; - case ISD::SRL: Result = PromoteResult_SRL(N); break; - - case ISD::SELECT: Result = PromoteResult_SELECT(N); break; - case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break; - - } - - // If Result is null, the sub-method took care of registering the result. - if (Result.Val) - SetPromotedOp(SDOperand(N, ResNo), Result); -} - -SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0))); -} - -SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) { - MVT::ValueType VT = N->getValueType(0); - // Zero extend things like i1, sign extend everything else. It shouldn't - // matter in theory which one we pick, but this tends to give better code? - unsigned Opc = VT != MVT::i1 ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; - SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT), - SDOperand(N, 0)); - assert(isa(Result) && "Didn't constant fold ext?"); - return Result; -} - -SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) { - SDOperand Res; - - switch (getTypeAction(N->getOperand(0).getValueType())) { - default: assert(0 && "Unknown type action!"); - case Legal: - case Expand: - Res = N->getOperand(0); - break; - case Promote: - Res = GetPromotedOp(N->getOperand(0)); - break; - } - - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - assert(MVT::getSizeInBits(Res.getValueType()) >= MVT::getSizeInBits(NVT) && - "Truncation doesn't make sense!"); - if (Res.getValueType() == NVT) - return Res; - - // Truncate to NVT instead of VT - return DAG.getNode(ISD::TRUNCATE, NVT, Res); -} - -SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - - if (getTypeAction(N->getOperand(0).getValueType()) == Promote) { - SDOperand Res = GetPromotedOp(N->getOperand(0)); - assert(MVT::getSizeInBits(Res.getValueType()) <= MVT::getSizeInBits(NVT) && - "Extension doesn't make sense!"); - - // If the result and operand types are the same after promotion, simplify - // to an in-register extension. - if (NVT == Res.getValueType()) { - // The high bits are not guaranteed to be anything. Insert an extend. - if (N->getOpcode() == ISD::SIGN_EXTEND) - return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, - DAG.getValueType(N->getOperand(0).getValueType())); - if (N->getOpcode() == ISD::ZERO_EXTEND) - return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType()); - assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!"); - return Res; - } - } - - // Otherwise, just extend the original operand all the way to the larger type. - return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) { - // NOTE: Assumes input is legal. - return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(), - N->getOperand(0), DAG.getValueType(N->getValueType(0))); -} - -SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) { - SDOperand Op = N->getOperand(0); - // If the operand needed to be promoted, do so now. - if (getTypeAction(Op.getValueType()) == Promote) - // The input result is prerounded, so we don't have to do anything special. - Op = GetPromotedOp(Op); - - unsigned NewOpc = N->getOpcode(); - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - - // If we're promoting a UINT to a larger size, check to see if the new node - // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since - // we can use that instead. This allows us to generate better code for - // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not - // legal, such as PowerPC. - if (N->getOpcode() == ISD::FP_TO_UINT) { - if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && - (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || - TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)) - NewOpc = ISD::FP_TO_SINT; - } - - return DAG.getNode(NewOpc, NVT, Op); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) { - assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??"); - return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0), - N->getOperand(1), N->getOperand(2)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - ISD::LoadExtType ExtType = - ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); - SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(), - N->getSrcValue(), N->getSrcValueOffset(), - N->getLoadedVT(), N->isVolatile(), - N->getAlignment()); - - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Res.getValue(1)); - return Res; -} - -SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) { - // The input may have strange things in the top bits of the registers, but - // these operations don't care. They may have weird bits going out, but - // that too is okay if they are integer operations. - SDOperand LHS = GetPromotedOp(N->getOperand(0)); - SDOperand RHS = GetPromotedOp(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SDIV(SDNode *N) { - // Sign extend the input. - SDOperand LHS = GetPromotedOp(N->getOperand(0)); - SDOperand RHS = GetPromotedOp(N->getOperand(1)); - MVT::ValueType VT = N->getValueType(0); - LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS, - DAG.getValueType(VT)); - RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS, - DAG.getValueType(VT)); - - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_UDIV(SDNode *N) { - // Zero extend the input. - SDOperand LHS = GetPromotedOp(N->getOperand(0)); - SDOperand RHS = GetPromotedOp(N->getOperand(1)); - MVT::ValueType VT = N->getValueType(0); - LHS = DAG.getZeroExtendInReg(LHS, VT); - RHS = DAG.getZeroExtendInReg(RHS, VT); - - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SHL(SDNode *N) { - return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)), - GetPromotedOp(N->getOperand(0)), N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SRA(SDNode *N) { - // The input value must be properly sign extended. - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Res = GetPromotedOp(N->getOperand(0)); - Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT)); - return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SRL(SDNode *N) { - // The input value must be properly zero extended. - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Res = GetPromotedZExtOp(N->getOperand(0)); - return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) { - SDOperand LHS = GetPromotedOp(N->getOperand(1)); - SDOperand RHS = GetPromotedOp(N->getOperand(2)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); -} - -SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) { - SDOperand LHS = GetPromotedOp(N->getOperand(2)); - SDOperand RHS = GetPromotedOp(N->getOperand(3)); - return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), - N->getOperand(1), LHS, RHS, N->getOperand(4)); -} - - -//===----------------------------------------------------------------------===// // Result Expansion //===----------------------------------------------------------------------===// @@ -1488,230 +1243,6 @@ //===----------------------------------------------------------------------===// -// Operand Promotion -//===----------------------------------------------------------------------===// - -/// PromoteOperand - This method is called when the specified operand of the -/// specified node is found to need promotion. At this point, all of the result -/// types of the node are known to be legal, but other operands of the node may -/// need promotion or expansion as well as the specified one. -bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) { - DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res; - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "PromoteOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator's operand!"); - abort(); - - case ISD::ANY_EXTEND: Res = PromoteOperand_ANY_EXTEND(N); break; - case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break; - case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break; - case ISD::TRUNCATE: Res = PromoteOperand_TRUNCATE(N); break; - case ISD::FP_EXTEND: Res = PromoteOperand_FP_EXTEND(N); break; - case ISD::FP_ROUND: Res = PromoteOperand_FP_ROUND(N); break; - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: Res = PromoteOperand_INT_TO_FP(N); break; - - case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break; - case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break; - case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break; - case ISD::SETCC: Res = PromoteOperand_SETCC(N, OpNo); break; - - case ISD::STORE: Res = PromoteOperand_STORE(cast(N), - OpNo); break; - case ISD::MEMSET: - case ISD::MEMCPY: - case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; - } - - // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; - // If the result is N, the sub-method updated N in place. - if (Res.Val == N) { - // Mark N as new and remark N and its operands. This allows us to correctly - // revisit N if it needs another step of promotion and allows us to visit - // any new operands to N. - N->setNodeId(NewNode); - MarkNewNodes(N); - return true; - } - - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && - "Invalid operand expansion"); - - ReplaceValueWith(SDOperand(N, 0), Res); - return false; -} - -SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); - return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType()); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); - return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), - Op, DAG.getValueType(N->getOperand(0).getValueType())); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_TRUNCATE(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) { - SDOperand Op = GetPromotedOp(N->getOperand(0)); - return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) { - SDOperand In = GetPromotedOp(N->getOperand(0)); - MVT::ValueType OpVT = N->getOperand(0).getValueType(); - if (N->getOpcode() == ISD::UINT_TO_FP) - In = DAG.getZeroExtendInReg(In, OpVT); - else - In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), - In, DAG.getValueType(OpVT)); - - return DAG.UpdateNodeOperands(SDOperand(N, 0), In); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) { - assert(OpNo == 0 && "Only know how to promote condition"); - SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition. - - // The top bits of the promoted condition are not necessarily zero, ensure - // that the value is properly zero extended. - if (!DAG.MaskedValueIsZero(Cond, - MVT::getIntVTBitMask(Cond.getValueType())^1)) { - Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); - MarkNewNodes(Cond.Val); - } - - // The chain (Op#0) and basic block destination (Op#2) are always legal types. - return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1), - N->getOperand(2)); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) { - assert(OpNo == 1 && "only know how to promote condition"); - SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition. - - // The top bits of the promoted condition are not necessarily zero, ensure - // that the value is properly zero extended. - if (!DAG.MaskedValueIsZero(Cond, - MVT::getIntVTBitMask(Cond.getValueType())^1)) { - Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); - MarkNewNodes(Cond.Val); - } - - // The chain (Op#0) and basic block destination (Op#2) are always legal types. - return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond, - N->getOperand(2)); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) { - assert(OpNo == 2 && "Don't know how to promote this operand"); - - SDOperand LHS = N->getOperand(2); - SDOperand RHS = N->getOperand(3); - PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(1))->get()); - - // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always - // legal types. - return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), - N->getOperand(1), LHS, RHS, N->getOperand(4)); -} - -SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) { - assert(OpNo == 0 && "Don't know how to promote this operand"); - - SDOperand LHS = N->getOperand(0); - SDOperand RHS = N->getOperand(1); - PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(2))->get()); - - // The CC (#2) is always legal. - return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2)); -} - -/// PromoteSetCCOperands - Promote the operands of a comparison. This code is -/// shared among BR_CC, SELECT_CC, and SETCC handlers. -void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS, - ISD::CondCode CCCode) { - MVT::ValueType VT = NewLHS.getValueType(); - - // Get the promoted values. - NewLHS = GetPromotedOp(NewLHS); - NewRHS = GetPromotedOp(NewRHS); - - // If this is an FP compare, the operands have already been extended. - if (!MVT::isInteger(NewLHS.getValueType())) - return; - - // Otherwise, we have to insert explicit sign or zero extends. Note - // that we could insert sign extends for ALL conditions, but zero extend - // is cheaper on many machines (an AND instead of two shifts), so prefer - // it. - switch (CCCode) { - default: assert(0 && "Unknown integer comparison!"); - case ISD::SETEQ: - case ISD::SETNE: - case ISD::SETUGE: - case ISD::SETUGT: - case ISD::SETULE: - case ISD::SETULT: - // ALL of these operations will work if we either sign or zero extend - // the operands (including the unsigned comparisons!). Zero extend is - // usually a simpler/cheaper operation, so prefer it. - NewLHS = DAG.getZeroExtendInReg(NewLHS, VT); - NewRHS = DAG.getZeroExtendInReg(NewRHS, VT); - return; - case ISD::SETGE: - case ISD::SETGT: - case ISD::SETLT: - case ISD::SETLE: - NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS, - DAG.getValueType(VT)); - NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS, - DAG.getValueType(VT)); - return; - } -} - -SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){ - SDOperand Ch = N->getChain(), Ptr = N->getBasePtr(); - int SVOffset = N->getSrcValueOffset(); - unsigned Alignment = N->getAlignment(); - bool isVolatile = N->isVolatile(); - - SDOperand Val = GetPromotedOp(N->getValue()); // Get promoted value. - - assert(!N->isTruncatingStore() && "Cannot promote this store operand!"); - - // Truncate the value and store the result. - return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(), - SVOffset, N->getStoredVT(), - isVolatile, Alignment); -} - - -//===----------------------------------------------------------------------===// // Operand Expansion //===----------------------------------------------------------------------===// Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp?rev=44716&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp (added) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp Sat Dec 8 14:24:38 2007 @@ -0,0 +1,487 @@ +//===-- LegalizeTypesPromote.cpp - Promotion for LegalizeTypes ------------===// +// +// 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 promotion support for LegalizeTypes. Promotion is the +// act of changing a computation in an invalid type to be a computation in a +// larger type. For example, implementing i8 arithmetic in an i32 register (as +// is often needed on powerpc for example). +// +//===----------------------------------------------------------------------===// + +#include "LegalizeTypes.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Result Promotion +//===----------------------------------------------------------------------===// + +/// PromoteResult - This method is called when a result of a node is found to be +/// in need of promotion to a larger type. At this point, the node may also +/// have invalid operands or may have other results that need expansion, we just +/// know that (at least) one result needs promotion. +void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) { + DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n"); + SDOperand Result = SDOperand(); + + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "PromoteResult #" << ResNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to promote this operator!"); + abort(); + case ISD::UNDEF: Result = PromoteResult_UNDEF(N); break; + case ISD::Constant: Result = PromoteResult_Constant(N); break; + + case ISD::TRUNCATE: Result = PromoteResult_TRUNCATE(N); break; + case ISD::SIGN_EXTEND: + case ISD::ZERO_EXTEND: + case ISD::ANY_EXTEND: Result = PromoteResult_INT_EXTEND(N); break; + case ISD::FP_ROUND: Result = PromoteResult_FP_ROUND(N); break; + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: Result = PromoteResult_FP_TO_XINT(N); break; + case ISD::SETCC: Result = PromoteResult_SETCC(N); break; + case ISD::LOAD: Result = PromoteResult_LOAD(cast(N)); break; + + case ISD::AND: + case ISD::OR: + case ISD::XOR: + case ISD::ADD: + case ISD::SUB: + case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break; + + case ISD::SDIV: + case ISD::SREM: Result = PromoteResult_SDIV(N); break; + + case ISD::UDIV: + case ISD::UREM: Result = PromoteResult_UDIV(N); break; + + case ISD::SHL: Result = PromoteResult_SHL(N); break; + case ISD::SRA: Result = PromoteResult_SRA(N); break; + case ISD::SRL: Result = PromoteResult_SRL(N); break; + + case ISD::SELECT: Result = PromoteResult_SELECT(N); break; + case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break; + + } + + // If Result is null, the sub-method took care of registering the result. + if (Result.Val) + SetPromotedOp(SDOperand(N, ResNo), Result); +} + +SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) { + return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0))); +} + +SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + // Zero extend things like i1, sign extend everything else. It shouldn't + // matter in theory which one we pick, but this tends to give better code? + unsigned Opc = VT != MVT::i1 ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; + SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT), + SDOperand(N, 0)); + assert(isa(Result) && "Didn't constant fold ext?"); + return Result; +} + +SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) { + SDOperand Res; + + switch (getTypeAction(N->getOperand(0).getValueType())) { + default: assert(0 && "Unknown type action!"); + case Legal: + case Expand: + Res = N->getOperand(0); + break; + case Promote: + Res = GetPromotedOp(N->getOperand(0)); + break; + } + + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + assert(MVT::getSizeInBits(Res.getValueType()) >= MVT::getSizeInBits(NVT) && + "Truncation doesn't make sense!"); + if (Res.getValueType() == NVT) + return Res; + + // Truncate to NVT instead of VT + return DAG.getNode(ISD::TRUNCATE, NVT, Res); +} + +SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + + if (getTypeAction(N->getOperand(0).getValueType()) == Promote) { + SDOperand Res = GetPromotedOp(N->getOperand(0)); + assert(MVT::getSizeInBits(Res.getValueType()) <= MVT::getSizeInBits(NVT) && + "Extension doesn't make sense!"); + + // If the result and operand types are the same after promotion, simplify + // to an in-register extension. + if (NVT == Res.getValueType()) { + // The high bits are not guaranteed to be anything. Insert an extend. + if (N->getOpcode() == ISD::SIGN_EXTEND) + return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, + DAG.getValueType(N->getOperand(0).getValueType())); + if (N->getOpcode() == ISD::ZERO_EXTEND) + return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType()); + assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!"); + return Res; + } + } + + // Otherwise, just extend the original operand all the way to the larger type. + return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0)); +} + +SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) { + // NOTE: Assumes input is legal. + return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(), + N->getOperand(0), DAG.getValueType(N->getValueType(0))); +} + +SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) { + SDOperand Op = N->getOperand(0); + // If the operand needed to be promoted, do so now. + if (getTypeAction(Op.getValueType()) == Promote) + // The input result is prerounded, so we don't have to do anything special. + Op = GetPromotedOp(Op); + + unsigned NewOpc = N->getOpcode(); + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + + // If we're promoting a UINT to a larger size, check to see if the new node + // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since + // we can use that instead. This allows us to generate better code for + // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not + // legal, such as PowerPC. + if (N->getOpcode() == ISD::FP_TO_UINT) { + if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && + (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || + TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)) + NewOpc = ISD::FP_TO_SINT; + } + + return DAG.getNode(NewOpc, NVT, Op); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) { + assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??"); + return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0), + N->getOperand(1), N->getOperand(2)); +} + +SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + ISD::LoadExtType ExtType = + ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); + SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(), + N->getSrcValue(), N->getSrcValueOffset(), + N->getLoadedVT(), N->isVolatile(), + N->getAlignment()); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Res.getValue(1)); + return Res; +} + +SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) { + // The input may have strange things in the top bits of the registers, but + // these operations don't care. They may have weird bits going out, but + // that too is okay if they are integer operations. + SDOperand LHS = GetPromotedOp(N->getOperand(0)); + SDOperand RHS = GetPromotedOp(N->getOperand(1)); + return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SDIV(SDNode *N) { + // Sign extend the input. + SDOperand LHS = GetPromotedOp(N->getOperand(0)); + SDOperand RHS = GetPromotedOp(N->getOperand(1)); + MVT::ValueType VT = N->getValueType(0); + LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS, + DAG.getValueType(VT)); + RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS, + DAG.getValueType(VT)); + + return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); +} + +SDOperand DAGTypeLegalizer::PromoteResult_UDIV(SDNode *N) { + // Zero extend the input. + SDOperand LHS = GetPromotedOp(N->getOperand(0)); + SDOperand RHS = GetPromotedOp(N->getOperand(1)); + MVT::ValueType VT = N->getValueType(0); + LHS = DAG.getZeroExtendInReg(LHS, VT); + RHS = DAG.getZeroExtendInReg(RHS, VT); + + return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SHL(SDNode *N) { + return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)), + GetPromotedOp(N->getOperand(0)), N->getOperand(1)); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SRA(SDNode *N) { + // The input value must be properly sign extended. + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + SDOperand Res = GetPromotedOp(N->getOperand(0)); + Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT)); + return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1)); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SRL(SDNode *N) { + // The input value must be properly zero extended. + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + SDOperand Res = GetPromotedZExtOp(N->getOperand(0)); + return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1)); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) { + SDOperand LHS = GetPromotedOp(N->getOperand(1)); + SDOperand RHS = GetPromotedOp(N->getOperand(2)); + return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); +} + +SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) { + SDOperand LHS = GetPromotedOp(N->getOperand(2)); + SDOperand RHS = GetPromotedOp(N->getOperand(3)); + return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), + N->getOperand(1), LHS, RHS, N->getOperand(4)); +} + + +//===----------------------------------------------------------------------===// +// Operand Promotion +//===----------------------------------------------------------------------===// + +/// PromoteOperand - This method is called when the specified operand of the +/// specified node is found to need promotion. At this point, all of the result +/// types of the node are known to be legal, but other operands of the node may +/// need promotion or expansion as well as the specified one. +bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) { + DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n"); + SDOperand Res; + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "PromoteOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to promote this operator's operand!"); + abort(); + + case ISD::ANY_EXTEND: Res = PromoteOperand_ANY_EXTEND(N); break; + case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break; + case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break; + case ISD::TRUNCATE: Res = PromoteOperand_TRUNCATE(N); break; + case ISD::FP_EXTEND: Res = PromoteOperand_FP_EXTEND(N); break; + case ISD::FP_ROUND: Res = PromoteOperand_FP_ROUND(N); break; + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: Res = PromoteOperand_INT_TO_FP(N); break; + + case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break; + case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break; + case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break; + case ISD::SETCC: Res = PromoteOperand_SETCC(N, OpNo); break; + + case ISD::STORE: Res = PromoteOperand_STORE(cast(N), + OpNo); break; + case ISD::MEMSET: + case ISD::MEMCPY: + case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; + } + + // If the result is null, the sub-method took care of registering results etc. + if (!Res.Val) return false; + // If the result is N, the sub-method updated N in place. + if (Res.Val == N) { + // Mark N as new and remark N and its operands. This allows us to correctly + // revisit N if it needs another step of promotion and allows us to visit + // any new operands to N. + N->setNodeId(NewNode); + MarkNewNodes(N); + return true; + } + + assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + "Invalid operand expansion"); + + ReplaceValueWith(SDOperand(N, 0), Res); + return false; +} + +SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) { + SDOperand Op = GetPromotedOp(N->getOperand(0)); + return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) { + SDOperand Op = GetPromotedOp(N->getOperand(0)); + Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); + return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType()); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) { + SDOperand Op = GetPromotedOp(N->getOperand(0)); + Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), + Op, DAG.getValueType(N->getOperand(0).getValueType())); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_TRUNCATE(SDNode *N) { + SDOperand Op = GetPromotedOp(N->getOperand(0)); + return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) { + SDOperand Op = GetPromotedOp(N->getOperand(0)); + return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) { + SDOperand Op = GetPromotedOp(N->getOperand(0)); + return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) { + SDOperand In = GetPromotedOp(N->getOperand(0)); + MVT::ValueType OpVT = N->getOperand(0).getValueType(); + if (N->getOpcode() == ISD::UINT_TO_FP) + In = DAG.getZeroExtendInReg(In, OpVT); + else + In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), + In, DAG.getValueType(OpVT)); + + return DAG.UpdateNodeOperands(SDOperand(N, 0), In); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) { + assert(OpNo == 0 && "Only know how to promote condition"); + SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition. + + // The top bits of the promoted condition are not necessarily zero, ensure + // that the value is properly zero extended. + if (!DAG.MaskedValueIsZero(Cond, + MVT::getIntVTBitMask(Cond.getValueType())^1)) { + Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); + MarkNewNodes(Cond.Val); + } + + // The chain (Op#0) and basic block destination (Op#2) are always legal types. + return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1), + N->getOperand(2)); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) { + assert(OpNo == 1 && "only know how to promote condition"); + SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition. + + // The top bits of the promoted condition are not necessarily zero, ensure + // that the value is properly zero extended. + if (!DAG.MaskedValueIsZero(Cond, + MVT::getIntVTBitMask(Cond.getValueType())^1)) { + Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); + MarkNewNodes(Cond.Val); + } + + // The chain (Op#0) and basic block destination (Op#2) are always legal types. + return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond, + N->getOperand(2)); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) { + assert(OpNo == 2 && "Don't know how to promote this operand"); + + SDOperand LHS = N->getOperand(2); + SDOperand RHS = N->getOperand(3); + PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(1))->get()); + + // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always + // legal types. + return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), + N->getOperand(1), LHS, RHS, N->getOperand(4)); +} + +SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) { + assert(OpNo == 0 && "Don't know how to promote this operand"); + + SDOperand LHS = N->getOperand(0); + SDOperand RHS = N->getOperand(1); + PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(2))->get()); + + // The CC (#2) is always legal. + return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2)); +} + +/// PromoteSetCCOperands - Promote the operands of a comparison. This code is +/// shared among BR_CC, SELECT_CC, and SETCC handlers. +void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS, + ISD::CondCode CCCode) { + MVT::ValueType VT = NewLHS.getValueType(); + + // Get the promoted values. + NewLHS = GetPromotedOp(NewLHS); + NewRHS = GetPromotedOp(NewRHS); + + // If this is an FP compare, the operands have already been extended. + if (!MVT::isInteger(NewLHS.getValueType())) + return; + + // Otherwise, we have to insert explicit sign or zero extends. Note + // that we could insert sign extends for ALL conditions, but zero extend + // is cheaper on many machines (an AND instead of two shifts), so prefer + // it. + switch (CCCode) { + default: assert(0 && "Unknown integer comparison!"); + case ISD::SETEQ: + case ISD::SETNE: + case ISD::SETUGE: + case ISD::SETUGT: + case ISD::SETULE: + case ISD::SETULT: + // ALL of these operations will work if we either sign or zero extend + // the operands (including the unsigned comparisons!). Zero extend is + // usually a simpler/cheaper operation, so prefer it. + NewLHS = DAG.getZeroExtendInReg(NewLHS, VT); + NewRHS = DAG.getZeroExtendInReg(NewRHS, VT); + return; + case ISD::SETGE: + case ISD::SETGT: + case ISD::SETLT: + case ISD::SETLE: + NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS, + DAG.getValueType(VT)); + NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS, + DAG.getValueType(VT)); + return; + } +} + +SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){ + SDOperand Ch = N->getChain(), Ptr = N->getBasePtr(); + int SVOffset = N->getSrcValueOffset(); + unsigned Alignment = N->getAlignment(); + bool isVolatile = N->isVolatile(); + + SDOperand Val = GetPromotedOp(N->getValue()); // Get promoted value. + + assert(!N->isTruncatingStore() && "Cannot promote this store operand!"); + + // Truncate the value and store the result. + return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(), + SVOffset, N->getStoredVT(), + isVolatile, Alignment); +} From sabre at nondot.org Sat Dec 8 14:27:32 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 20:27:32 -0000 Subject: [llvm-commits] [llvm] r44717 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypesExpand.cpp Message-ID: <200712082027.lB8KRW25008267@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 14:27:32 2007 New Revision: 44717 URL: http://llvm.org/viewvc/llvm-project?rev=44717&view=rev Log: Split expansion out into its own file. Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=44717&r1=44716&r2=44717&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sat Dec 8 14:27:32 2007 @@ -407,721 +407,6 @@ //===----------------------------------------------------------------------===// -// Result Expansion -//===----------------------------------------------------------------------===// - -/// ExpandResult - This method is called when the specified result of the -/// specified node is found to need expansion. At this point, the node may also -/// have invalid operands or may have other results that need promotion, we just -/// know that (at least) one result needs expansion. -void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) { - DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); - SDOperand Lo, Hi; - Lo = Hi = SDOperand(); - - // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } - - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ExpandResult #" << ResNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to expand the result of this operator!"); - abort(); - - case ISD::UNDEF: ExpandResult_UNDEF(N, Lo, Hi); break; - case ISD::Constant: ExpandResult_Constant(N, Lo, Hi); break; - case ISD::BUILD_PAIR: ExpandResult_BUILD_PAIR(N, Lo, Hi); break; - case ISD::MERGE_VALUES: ExpandResult_MERGE_VALUES(N, Lo, Hi); break; - case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break; - case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break; - case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break; - case ISD::BIT_CONVERT: ExpandResult_BIT_CONVERT(N, Lo, Hi); break; - case ISD::SIGN_EXTEND_INREG: ExpandResult_SIGN_EXTEND_INREG(N, Lo, Hi); break; - case ISD::LOAD: ExpandResult_LOAD(cast(N), Lo, Hi); break; - - case ISD::AND: - case ISD::OR: - case ISD::XOR: ExpandResult_Logical(N, Lo, Hi); break; - case ISD::BSWAP: ExpandResult_BSWAP(N, Lo, Hi); break; - case ISD::ADD: - case ISD::SUB: ExpandResult_ADDSUB(N, Lo, Hi); break; - case ISD::ADDC: - case ISD::SUBC: ExpandResult_ADDSUBC(N, Lo, Hi); break; - case ISD::ADDE: - case ISD::SUBE: ExpandResult_ADDSUBE(N, Lo, Hi); break; - case ISD::SELECT: ExpandResult_SELECT(N, Lo, Hi); break; - case ISD::SELECT_CC: ExpandResult_SELECT_CC(N, Lo, Hi); break; - case ISD::MUL: ExpandResult_MUL(N, Lo, Hi); break; - case ISD::SHL: - case ISD::SRA: - case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break; - } - - // If Lo/Hi is null, the sub-method took care of registering results etc. - if (Lo.Val) - SetExpandedOp(SDOperand(N, ResNo), Lo, Hi); -} - -void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - Lo = Hi = DAG.getNode(ISD::UNDEF, NVT); -} - -void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - uint64_t Cst = cast(N)->getValue(); - Lo = DAG.getConstant(Cst, NVT); - Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT); -} - -void DAGTypeLegalizer::ExpandResult_BUILD_PAIR(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Return the operands. - Lo = N->getOperand(0); - Hi = N->getOperand(1); -} - -void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // A MERGE_VALUES node can produce any number of values. We know that the - // first illegal one needs to be expanded into Lo/Hi. - unsigned i; - - // The string of legal results gets turns into the input operands, which have - // the same type. - for (i = 0; isTypeLegal(N->getValueType(i)); ++i) - ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); - - // The first illegal result must be the one that needs to be expanded. - GetExpandedOp(N->getOperand(i), Lo, Hi); - - // Legalize the rest of the results into the input operands whether they are - // legal or not. - unsigned e = N->getNumValues(); - for (++i; i != e; ++i) - ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); -} - -void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Op = N->getOperand(0); - if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { - // The low part is any extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op); - Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined. - } else { - // For example, extension of an i48 to an i64. The operand type necessarily - // promotes to the result type, so will end up being expanded too. - assert(getTypeAction(Op.getValueType()) == Promote && - "Don't know how to expand this result!"); - SDOperand Res = GetPromotedOp(Op); - assert(Res.getValueType() == N->getValueType(0) && - "Operand over promoted?"); - // Split the promoted operand. This will simplify when it is expanded. - SplitOp(Res, Lo, Hi); - } -} - -void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Op = N->getOperand(0); - if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { - // The low part is zero extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); - Hi = DAG.getConstant(0, NVT); // The high part is just a zero. - } else { - // For example, extension of an i48 to an i64. The operand type necessarily - // promotes to the result type, so will end up being expanded too. - assert(getTypeAction(Op.getValueType()) == Promote && - "Don't know how to expand this result!"); - SDOperand Res = GetPromotedOp(Op); - assert(Res.getValueType() == N->getValueType(0) && - "Operand over promoted?"); - // Split the promoted operand. This will simplify when it is expanded. - SplitOp(Res, Lo, Hi); - unsigned ExcessBits = - MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); - Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits)); - } -} - -void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Op = N->getOperand(0); - if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { - // The low part is sign extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); - // The high part is obtained by SRA'ing all but one of the bits of low part. - unsigned LoSize = MVT::getSizeInBits(NVT); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); - } else { - // For example, extension of an i48 to an i64. The operand type necessarily - // promotes to the result type, so will end up being expanded too. - assert(getTypeAction(Op.getValueType()) == Promote && - "Don't know how to expand this result!"); - SDOperand Res = GetPromotedOp(Op); - assert(Res.getValueType() == N->getValueType(0) && - "Operand over promoted?"); - // Split the promoted operand. This will simplify when it is expanded. - SplitOp(Res, Lo, Hi); - unsigned ExcessBits = - MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); - Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, - DAG.getValueType(MVT::getIntegerType(ExcessBits))); - } -} - -void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Lower the bit-convert to a store/load from the stack, then expand the load. - SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); - ExpandResult_LOAD(cast(Op.Val), Lo, Hi); -} - -void DAGTypeLegalizer:: -ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - GetExpandedOp(N->getOperand(0), Lo, Hi); - MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); - - if (MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(Lo.getValueType())) { - // sext_inreg the low part if needed. - Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo, - N->getOperand(1)); - - // The high part gets the sign extension from the lo-part. This handles - // things like sextinreg V:i64 from i8. - Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo, - DAG.getConstant(MVT::getSizeInBits(Hi.getValueType())-1, - TLI.getShiftAmountTy())); - } else { - // For example, extension of an i48 to an i64. Leave the low part alone, - // sext_inreg the high part. - unsigned ExcessBits = - MVT::getSizeInBits(EVT) - MVT::getSizeInBits(Lo.getValueType()); - Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, - DAG.getValueType(MVT::getIntegerType(ExcessBits))); - } -} - -void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Ch = N->getChain(); // Legalize the chain. - SDOperand Ptr = N->getBasePtr(); // Legalize the pointer. - ISD::LoadExtType ExtType = N->getExtensionType(); - int SVOffset = N->getSrcValueOffset(); - unsigned Alignment = N->getAlignment(); - bool isVolatile = N->isVolatile(); - - assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); - - if (ExtType == ISD::NON_EXTLOAD) { - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - - // Handle endianness of the load. - if (!TLI.isLittleEndian()) - std::swap(Lo, Hi); - } else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) { - MVT::ValueType EVT = N->getLoadedVT(); - - Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT, - isVolatile, Alignment); - - // Remember the chain. - Ch = Lo.getValue(1); - - if (ExtType == ISD::SEXTLOAD) { - // The high part is obtained by SRA'ing all but one of the bits of the - // lo part. - unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); - } else if (ExtType == ISD::ZEXTLOAD) { - // The high part is just a zero. - Hi = DAG.getConstant(0, NVT); - } else { - assert(ExtType == ISD::EXTLOAD && "Unknown extload!"); - // The high part is undefined. - Hi = DAG.getNode(ISD::UNDEF, NVT); - } - } else if (TLI.isLittleEndian()) { - // Little-endian - low bits are at low addresses. - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - - unsigned ExcessBits = - MVT::getSizeInBits(N->getLoadedVT()) - MVT::getSizeInBits(NVT); - MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); - - // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, NEVT, - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - } else { - // Big-endian - high bits are at low addresses. Favor aligned loads at - // the cost of some bit-fiddling. - MVT::ValueType EVT = N->getLoadedVT(); - unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - unsigned ExcessBits = (EBytes - IncrementSize)*8; - - // Load both the high bits and maybe some of the low bits. - Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits), - isVolatile, Alignment); - - // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - // Load the rest of the low bits. - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits), - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - - if (ExcessBits < MVT::getSizeInBits(NVT)) { - // Transfer low bits from the bottom of Hi to the top of Lo. - Lo = DAG.getNode(ISD::OR, NVT, Lo, - DAG.getNode(ISD::SHL, NVT, Hi, - DAG.getConstant(ExcessBits, - TLI.getShiftAmountTy()))); - // Move high bits to the right position in Hi. - Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi, - DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, - TLI.getShiftAmountTy())); - } - } - - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Ch); -} - -void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(0), LL, LH); - GetExpandedOp(N->getOperand(1), RL, RH); - Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL); - Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH); -} - -void DAGTypeLegalizer::ExpandResult_BSWAP(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - GetExpandedOp(N->getOperand(0), Hi, Lo); // Note swapped operands. - Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo); - Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi); -} - -void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(1), LL, LH); - GetExpandedOp(N->getOperand(2), RL, RH); - Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL); - - assert(N->getOperand(0).getValueType() != MVT::f32 && - "FIXME: softfp shouldn't use expand!"); - Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH); -} - -void DAGTypeLegalizer::ExpandResult_SELECT_CC(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(2), LL, LH); - GetExpandedOp(N->getOperand(3), RL, RH); - Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), - N->getOperand(1), LL, RL, N->getOperand(4)); - - assert(N->getOperand(0).getValueType() != MVT::f32 && - "FIXME: softfp shouldn't use expand!"); - Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), - N->getOperand(1), LH, RH, N->getOperand(4)); -} - -void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Expand the subcomponents. - SDOperand LHSL, LHSH, RHSL, RHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - GetExpandedOp(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); - SDOperand LoOps[2] = { LHSL, RHSL }; - SDOperand HiOps[3] = { LHSH, RHSH }; - - if (N->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); - } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); - } -} - -void DAGTypeLegalizer::ExpandResult_ADDSUBC(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Expand the subcomponents. - SDOperand LHSL, LHSH, RHSL, RHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - GetExpandedOp(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); - SDOperand LoOps[2] = { LHSL, RHSL }; - SDOperand HiOps[3] = { LHSH, RHSH }; - - if (N->getOpcode() == ISD::ADDC) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); - } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); - } - - // Legalized the flag result - switch anything that used the old flag to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); -} - -void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Expand the subcomponents. - SDOperand LHSL, LHSH, RHSL, RHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - GetExpandedOp(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); - SDOperand LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; - SDOperand HiOps[3] = { LHSH, RHSH }; - - Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3); - - // Legalized the flag result - switch anything that used the old flag to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); -} - -void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType VT = N->getValueType(0); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - - bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT); - bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT); - bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT); - bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT); - if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { - SDOperand LL, LH, RL, RH; - GetExpandedOp(N->getOperand(0), LL, LH); - GetExpandedOp(N->getOperand(1), RL, RH); - unsigned BitSize = MVT::getSizeInBits(NVT); - unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0)); - unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1)); - - // FIXME: generalize this to handle other bit sizes - if (LHSSB == 32 && RHSSB == 32 && - DAG.MaskedValueIsZero(N->getOperand(0), 0xFFFFFFFF00000000ULL) && - DAG.MaskedValueIsZero(N->getOperand(1), 0xFFFFFFFF00000000ULL)) { - // The inputs are both zero-extended. - if (HasUMUL_LOHI) { - // We can emit a umul_lohi. - Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); - Hi = SDOperand(Lo.Val, 1); - return; - } - if (HasMULHU) { - // We can emit a mulhu+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); - return; - } - } - if (LHSSB > BitSize && RHSSB > BitSize) { - // The input values are both sign-extended. - if (HasSMUL_LOHI) { - // We can emit a smul_lohi. - Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); - Hi = SDOperand(Lo.Val, 1); - return; - } - if (HasMULHS) { - // We can emit a mulhs+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); - return; - } - } - if (HasUMUL_LOHI) { - // Lo,Hi = umul LHS, RHS. - SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, - DAG.getVTList(NVT, NVT), LL, RL); - Lo = UMulLOHI; - Hi = UMulLOHI.getValue(1); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); - return; - } - } - - abort(); -#if 0 // FIXME! - // If nothing else, we can make a libcall. - Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), N, - false/*sign irrelevant*/, Hi); -#endif -} - - -void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType VT = N->getValueType(0); - - // If we can emit an efficient shift operation, do so now. Check to see if - // the RHS is a constant. - if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) - return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi); - - // If we can determine that the high bit of the shift is zero or one, even if - // the low bits are variable, emit this shift in an optimized form. - if (ExpandShiftWithKnownAmountBit(N, Lo, Hi)) - return; - - // If this target supports shift_PARTS, use it. First, map to the _PARTS opc. - unsigned PartsOpc; - if (N->getOpcode() == ISD::SHL) - PartsOpc = ISD::SHL_PARTS; - else if (N->getOpcode() == ISD::SRL) - PartsOpc = ISD::SRL_PARTS; - else { - assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); - PartsOpc = ISD::SRA_PARTS; - } - - // Next check to see if the target supports this SHL_PARTS operation or if it - // will custom expand it. - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT); - if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || - Action == TargetLowering::Custom) { - // Expand the subcomponents. - SDOperand LHSL, LHSH; - GetExpandedOp(N->getOperand(0), LHSL, LHSH); - - SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) }; - MVT::ValueType VT = LHSL.getValueType(); - Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); - Hi = Lo.getValue(1); - return; - } - - abort(); -#if 0 // FIXME! - // Otherwise, emit a libcall. - unsigned RuntimeCode = ; // SRL -> SRL_I64 etc. - bool Signed = ; - Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SRL_I64), N, - false/*lshr is unsigned*/, Hi); -#endif -} - - -/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded, -/// and the shift amount is a constant 'Amt'. Expand the operation. -void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, - SDOperand &Lo, SDOperand &Hi) { - // Expand the incoming operand to be shifted, so that we have its parts - SDOperand InL, InH; - GetExpandedOp(N->getOperand(0), InL, InH); - - MVT::ValueType NVT = InL.getValueType(); - unsigned VTBits = MVT::getSizeInBits(N->getValueType(0)); - unsigned NVTBits = MVT::getSizeInBits(NVT); - MVT::ValueType ShTy = N->getOperand(1).getValueType(); - - if (N->getOpcode() == ISD::SHL) { - if (Amt > VTBits) { - Lo = Hi = DAG.getConstant(0, NVT); - } else if (Amt > NVTBits) { - Lo = DAG.getConstant(0, NVT); - Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); - } else if (Amt == NVTBits) { - Lo = DAG.getConstant(0, NVT); - Hi = InL; - } else { - Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy)); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SHL, NVT, InH, - DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SRL, NVT, InL, - DAG.getConstant(NVTBits-Amt, ShTy))); - } - return; - } - - if (N->getOpcode() == ISD::SRL) { - if (Amt > VTBits) { - Lo = DAG.getConstant(0, NVT); - Hi = DAG.getConstant(0, NVT); - } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); - Hi = DAG.getConstant(0, NVT); - } else if (Amt == NVTBits) { - Lo = InH; - Hi = DAG.getConstant(0, NVT); - } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, - DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, - DAG.getConstant(NVTBits-Amt, ShTy))); - Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy)); - } - return; - } - - assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); - if (Amt > VTBits) { - Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(NVTBits-1, ShTy)); - } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(Amt-NVTBits, ShTy)); - Hi = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(NVTBits-1, ShTy)); - } else if (Amt == NVTBits) { - Lo = InH; - Hi = DAG.getNode(ISD::SRA, NVT, InH, - DAG.getConstant(NVTBits-1, ShTy)); - } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, - DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, - DAG.getConstant(NVTBits-Amt, ShTy))); - Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy)); - } -} - -/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify -/// this shift based on knowledge of the high bit of the shift amount. If we -/// can tell this, we know that it is >= 32 or < 32, without knowing the actual -/// shift amount. -bool DAGTypeLegalizer:: -ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - unsigned NVTBits = MVT::getSizeInBits(NVT); - assert(!(NVTBits & (NVTBits - 1)) && - "Expanded integer type size not a power of two!"); - - uint64_t HighBitMask = NVTBits, KnownZero, KnownOne; - DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne); - - // If we don't know anything about the high bit, exit. - if (((KnownZero|KnownOne) & HighBitMask) == 0) - return false; - - // Get the incoming operand to be shifted. - SDOperand InL, InH; - GetExpandedOp(N->getOperand(0), InL, InH); - SDOperand Amt = N->getOperand(1); - - // If we know that the high bit of the shift amount is one, then we can do - // this as a couple of simple shifts. - if (KnownOne & HighBitMask) { - // Mask out the high bit, which we know is set. - Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt, - DAG.getConstant(NVTBits-1, Amt.getValueType())); - - switch (N->getOpcode()) { - default: assert(0 && "Unknown shift"); - case ISD::SHL: - Lo = DAG.getConstant(0, NVT); // Low part is zero. - Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part. - return true; - case ISD::SRL: - Hi = DAG.getConstant(0, NVT); // Hi part is zero. - Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part. - return true; - case ISD::SRA: - Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part. - DAG.getConstant(NVTBits-1, Amt.getValueType())); - Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part. - return true; - } - } - - // If we know that the high bit of the shift amount is zero, then we can do - // this as a couple of simple shifts. - assert((KnownZero & HighBitMask) && "Bad mask computation above"); - - // Compute 32-amt. - SDOperand Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(), - DAG.getConstant(NVTBits, Amt.getValueType()), - Amt); - unsigned Op1, Op2; - switch (N->getOpcode()) { - default: assert(0 && "Unknown shift"); - case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break; - case ISD::SRL: - case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break; - } - - Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(Op1, NVT, InH, Amt), - DAG.getNode(Op2, NVT, InL, Amt2)); - return true; -} - -//===----------------------------------------------------------------------===// // Result Vector Scalarization: <1 x ty> -> ty. //===----------------------------------------------------------------------===// @@ -1243,435 +528,6 @@ //===----------------------------------------------------------------------===// -// Operand Expansion -//===----------------------------------------------------------------------===// - -/// ExpandOperand - This method is called when the specified operand of the -/// specified node is found to need expansion. At this point, all of the result -/// types of the node are known to be legal, but other operands of the node may -/// need promotion or expansion as well as the specified one. -bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) { - DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res(0, 0); - - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); - - if (Res.Val == 0) { - switch (N->getOpcode()) { - default: - #ifndef NDEBUG - cerr << "ExpandOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; - #endif - assert(0 && "Do not know how to expand this operator's operand!"); - abort(); - - case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break; - case ISD::BIT_CONVERT: Res = ExpandOperand_BIT_CONVERT(N); break; - - case ISD::SINT_TO_FP: - Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0)); - break; - case ISD::UINT_TO_FP: - Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); - break; - case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break; - case ISD::SETCC: Res = ExpandOperand_SETCC(N); break; - - case ISD::STORE: - Res = ExpandOperand_STORE(cast(N), OpNo); - break; - case ISD::MEMSET: - case ISD::MEMCPY: - case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; - } - } - - // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; - // If the result is N, the sub-method updated N in place. Check to see if any - // operands are new, and if so, mark them. - if (Res.Val == N) { - // Mark N as new and remark N and its operands. This allows us to correctly - // revisit N if it needs another step of promotion and allows us to visit - // any new operands to N. - N->setNodeId(NewNode); - MarkNewNodes(N); - return true; - } - - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && - "Invalid operand expansion"); - - ReplaceValueWith(SDOperand(N, 0), Res); - return false; -} - -SDOperand DAGTypeLegalizer::ExpandOperand_TRUNCATE(SDNode *N) { - SDOperand InL, InH; - GetExpandedOp(N->getOperand(0), InL, InH); - // Just truncate the low part of the source. - return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) { - return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source, - MVT::ValueType DestTy) { - // We know the destination is legal, but that the input needs to be expanded. - assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); - - // Check to see if the target has a custom way to lower this. If so, use it. - switch (TLI.getOperationAction(ISD::SINT_TO_FP, Source.getValueType())) { - default: assert(0 && "This action not implemented for this operation!"); - case TargetLowering::Legal: - case TargetLowering::Expand: - break; // This case is handled below. - case TargetLowering::Custom: - SDOperand NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy, - Source), DAG); - if (NV.Val) return NV; - break; // The target lowered this. - } - - RTLIB::Libcall LC; - if (DestTy == MVT::f32) - LC = RTLIB::SINTTOFP_I64_F32; - else { - assert(DestTy == MVT::f64 && "Unknown fp value type!"); - LC = RTLIB::SINTTOFP_I64_F64; - } - - assert(0 && "FIXME: no libcalls yet!"); - abort(); -#if 0 - assert(TLI.getLibcallName(LC) && "Don't know how to expand this SINT_TO_FP!"); - Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source); - SDOperand UnusedHiPart; - return ExpandLibCall(TLI.getLibcallName(LC), Source.Val, true, UnusedHiPart); -#endif -} - -SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source, - MVT::ValueType DestTy) { - // We know the destination is legal, but that the input needs to be expanded. - assert(getTypeAction(Source.getValueType()) == Expand && - "This is not an expansion!"); - assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); - - // If this is unsigned, and not supported, first perform the conversion to - // signed, then adjust the result if the sign bit is set. - SDOperand SignedConv = ExpandOperand_SINT_TO_FP(Source, DestTy); - - // The 64-bit value loaded will be incorrectly if the 'sign bit' of the - // incoming integer is set. To handle this, we dynamically test to see if - // it is set, and, if so, add a fudge factor. - SDOperand Lo, Hi; - GetExpandedOp(Source, Lo, Hi); - - SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi, - DAG.getConstant(0, Hi.getValueType()), - ISD::SETLT); - SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); - SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), - SignSet, Four, Zero); - uint64_t FF = 0x5f800000ULL; - if (TLI.isLittleEndian()) FF <<= 32; - Constant *FudgeFactor = ConstantInt::get(Type::Int64Ty, FF); - - SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); - CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); - SDOperand FudgeInReg; - if (DestTy == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0); - else if (MVT::getSizeInBits(DestTy) > MVT::getSizeInBits(MVT::f32)) - // FIXME: Avoid the extend by construction the right constantpool? - FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(), - CPIdx, NULL, 0, MVT::f32); - else - assert(0 && "Unexpected conversion"); - - return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) { - SDOperand Lo, Hi; - GetExpandedOp(N->getOperand(0), Lo, Hi); - return cast(N->getOperand(1))->getValue() ? Hi : Lo; -} - -SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) { - SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); - ISD::CondCode CCCode = cast(N->getOperand(2))->get(); - ExpandSetCCOperands(NewLHS, NewRHS, CCCode); - - // If ExpandSetCCOperands returned a scalar, use it. - if (NewRHS.Val == 0) return NewLHS; - - // Otherwise, update N to have the operands specified. - return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS, - DAG.getCondCode(CCCode)); -} - -/// ExpandSetCCOperands - Expand the operands of a comparison. This code is -/// shared among BR_CC, SELECT_CC, and SETCC handlers. -void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, - ISD::CondCode &CCCode) { - SDOperand LHSLo, LHSHi, RHSLo, RHSHi; - GetExpandedOp(NewLHS, LHSLo, LHSHi); - GetExpandedOp(NewRHS, RHSLo, RHSHi); - - MVT::ValueType VT = NewLHS.getValueType(); - if (VT == MVT::f32 || VT == MVT::f64) { - assert(0 && "FIXME: softfp not implemented yet! should be promote not exp"); - } - - if (VT == MVT::ppcf128) { - // FIXME: This generated code sucks. We want to generate - // FCMP crN, hi1, hi2 - // BNE crN, L: - // FCMP crN, lo1, lo2 - // The following can be improved, but not that much. - SDOperand Tmp1, Tmp2, Tmp3; - Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, CCCode); - Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETNE); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, CCCode); - Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); - NewRHS = SDOperand(); // LHS is the result, not a compare. - return; - } - - - if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) { - if (RHSLo == RHSHi) - if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) - if (RHSCST->isAllOnesValue()) { - // Equality comparison to -1. - NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); - NewRHS = RHSLo; - return; - } - - NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); - NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); - NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS); - NewRHS = DAG.getConstant(0, NewLHS.getValueType()); - return; - } - - // If this is a comparison of the sign bit, just look at the top part. - // X > -1, x < 0 - if (ConstantSDNode *CST = dyn_cast(NewRHS)) - if ((CCCode == ISD::SETLT && CST->getValue() == 0) || // X < 0 - (CCCode == ISD::SETGT && CST->isAllOnesValue())) { // X > -1 - NewLHS = LHSHi; - NewRHS = RHSHi; - return; - } - - // FIXME: This generated code sucks. - ISD::CondCode LowCC; - switch (CCCode) { - default: assert(0 && "Unknown integer setcc!"); - case ISD::SETLT: - case ISD::SETULT: LowCC = ISD::SETULT; break; - case ISD::SETGT: - case ISD::SETUGT: LowCC = ISD::SETUGT; break; - case ISD::SETLE: - case ISD::SETULE: LowCC = ISD::SETULE; break; - case ISD::SETGE: - case ISD::SETUGE: LowCC = ISD::SETUGE; break; - } - - // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison - // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands - // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; - - // NOTE: on targets without efficient SELECT of bools, we can always use - // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) - TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL); - SDOperand Tmp1, Tmp2; - Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC, - false, DagCombineInfo); - if (!Tmp1.Val) - Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC); - Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, - CCCode, false, DagCombineInfo); - if (!Tmp2.Val) - Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, - DAG.getCondCode(CCCode)); - - ConstantSDNode *Tmp1C = dyn_cast(Tmp1.Val); - ConstantSDNode *Tmp2C = dyn_cast(Tmp2.Val); - if ((Tmp1C && Tmp1C->getValue() == 0) || - (Tmp2C && Tmp2C->getValue() == 0 && - (CCCode == ISD::SETLE || CCCode == ISD::SETGE || - CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) || - (Tmp2C && Tmp2C->getValue() == 1 && - (CCCode == ISD::SETLT || CCCode == ISD::SETGT || - CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) { - // low part is known false, returns high part. - // For LE / GE, if high part is known false, ignore the low part. - // For LT / GT, if high part is known true, ignore the low part. - NewLHS = Tmp2; - NewRHS = SDOperand(); - return; - } - - NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, - ISD::SETEQ, false, DagCombineInfo); - if (!NewLHS.Val) - NewLHS = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); - NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), - NewLHS, Tmp1, Tmp2); - NewRHS = SDOperand(); -} - -SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) { - assert(OpNo == 1 && "Can only expand the stored value so far"); - - MVT::ValueType VT = N->getOperand(1).getValueType(); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - SDOperand Ch = N->getChain(); - SDOperand Ptr = N->getBasePtr(); - int SVOffset = N->getSrcValueOffset(); - unsigned Alignment = N->getAlignment(); - bool isVolatile = N->isVolatile(); - SDOperand Lo, Hi; - - assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); - - if (!N->isTruncatingStore()) { - unsigned IncrementSize = 0; - - // If this is a vector type, then we have to calculate the increment as - // the product of the element size in bytes, and the number of elements - // in the high half of the vector. - if (MVT::isVector(N->getValue().getValueType())) { - assert(0 && "Vectors not supported yet"); - #if 0 - SDNode *InVal = ST->getValue().Val; - unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); - MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); - - // Figure out if there is a simple type corresponding to this Vector - // type. If so, convert to the vector type. - MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems); - if (TLI.isTypeLegal(TVT)) { - // Turn this into a normal store of the vector type. - Tmp3 = LegalizeOp(Node->getOperand(1)); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - Result = LegalizeOp(Result); - break; - } else if (NumElems == 1) { - // Turn this into a normal store of the scalar type. - Tmp3 = ScalarizeVectorOp(Node->getOperand(1)); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - // The scalarized value type may not be legal, e.g. it might require - // promotion or expansion. Relegalize the scalar store. - return LegalizeOp(Result); - } else { - SplitVectorOp(Node->getOperand(1), Lo, Hi); - IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8; - } - #endif - } else { - GetExpandedOp(N->getValue(), Lo, Hi); - IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0; - - if (!TLI.isLittleEndian()) - std::swap(Lo, Hi); - } - - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), - SVOffset, isVolatile, Alignment); - - assert(Hi.Val && "FIXME: int <-> float should be handled with promote!"); - #if 0 - if (Hi.Val == NULL) { - // Must be int <-> float one-to-one expansion. - return Lo; - } - #endif - - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); - Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } else if (MVT::getSizeInBits(N->getStoredVT()) <= MVT::getSizeInBits(NVT)) { - GetExpandedOp(N->getValue(), Lo, Hi); - return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, - N->getStoredVT(), isVolatile, Alignment); - } else if (TLI.isLittleEndian()) { - // Little-endian - low bits are at low addresses. - GetExpandedOp(N->getValue(), Lo, Hi); - - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - - unsigned ExcessBits = - MVT::getSizeInBits(N->getStoredVT()) - MVT::getSizeInBits(NVT); - MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); - - // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, NEVT, - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } else { - // Big-endian - high bits are at low addresses. Favor aligned stores at - // the cost of some bit-fiddling. - GetExpandedOp(N->getValue(), Lo, Hi); - - MVT::ValueType EVT = N->getStoredVT(); - unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; - unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; - unsigned ExcessBits = (EBytes - IncrementSize)*8; - MVT::ValueType HiVT = - MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits); - - if (ExcessBits < MVT::getSizeInBits(NVT)) { - // Transfer high bits from the top of Lo to the bottom of Hi. - Hi = DAG.getNode(ISD::SHL, NVT, Hi, - DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, - TLI.getShiftAmountTy())); - Hi = DAG.getNode(ISD::OR, NVT, Hi, - DAG.getNode(ISD::SRL, NVT, Lo, - DAG.getConstant(ExcessBits, - TLI.getShiftAmountTy()))); - } - - // Store both the high bits and maybe some of the low bits. - Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), - SVOffset, HiVT, isVolatile, Alignment); - - // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - getIntPtrConstant(IncrementSize)); - // Store the lowest ExcessBits bits in the second half. - Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), - SVOffset+IncrementSize, - MVT::getIntegerType(ExcessBits), - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } -} - -//===----------------------------------------------------------------------===// // Operand Vector Scalarization <1 x ty> -> ty. //===----------------------------------------------------------------------===// Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp?rev=44717&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp (added) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp Sat Dec 8 14:27:32 2007 @@ -0,0 +1,1166 @@ +//===-- LegalizeTypesExpand.cpp - Expansion for LegalizeTypes -------------===// +// +// 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 expansion support for LegalizeTypes. Expansion is the +// act of changing a computation in an invalid type to be a computation in +// multiple registers of a smaller type. For example, implementing i64 +// arithmetic in two i32 registers (as is often needed on 32-bit targets, for +// example). +// +//===----------------------------------------------------------------------===// + +#include "LegalizeTypes.h" +#include "llvm/Constants.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Result Expansion +//===----------------------------------------------------------------------===// + +/// ExpandResult - This method is called when the specified result of the +/// specified node is found to need expansion. At this point, the node may also +/// have invalid operands or may have other results that need promotion, we just +/// know that (at least) one result needs expansion. +void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) { + DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); + SDOperand Lo, Hi; + Lo = Hi = SDOperand(); + + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } + + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "ExpandResult #" << ResNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to expand the result of this operator!"); + abort(); + + case ISD::UNDEF: ExpandResult_UNDEF(N, Lo, Hi); break; + case ISD::Constant: ExpandResult_Constant(N, Lo, Hi); break; + case ISD::BUILD_PAIR: ExpandResult_BUILD_PAIR(N, Lo, Hi); break; + case ISD::MERGE_VALUES: ExpandResult_MERGE_VALUES(N, Lo, Hi); break; + case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break; + case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break; + case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break; + case ISD::BIT_CONVERT: ExpandResult_BIT_CONVERT(N, Lo, Hi); break; + case ISD::SIGN_EXTEND_INREG: ExpandResult_SIGN_EXTEND_INREG(N, Lo, Hi); break; + case ISD::LOAD: ExpandResult_LOAD(cast(N), Lo, Hi); break; + + case ISD::AND: + case ISD::OR: + case ISD::XOR: ExpandResult_Logical(N, Lo, Hi); break; + case ISD::BSWAP: ExpandResult_BSWAP(N, Lo, Hi); break; + case ISD::ADD: + case ISD::SUB: ExpandResult_ADDSUB(N, Lo, Hi); break; + case ISD::ADDC: + case ISD::SUBC: ExpandResult_ADDSUBC(N, Lo, Hi); break; + case ISD::ADDE: + case ISD::SUBE: ExpandResult_ADDSUBE(N, Lo, Hi); break; + case ISD::SELECT: ExpandResult_SELECT(N, Lo, Hi); break; + case ISD::SELECT_CC: ExpandResult_SELECT_CC(N, Lo, Hi); break; + case ISD::MUL: ExpandResult_MUL(N, Lo, Hi); break; + case ISD::SHL: + case ISD::SRA: + case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break; + } + + // If Lo/Hi is null, the sub-method took care of registering results etc. + if (Lo.Val) + SetExpandedOp(SDOperand(N, ResNo), Lo, Hi); +} + +void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + Lo = Hi = DAG.getNode(ISD::UNDEF, NVT); +} + +void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + uint64_t Cst = cast(N)->getValue(); + Lo = DAG.getConstant(Cst, NVT); + Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT); +} + +void DAGTypeLegalizer::ExpandResult_BUILD_PAIR(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Return the operands. + Lo = N->getOperand(0); + Hi = N->getOperand(1); +} + +void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // A MERGE_VALUES node can produce any number of values. We know that the + // first illegal one needs to be expanded into Lo/Hi. + unsigned i; + + // The string of legal results gets turns into the input operands, which have + // the same type. + for (i = 0; isTypeLegal(N->getValueType(i)); ++i) + ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); + + // The first illegal result must be the one that needs to be expanded. + GetExpandedOp(N->getOperand(i), Lo, Hi); + + // Legalize the rest of the results into the input operands whether they are + // legal or not. + unsigned e = N->getNumValues(); + for (++i; i != e; ++i) + ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); +} + +void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDOperand Op = N->getOperand(0); + if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { + // The low part is any extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op); + Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined. + } else { + // For example, extension of an i48 to an i64. The operand type necessarily + // promotes to the result type, so will end up being expanded too. + assert(getTypeAction(Op.getValueType()) == Promote && + "Don't know how to expand this result!"); + SDOperand Res = GetPromotedOp(Op); + assert(Res.getValueType() == N->getValueType(0) && + "Operand over promoted?"); + // Split the promoted operand. This will simplify when it is expanded. + SplitOp(Res, Lo, Hi); + } +} + +void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDOperand Op = N->getOperand(0); + if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { + // The low part is zero extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); + Hi = DAG.getConstant(0, NVT); // The high part is just a zero. + } else { + // For example, extension of an i48 to an i64. The operand type necessarily + // promotes to the result type, so will end up being expanded too. + assert(getTypeAction(Op.getValueType()) == Promote && + "Don't know how to expand this result!"); + SDOperand Res = GetPromotedOp(Op); + assert(Res.getValueType() == N->getValueType(0) && + "Operand over promoted?"); + // Split the promoted operand. This will simplify when it is expanded. + SplitOp(Res, Lo, Hi); + unsigned ExcessBits = + MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); + Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits)); + } +} + +void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDOperand Op = N->getOperand(0); + if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { + // The low part is sign extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); + // The high part is obtained by SRA'ing all but one of the bits of low part. + unsigned LoSize = MVT::getSizeInBits(NVT); + Hi = DAG.getNode(ISD::SRA, NVT, Lo, + DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); + } else { + // For example, extension of an i48 to an i64. The operand type necessarily + // promotes to the result type, so will end up being expanded too. + assert(getTypeAction(Op.getValueType()) == Promote && + "Don't know how to expand this result!"); + SDOperand Res = GetPromotedOp(Op); + assert(Res.getValueType() == N->getValueType(0) && + "Operand over promoted?"); + // Split the promoted operand. This will simplify when it is expanded. + SplitOp(Res, Lo, Hi); + unsigned ExcessBits = + MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); + Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, + DAG.getValueType(MVT::getIntegerType(ExcessBits))); + } +} + +void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Lower the bit-convert to a store/load from the stack, then expand the load. + SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); + ExpandResult_LOAD(cast(Op.Val), Lo, Hi); +} + +void DAGTypeLegalizer:: +ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + GetExpandedOp(N->getOperand(0), Lo, Hi); + MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); + + if (MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(Lo.getValueType())) { + // sext_inreg the low part if needed. + Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo, + N->getOperand(1)); + + // The high part gets the sign extension from the lo-part. This handles + // things like sextinreg V:i64 from i8. + Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo, + DAG.getConstant(MVT::getSizeInBits(Hi.getValueType())-1, + TLI.getShiftAmountTy())); + } else { + // For example, extension of an i48 to an i64. Leave the low part alone, + // sext_inreg the high part. + unsigned ExcessBits = + MVT::getSizeInBits(EVT) - MVT::getSizeInBits(Lo.getValueType()); + Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, + DAG.getValueType(MVT::getIntegerType(ExcessBits))); + } +} + +void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + SDOperand Ch = N->getChain(); // Legalize the chain. + SDOperand Ptr = N->getBasePtr(); // Legalize the pointer. + ISD::LoadExtType ExtType = N->getExtensionType(); + int SVOffset = N->getSrcValueOffset(); + unsigned Alignment = N->getAlignment(); + bool isVolatile = N->isVolatile(); + + assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); + + if (ExtType == ISD::NON_EXTLOAD) { + Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + isVolatile, Alignment); + // Increment the pointer to the other half. + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, + isVolatile, MinAlign(Alignment, IncrementSize)); + + // Build a factor node to remember that this load is independent of the + // other one. + Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + + // Handle endianness of the load. + if (!TLI.isLittleEndian()) + std::swap(Lo, Hi); + } else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) { + MVT::ValueType EVT = N->getLoadedVT(); + + Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT, + isVolatile, Alignment); + + // Remember the chain. + Ch = Lo.getValue(1); + + if (ExtType == ISD::SEXTLOAD) { + // The high part is obtained by SRA'ing all but one of the bits of the + // lo part. + unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); + Hi = DAG.getNode(ISD::SRA, NVT, Lo, + DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); + } else if (ExtType == ISD::ZEXTLOAD) { + // The high part is just a zero. + Hi = DAG.getConstant(0, NVT); + } else { + assert(ExtType == ISD::EXTLOAD && "Unknown extload!"); + // The high part is undefined. + Hi = DAG.getNode(ISD::UNDEF, NVT); + } + } else if (TLI.isLittleEndian()) { + // Little-endian - low bits are at low addresses. + Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + isVolatile, Alignment); + + unsigned ExcessBits = + MVT::getSizeInBits(N->getLoadedVT()) - MVT::getSizeInBits(NVT); + MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); + + // Increment the pointer to the other half. + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), + SVOffset+IncrementSize, NEVT, + isVolatile, MinAlign(Alignment, IncrementSize)); + + // Build a factor node to remember that this load is independent of the + // other one. + Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + } else { + // Big-endian - high bits are at low addresses. Favor aligned loads at + // the cost of some bit-fiddling. + MVT::ValueType EVT = N->getLoadedVT(); + unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + unsigned ExcessBits = (EBytes - IncrementSize)*8; + + // Load both the high bits and maybe some of the low bits. + Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits), + isVolatile, Alignment); + + // Increment the pointer to the other half. + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + // Load the rest of the low bits. + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), + SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits), + isVolatile, MinAlign(Alignment, IncrementSize)); + + // Build a factor node to remember that this load is independent of the + // other one. + Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + + if (ExcessBits < MVT::getSizeInBits(NVT)) { + // Transfer low bits from the bottom of Hi to the top of Lo. + Lo = DAG.getNode(ISD::OR, NVT, Lo, + DAG.getNode(ISD::SHL, NVT, Hi, + DAG.getConstant(ExcessBits, + TLI.getShiftAmountTy()))); + // Move high bits to the right position in Hi. + Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi, + DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, + TLI.getShiftAmountTy())); + } + } + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Ch); +} + +void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + SDOperand LL, LH, RL, RH; + GetExpandedOp(N->getOperand(0), LL, LH); + GetExpandedOp(N->getOperand(1), RL, RH); + Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL); + Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH); +} + +void DAGTypeLegalizer::ExpandResult_BSWAP(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + GetExpandedOp(N->getOperand(0), Hi, Lo); // Note swapped operands. + Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo); + Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi); +} + +void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + SDOperand LL, LH, RL, RH; + GetExpandedOp(N->getOperand(1), LL, LH); + GetExpandedOp(N->getOperand(2), RL, RH); + Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL); + + assert(N->getOperand(0).getValueType() != MVT::f32 && + "FIXME: softfp shouldn't use expand!"); + Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH); +} + +void DAGTypeLegalizer::ExpandResult_SELECT_CC(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + SDOperand LL, LH, RL, RH; + GetExpandedOp(N->getOperand(2), LL, LH); + GetExpandedOp(N->getOperand(3), RL, RH); + Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), + N->getOperand(1), LL, RL, N->getOperand(4)); + + assert(N->getOperand(0).getValueType() != MVT::f32 && + "FIXME: softfp shouldn't use expand!"); + Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), + N->getOperand(1), LH, RH, N->getOperand(4)); +} + +void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Expand the subcomponents. + SDOperand LHSL, LHSH, RHSL, RHSH; + GetExpandedOp(N->getOperand(0), LHSL, LHSH); + GetExpandedOp(N->getOperand(1), RHSL, RHSH); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDOperand LoOps[2] = { LHSL, RHSL }; + SDOperand HiOps[3] = { LHSH, RHSH }; + + if (N->getOpcode() == ISD::ADD) { + Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + } else { + Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + } +} + +void DAGTypeLegalizer::ExpandResult_ADDSUBC(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Expand the subcomponents. + SDOperand LHSL, LHSH, RHSL, RHSH; + GetExpandedOp(N->getOperand(0), LHSL, LHSH); + GetExpandedOp(N->getOperand(1), RHSL, RHSH); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDOperand LoOps[2] = { LHSL, RHSL }; + SDOperand HiOps[3] = { LHSH, RHSH }; + + if (N->getOpcode() == ISD::ADDC) { + Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + } else { + Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + } + + // Legalized the flag result - switch anything that used the old flag to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); +} + +void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Expand the subcomponents. + SDOperand LHSL, LHSH, RHSL, RHSH; + GetExpandedOp(N->getOperand(0), LHSL, LHSH); + GetExpandedOp(N->getOperand(1), RHSL, RHSH); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDOperand LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; + SDOperand HiOps[3] = { LHSH, RHSH }; + + Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3); + + // Legalized the flag result - switch anything that used the old flag to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); +} + +void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType VT = N->getValueType(0); + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + + bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT); + bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT); + bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT); + bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT); + if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { + SDOperand LL, LH, RL, RH; + GetExpandedOp(N->getOperand(0), LL, LH); + GetExpandedOp(N->getOperand(1), RL, RH); + unsigned BitSize = MVT::getSizeInBits(NVT); + unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0)); + unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1)); + + // FIXME: generalize this to handle other bit sizes + if (LHSSB == 32 && RHSSB == 32 && + DAG.MaskedValueIsZero(N->getOperand(0), 0xFFFFFFFF00000000ULL) && + DAG.MaskedValueIsZero(N->getOperand(1), 0xFFFFFFFF00000000ULL)) { + // The inputs are both zero-extended. + if (HasUMUL_LOHI) { + // We can emit a umul_lohi. + Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Hi = SDOperand(Lo.Val, 1); + return; + } + if (HasMULHU) { + // We can emit a mulhu+mul. + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + return; + } + } + if (LHSSB > BitSize && RHSSB > BitSize) { + // The input values are both sign-extended. + if (HasSMUL_LOHI) { + // We can emit a smul_lohi. + Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Hi = SDOperand(Lo.Val, 1); + return; + } + if (HasMULHS) { + // We can emit a mulhs+mul. + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); + return; + } + } + if (HasUMUL_LOHI) { + // Lo,Hi = umul LHS, RHS. + SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, + DAG.getVTList(NVT, NVT), LL, RL); + Lo = UMulLOHI; + Hi = UMulLOHI.getValue(1); + RH = DAG.getNode(ISD::MUL, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + return; + } + } + + abort(); +#if 0 // FIXME! + // If nothing else, we can make a libcall. + Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), N, + false/*sign irrelevant*/, Hi); +#endif +} + + +void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType VT = N->getValueType(0); + + // If we can emit an efficient shift operation, do so now. Check to see if + // the RHS is a constant. + if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) + return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi); + + // If we can determine that the high bit of the shift is zero or one, even if + // the low bits are variable, emit this shift in an optimized form. + if (ExpandShiftWithKnownAmountBit(N, Lo, Hi)) + return; + + // If this target supports shift_PARTS, use it. First, map to the _PARTS opc. + unsigned PartsOpc; + if (N->getOpcode() == ISD::SHL) + PartsOpc = ISD::SHL_PARTS; + else if (N->getOpcode() == ISD::SRL) + PartsOpc = ISD::SRL_PARTS; + else { + assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); + PartsOpc = ISD::SRA_PARTS; + } + + // Next check to see if the target supports this SHL_PARTS operation or if it + // will custom expand it. + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT); + if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || + Action == TargetLowering::Custom) { + // Expand the subcomponents. + SDOperand LHSL, LHSH; + GetExpandedOp(N->getOperand(0), LHSL, LHSH); + + SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) }; + MVT::ValueType VT = LHSL.getValueType(); + Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); + Hi = Lo.getValue(1); + return; + } + + abort(); +#if 0 // FIXME! + // Otherwise, emit a libcall. + unsigned RuntimeCode = ; // SRL -> SRL_I64 etc. + bool Signed = ; + Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SRL_I64), N, + false/*lshr is unsigned*/, Hi); +#endif +} + + +/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded, +/// and the shift amount is a constant 'Amt'. Expand the operation. +void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, + SDOperand &Lo, SDOperand &Hi) { + // Expand the incoming operand to be shifted, so that we have its parts + SDOperand InL, InH; + GetExpandedOp(N->getOperand(0), InL, InH); + + MVT::ValueType NVT = InL.getValueType(); + unsigned VTBits = MVT::getSizeInBits(N->getValueType(0)); + unsigned NVTBits = MVT::getSizeInBits(NVT); + MVT::ValueType ShTy = N->getOperand(1).getValueType(); + + if (N->getOpcode() == ISD::SHL) { + if (Amt > VTBits) { + Lo = Hi = DAG.getConstant(0, NVT); + } else if (Amt > NVTBits) { + Lo = DAG.getConstant(0, NVT); + Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); + } else if (Amt == NVTBits) { + Lo = DAG.getConstant(0, NVT); + Hi = InL; + } else { + Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy)); + Hi = DAG.getNode(ISD::OR, NVT, + DAG.getNode(ISD::SHL, NVT, InH, + DAG.getConstant(Amt, ShTy)), + DAG.getNode(ISD::SRL, NVT, InL, + DAG.getConstant(NVTBits-Amt, ShTy))); + } + return; + } + + if (N->getOpcode() == ISD::SRL) { + if (Amt > VTBits) { + Lo = DAG.getConstant(0, NVT); + Hi = DAG.getConstant(0, NVT); + } else if (Amt > NVTBits) { + Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); + Hi = DAG.getConstant(0, NVT); + } else if (Amt == NVTBits) { + Lo = InH; + Hi = DAG.getConstant(0, NVT); + } else { + Lo = DAG.getNode(ISD::OR, NVT, + DAG.getNode(ISD::SRL, NVT, InL, + DAG.getConstant(Amt, ShTy)), + DAG.getNode(ISD::SHL, NVT, InH, + DAG.getConstant(NVTBits-Amt, ShTy))); + Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy)); + } + return; + } + + assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); + if (Amt > VTBits) { + Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(NVTBits-1, ShTy)); + } else if (Amt > NVTBits) { + Lo = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(Amt-NVTBits, ShTy)); + Hi = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(NVTBits-1, ShTy)); + } else if (Amt == NVTBits) { + Lo = InH; + Hi = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(NVTBits-1, ShTy)); + } else { + Lo = DAG.getNode(ISD::OR, NVT, + DAG.getNode(ISD::SRL, NVT, InL, + DAG.getConstant(Amt, ShTy)), + DAG.getNode(ISD::SHL, NVT, InH, + DAG.getConstant(NVTBits-Amt, ShTy))); + Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy)); + } +} + +/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify +/// this shift based on knowledge of the high bit of the shift amount. If we +/// can tell this, we know that it is >= 32 or < 32, without knowing the actual +/// shift amount. +bool DAGTypeLegalizer:: +ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + unsigned NVTBits = MVT::getSizeInBits(NVT); + assert(!(NVTBits & (NVTBits - 1)) && + "Expanded integer type size not a power of two!"); + + uint64_t HighBitMask = NVTBits, KnownZero, KnownOne; + DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne); + + // If we don't know anything about the high bit, exit. + if (((KnownZero|KnownOne) & HighBitMask) == 0) + return false; + + // Get the incoming operand to be shifted. + SDOperand InL, InH; + GetExpandedOp(N->getOperand(0), InL, InH); + SDOperand Amt = N->getOperand(1); + + // If we know that the high bit of the shift amount is one, then we can do + // this as a couple of simple shifts. + if (KnownOne & HighBitMask) { + // Mask out the high bit, which we know is set. + Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt, + DAG.getConstant(NVTBits-1, Amt.getValueType())); + + switch (N->getOpcode()) { + default: assert(0 && "Unknown shift"); + case ISD::SHL: + Lo = DAG.getConstant(0, NVT); // Low part is zero. + Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part. + return true; + case ISD::SRL: + Hi = DAG.getConstant(0, NVT); // Hi part is zero. + Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part. + return true; + case ISD::SRA: + Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part. + DAG.getConstant(NVTBits-1, Amt.getValueType())); + Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part. + return true; + } + } + + // If we know that the high bit of the shift amount is zero, then we can do + // this as a couple of simple shifts. + assert((KnownZero & HighBitMask) && "Bad mask computation above"); + + // Compute 32-amt. + SDOperand Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(), + DAG.getConstant(NVTBits, Amt.getValueType()), + Amt); + unsigned Op1, Op2; + switch (N->getOpcode()) { + default: assert(0 && "Unknown shift"); + case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break; + case ISD::SRL: + case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break; + } + + Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt); + Hi = DAG.getNode(ISD::OR, NVT, + DAG.getNode(Op1, NVT, InH, Amt), + DAG.getNode(Op2, NVT, InL, Amt2)); + return true; +} + + +//===----------------------------------------------------------------------===// +// Operand Expansion +//===----------------------------------------------------------------------===// + +/// ExpandOperand - This method is called when the specified operand of the +/// specified node is found to need expansion. At this point, all of the result +/// types of the node are known to be legal, but other operands of the node may +/// need promotion or expansion as well as the specified one. +bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) { + DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n"); + SDOperand Res(0, 0); + + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, 0), DAG); + + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: + #ifndef NDEBUG + cerr << "ExpandOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; + #endif + assert(0 && "Do not know how to expand this operator's operand!"); + abort(); + + case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break; + case ISD::BIT_CONVERT: Res = ExpandOperand_BIT_CONVERT(N); break; + + case ISD::SINT_TO_FP: + Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0)); + break; + case ISD::UINT_TO_FP: + Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); + break; + case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break; + case ISD::SETCC: Res = ExpandOperand_SETCC(N); break; + + case ISD::STORE: + Res = ExpandOperand_STORE(cast(N), OpNo); + break; + case ISD::MEMSET: + case ISD::MEMCPY: + case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; + } + } + + // If the result is null, the sub-method took care of registering results etc. + if (!Res.Val) return false; + // If the result is N, the sub-method updated N in place. Check to see if any + // operands are new, and if so, mark them. + if (Res.Val == N) { + // Mark N as new and remark N and its operands. This allows us to correctly + // revisit N if it needs another step of promotion and allows us to visit + // any new operands to N. + N->setNodeId(NewNode); + MarkNewNodes(N); + return true; + } + + assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + "Invalid operand expansion"); + + ReplaceValueWith(SDOperand(N, 0), Res); + return false; +} + +SDOperand DAGTypeLegalizer::ExpandOperand_TRUNCATE(SDNode *N) { + SDOperand InL, InH; + GetExpandedOp(N->getOperand(0), InL, InH); + // Just truncate the low part of the source. + return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL); +} + +SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) { + return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); +} + +SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source, + MVT::ValueType DestTy) { + // We know the destination is legal, but that the input needs to be expanded. + assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); + + // Check to see if the target has a custom way to lower this. If so, use it. + switch (TLI.getOperationAction(ISD::SINT_TO_FP, Source.getValueType())) { + default: assert(0 && "This action not implemented for this operation!"); + case TargetLowering::Legal: + case TargetLowering::Expand: + break; // This case is handled below. + case TargetLowering::Custom: + SDOperand NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy, + Source), DAG); + if (NV.Val) return NV; + break; // The target lowered this. + } + + RTLIB::Libcall LC; + if (DestTy == MVT::f32) + LC = RTLIB::SINTTOFP_I64_F32; + else { + assert(DestTy == MVT::f64 && "Unknown fp value type!"); + LC = RTLIB::SINTTOFP_I64_F64; + } + + assert(0 && "FIXME: no libcalls yet!"); + abort(); +#if 0 + assert(TLI.getLibcallName(LC) && "Don't know how to expand this SINT_TO_FP!"); + Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source); + SDOperand UnusedHiPart; + return ExpandLibCall(TLI.getLibcallName(LC), Source.Val, true, UnusedHiPart); +#endif +} + +SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source, + MVT::ValueType DestTy) { + // We know the destination is legal, but that the input needs to be expanded. + assert(getTypeAction(Source.getValueType()) == Expand && + "This is not an expansion!"); + assert(Source.getValueType() == MVT::i64 && "Only handle expand from i64!"); + + // If this is unsigned, and not supported, first perform the conversion to + // signed, then adjust the result if the sign bit is set. + SDOperand SignedConv = ExpandOperand_SINT_TO_FP(Source, DestTy); + + // The 64-bit value loaded will be incorrectly if the 'sign bit' of the + // incoming integer is set. To handle this, we dynamically test to see if + // it is set, and, if so, add a fudge factor. + SDOperand Lo, Hi; + GetExpandedOp(Source, Lo, Hi); + + SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi, + DAG.getConstant(0, Hi.getValueType()), + ISD::SETLT); + SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); + SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), + SignSet, Four, Zero); + uint64_t FF = 0x5f800000ULL; + if (TLI.isLittleEndian()) FF <<= 32; + Constant *FudgeFactor = ConstantInt::get((Type*)Type::Int64Ty, FF); + + SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); + CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); + SDOperand FudgeInReg; + if (DestTy == MVT::f32) + FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0); + else if (MVT::getSizeInBits(DestTy) > MVT::getSizeInBits(MVT::f32)) + // FIXME: Avoid the extend by construction the right constantpool? + FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(), + CPIdx, NULL, 0, MVT::f32); + else + assert(0 && "Unexpected conversion"); + + return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); +} + +SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) { + SDOperand Lo, Hi; + GetExpandedOp(N->getOperand(0), Lo, Hi); + return cast(N->getOperand(1))->getValue() ? Hi : Lo; +} + +SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) { + SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); + ISD::CondCode CCCode = cast(N->getOperand(2))->get(); + ExpandSetCCOperands(NewLHS, NewRHS, CCCode); + + // If ExpandSetCCOperands returned a scalar, use it. + if (NewRHS.Val == 0) return NewLHS; + + // Otherwise, update N to have the operands specified. + return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS, + DAG.getCondCode(CCCode)); +} + +/// ExpandSetCCOperands - Expand the operands of a comparison. This code is +/// shared among BR_CC, SELECT_CC, and SETCC handlers. +void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, + ISD::CondCode &CCCode) { + SDOperand LHSLo, LHSHi, RHSLo, RHSHi; + GetExpandedOp(NewLHS, LHSLo, LHSHi); + GetExpandedOp(NewRHS, RHSLo, RHSHi); + + MVT::ValueType VT = NewLHS.getValueType(); + if (VT == MVT::f32 || VT == MVT::f64) { + assert(0 && "FIXME: softfp not implemented yet! should be promote not exp"); + } + + if (VT == MVT::ppcf128) { + // FIXME: This generated code sucks. We want to generate + // FCMP crN, hi1, hi2 + // BNE crN, L: + // FCMP crN, lo1, lo2 + // The following can be improved, but not that much. + SDOperand Tmp1, Tmp2, Tmp3; + Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); + Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, CCCode); + Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETNE); + Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, CCCode); + Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); + NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); + NewRHS = SDOperand(); // LHS is the result, not a compare. + return; + } + + + if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) { + if (RHSLo == RHSHi) + if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) + if (RHSCST->isAllOnesValue()) { + // Equality comparison to -1. + NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); + NewRHS = RHSLo; + return; + } + + NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); + NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); + NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS); + NewRHS = DAG.getConstant(0, NewLHS.getValueType()); + return; + } + + // If this is a comparison of the sign bit, just look at the top part. + // X > -1, x < 0 + if (ConstantSDNode *CST = dyn_cast(NewRHS)) + if ((CCCode == ISD::SETLT && CST->getValue() == 0) || // X < 0 + (CCCode == ISD::SETGT && CST->isAllOnesValue())) { // X > -1 + NewLHS = LHSHi; + NewRHS = RHSHi; + return; + } + + // FIXME: This generated code sucks. + ISD::CondCode LowCC; + switch (CCCode) { + default: assert(0 && "Unknown integer setcc!"); + case ISD::SETLT: + case ISD::SETULT: LowCC = ISD::SETULT; break; + case ISD::SETGT: + case ISD::SETUGT: LowCC = ISD::SETUGT; break; + case ISD::SETLE: + case ISD::SETULE: LowCC = ISD::SETULE; break; + case ISD::SETGE: + case ISD::SETUGE: LowCC = ISD::SETUGE; break; + } + + // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison + // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands + // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; + + // NOTE: on targets without efficient SELECT of bools, we can always use + // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) + TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL); + SDOperand Tmp1, Tmp2; + Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC, + false, DagCombineInfo); + if (!Tmp1.Val) + Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC); + Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, + CCCode, false, DagCombineInfo); + if (!Tmp2.Val) + Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, + DAG.getCondCode(CCCode)); + + ConstantSDNode *Tmp1C = dyn_cast(Tmp1.Val); + ConstantSDNode *Tmp2C = dyn_cast(Tmp2.Val); + if ((Tmp1C && Tmp1C->getValue() == 0) || + (Tmp2C && Tmp2C->getValue() == 0 && + (CCCode == ISD::SETLE || CCCode == ISD::SETGE || + CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) || + (Tmp2C && Tmp2C->getValue() == 1 && + (CCCode == ISD::SETLT || CCCode == ISD::SETGT || + CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) { + // low part is known false, returns high part. + // For LE / GE, if high part is known false, ignore the low part. + // For LT / GT, if high part is known true, ignore the low part. + NewLHS = Tmp2; + NewRHS = SDOperand(); + return; + } + + NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, + ISD::SETEQ, false, DagCombineInfo); + if (!NewLHS.Val) + NewLHS = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); + NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), + NewLHS, Tmp1, Tmp2); + NewRHS = SDOperand(); +} + +SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) { + assert(OpNo == 1 && "Can only expand the stored value so far"); + + MVT::ValueType VT = N->getOperand(1).getValueType(); + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + SDOperand Ch = N->getChain(); + SDOperand Ptr = N->getBasePtr(); + int SVOffset = N->getSrcValueOffset(); + unsigned Alignment = N->getAlignment(); + bool isVolatile = N->isVolatile(); + SDOperand Lo, Hi; + + assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); + + if (!N->isTruncatingStore()) { + unsigned IncrementSize = 0; + + // If this is a vector type, then we have to calculate the increment as + // the product of the element size in bytes, and the number of elements + // in the high half of the vector. + if (MVT::isVector(N->getValue().getValueType())) { + assert(0 && "Vectors not supported yet"); + #if 0 + SDNode *InVal = ST->getValue().Val; + unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); + MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); + + // Figure out if there is a simple type corresponding to this Vector + // type. If so, convert to the vector type. + MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems); + if (TLI.isTypeLegal(TVT)) { + // Turn this into a normal store of the vector type. + Tmp3 = LegalizeOp(Node->getOperand(1)); + Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + SVOffset, isVolatile, Alignment); + Result = LegalizeOp(Result); + break; + } else if (NumElems == 1) { + // Turn this into a normal store of the scalar type. + Tmp3 = ScalarizeVectorOp(Node->getOperand(1)); + Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + SVOffset, isVolatile, Alignment); + // The scalarized value type may not be legal, e.g. it might require + // promotion or expansion. Relegalize the scalar store. + return LegalizeOp(Result); + } else { + SplitVectorOp(Node->getOperand(1), Lo, Hi); + IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8; + } + #endif + } else { + GetExpandedOp(N->getValue(), Lo, Hi); + IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0; + + if (!TLI.isLittleEndian()) + std::swap(Lo, Hi); + } + + Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), + SVOffset, isVolatile, Alignment); + + assert(Hi.Val && "FIXME: int <-> float should be handled with promote!"); + #if 0 + if (Hi.Val == NULL) { + // Must be int <-> float one-to-one expansion. + return Lo; + } + #endif + + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); + Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, + isVolatile, MinAlign(Alignment, IncrementSize)); + return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + } else if (MVT::getSizeInBits(N->getStoredVT()) <= MVT::getSizeInBits(NVT)) { + GetExpandedOp(N->getValue(), Lo, Hi); + return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, + N->getStoredVT(), isVolatile, Alignment); + } else if (TLI.isLittleEndian()) { + // Little-endian - low bits are at low addresses. + GetExpandedOp(N->getValue(), Lo, Hi); + + Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, + isVolatile, Alignment); + + unsigned ExcessBits = + MVT::getSizeInBits(N->getStoredVT()) - MVT::getSizeInBits(NVT); + MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); + + // Increment the pointer to the other half. + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), + SVOffset+IncrementSize, NEVT, + isVolatile, MinAlign(Alignment, IncrementSize)); + return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + } else { + // Big-endian - high bits are at low addresses. Favor aligned stores at + // the cost of some bit-fiddling. + GetExpandedOp(N->getValue(), Lo, Hi); + + MVT::ValueType EVT = N->getStoredVT(); + unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + unsigned ExcessBits = (EBytes - IncrementSize)*8; + MVT::ValueType HiVT = + MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits); + + if (ExcessBits < MVT::getSizeInBits(NVT)) { + // Transfer high bits from the top of Lo to the bottom of Hi. + Hi = DAG.getNode(ISD::SHL, NVT, Hi, + DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, + TLI.getShiftAmountTy())); + Hi = DAG.getNode(ISD::OR, NVT, Hi, + DAG.getNode(ISD::SRL, NVT, Lo, + DAG.getConstant(ExcessBits, + TLI.getShiftAmountTy()))); + } + + // Store both the high bits and maybe some of the low bits. + Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), + SVOffset, HiVT, isVolatile, Alignment); + + // Increment the pointer to the other half. + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + // Store the lowest ExcessBits bits in the second half. + Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), + SVOffset+IncrementSize, + MVT::getIntegerType(ExcessBits), + isVolatile, MinAlign(Alignment, IncrementSize)); + return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + } +} + From sabre at nondot.org Sat Dec 8 14:30:28 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 20:30:28 -0000 Subject: [llvm-commits] [llvm] r44718 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypesScalarize.cpp Message-ID: <200712082030.lB8KUSBC008606@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 14:30:28 2007 New Revision: 44718 URL: http://llvm.org/viewvc/llvm-project?rev=44718&view=rev Log: split scalarization out to its own file. Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=44718&r1=44717&r2=44718&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sat Dec 8 14:30:28 2007 @@ -407,189 +407,6 @@ //===----------------------------------------------------------------------===// -// Result Vector Scalarization: <1 x ty> -> ty. -//===----------------------------------------------------------------------===// - - -void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { - DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); - cerr << "\n"); - SDOperand R = SDOperand(); - - // FIXME: Custom lowering for scalarization? -#if 0 - // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } -#endif - - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ScalarizeResult #" << ResNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to scalarize the result of this operator!"); - abort(); - - case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; - case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; - case ISD::ADD: - case ISD::FADD: - case ISD::SUB: - case ISD::FSUB: - case ISD::MUL: - case ISD::FMUL: - case ISD::SDIV: - case ISD::UDIV: - case ISD::FDIV: - case ISD::SREM: - case ISD::UREM: - case ISD::FREM: - case ISD::FPOW: - case ISD::AND: - case ISD::OR: - case ISD::XOR: R = ScalarizeRes_BinOp(N); break; - case ISD::FNEG: - case ISD::FABS: - case ISD::FSQRT: - case ISD::FSIN: - case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; - case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; - case ISD::BUILD_VECTOR: R = N->getOperand(0); break; - case ISD::INSERT_VECTOR_ELT: R = N->getOperand(1); break; - case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break; - case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break; - case ISD::SELECT: R = ScalarizeRes_SELECT(N); break; - } - - // If R is null, the sub-method took care of registering the resul. - if (R.Val) - SetScalarizedOp(SDOperand(N, ResNo), R); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(N->getValueType(0))); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { - SDOperand Result = DAG.getLoad(MVT::getVectorElementType(N->getValueType(0)), - N->getChain(), N->getBasePtr(), - N->getSrcValue(), N->getSrcValueOffset(), - N->isVolatile(), N->getAlignment()); - - // Legalized the chain result - switch anything that used the old chain to - // use the new one. - ReplaceValueWith(SDOperand(N, 1), Result.getValue(1)); - return Result; -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) { - SDOperand LHS = GetScalarizedOp(N->getOperand(0)); - SDOperand RHS = GetScalarizedOp(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) { - SDOperand Op = GetScalarizedOp(N->getOperand(0)); - return DAG.getNode(N->getOpcode(), Op.getValueType(), Op); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) { - SDOperand Op = GetScalarizedOp(N->getOperand(0)); - return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) { - // Figure out if the scalar is the LHS or RHS and return it. - SDOperand EltNum = N->getOperand(2).getOperand(0); - unsigned Op = cast(EltNum)->getValue() != 0; - return GetScalarizedOp(N->getOperand(Op)); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) { - MVT::ValueType NewVT = MVT::getVectorElementType(N->getValueType(0)); - return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); -} - -SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) { - SDOperand LHS = GetScalarizedOp(N->getOperand(1)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS, - GetScalarizedOp(N->getOperand(2))); -} - - -//===----------------------------------------------------------------------===// -// Operand Vector Scalarization <1 x ty> -> ty. -//===----------------------------------------------------------------------===// - -bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { - DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG); - cerr << "\n"); - SDOperand Res(0, 0); - - // FIXME: Should we support custom lowering for scalarization? -#if 0 - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); -#endif - - if (Res.Val == 0) { - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ScalarizeOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to scalarize this operator's operand!"); - abort(); - - case ISD::EXTRACT_VECTOR_ELT: - Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N, OpNo); - break; - } - } - - // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; - - // If the result is N, the sub-method updated N in place. Check to see if any - // operands are new, and if so, mark them. - if (Res.Val == N) { - // Mark N as new and remark N and its operands. This allows us to correctly - // revisit N if it needs another step of promotion and allows us to visit - // any new operands to N. - N->setNodeId(NewNode); - MarkNewNodes(N); - return true; - } - - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && - "Invalid operand expansion"); - - ReplaceValueWith(SDOperand(N, 0), Res); - return false; -} - -/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be -/// scalarized, it must be <1 x ty>, just return the operand, ignoring the -/// index. -SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, - unsigned OpNo) { - return GetScalarizedOp(N->getOperand(0)); -} - - -//===----------------------------------------------------------------------===// // Entry Point //===----------------------------------------------------------------------===// Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp?rev=44718&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp (added) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp Sat Dec 8 14:30:28 2007 @@ -0,0 +1,202 @@ +//===-- LegalizeTypesScalarize.cpp - Scalarization for LegalizeTypes ------===// +// +// 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 scalarization support for LegalizeTypes. Scalarization +// is the act of changing a computation in an invalid single-element vector type +// to be a computation in its scalar element type. For example, implementing +// <1 x f32> arithmetic in a scalar f32 register. This is needed as a base case +// when scalarizing vector arithmetic like <4 x f32>, which eventually +// decomposes to scalars if the target doesn't support v4f32 or v2f32 types. +// +//===----------------------------------------------------------------------===// + +#include "LegalizeTypes.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Result Vector Scalarization: <1 x ty> -> ty. +//===----------------------------------------------------------------------===// + +void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { + DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); + cerr << "\n"); + SDOperand R = SDOperand(); + + // FIXME: Custom lowering for scalarization? +#if 0 + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } +#endif + + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "ScalarizeResult #" << ResNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to scalarize the result of this operator!"); + abort(); + + case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; + case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; + case ISD::ADD: + case ISD::FADD: + case ISD::SUB: + case ISD::FSUB: + case ISD::MUL: + case ISD::FMUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::FDIV: + case ISD::SREM: + case ISD::UREM: + case ISD::FREM: + case ISD::FPOW: + case ISD::AND: + case ISD::OR: + case ISD::XOR: R = ScalarizeRes_BinOp(N); break; + case ISD::FNEG: + case ISD::FABS: + case ISD::FSQRT: + case ISD::FSIN: + case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; + case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; + case ISD::BUILD_VECTOR: R = N->getOperand(0); break; + case ISD::INSERT_VECTOR_ELT: R = N->getOperand(1); break; + case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break; + case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break; + case ISD::SELECT: R = ScalarizeRes_SELECT(N); break; + } + + // If R is null, the sub-method took care of registering the resul. + if (R.Val) + SetScalarizedOp(SDOperand(N, ResNo), R); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) { + return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(N->getValueType(0))); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { + SDOperand Result = DAG.getLoad(MVT::getVectorElementType(N->getValueType(0)), + N->getChain(), N->getBasePtr(), + N->getSrcValue(), N->getSrcValueOffset(), + N->isVolatile(), N->getAlignment()); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Result.getValue(1)); + return Result; +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) { + SDOperand LHS = GetScalarizedOp(N->getOperand(0)); + SDOperand RHS = GetScalarizedOp(N->getOperand(1)); + return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) { + SDOperand Op = GetScalarizedOp(N->getOperand(0)); + return DAG.getNode(N->getOpcode(), Op.getValueType(), Op); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) { + SDOperand Op = GetScalarizedOp(N->getOperand(0)); + return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) { + // Figure out if the scalar is the LHS or RHS and return it. + SDOperand EltNum = N->getOperand(2).getOperand(0); + unsigned Op = cast(EltNum)->getValue() != 0; + return GetScalarizedOp(N->getOperand(Op)); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) { + MVT::ValueType NewVT = MVT::getVectorElementType(N->getValueType(0)); + return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) { + SDOperand LHS = GetScalarizedOp(N->getOperand(1)); + return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS, + GetScalarizedOp(N->getOperand(2))); +} + + +//===----------------------------------------------------------------------===// +// Operand Vector Scalarization <1 x ty> -> ty. +//===----------------------------------------------------------------------===// + +bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { + DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG); + cerr << "\n"); + SDOperand Res(0, 0); + + // FIXME: Should we support custom lowering for scalarization? +#if 0 + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, 0), DAG); +#endif + + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "ScalarizeOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to scalarize this operator's operand!"); + abort(); + + case ISD::EXTRACT_VECTOR_ELT: + Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N, OpNo); + break; + } + } + + // If the result is null, the sub-method took care of registering results etc. + if (!Res.Val) return false; + + // If the result is N, the sub-method updated N in place. Check to see if any + // operands are new, and if so, mark them. + if (Res.Val == N) { + // Mark N as new and remark N and its operands. This allows us to correctly + // revisit N if it needs another step of promotion and allows us to visit + // any new operands to N. + N->setNodeId(NewNode); + MarkNewNodes(N); + return true; + } + + assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + "Invalid operand expansion"); + + ReplaceValueWith(SDOperand(N, 0), Res); + return false; +} + +/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be +/// scalarized, it must be <1 x ty>, just return the operand, ignoring the +/// index. +SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, + unsigned OpNo) { + return GetScalarizedOp(N->getOperand(0)); +} + From evan.cheng at apple.com Sat Dec 8 15:23:12 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 08 Dec 2007 13:23:12 -0800 Subject: [llvm-commits] [llvm] r44702 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineLICM.cpp lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h In-Reply-To: <200712080717.lB87Hu3F026865@zion.cs.uiuc.edu> References: <200712080717.lB87Hu3F026865@zion.cs.uiuc.edu> Message-ID: Sorry, I made a mistake. The renaming is a bad idea. Please revert. We should mark instructions that produce side effects. All the others have no side effects. Then those that do not have register operands are candidates for trivial remat. Evan On Dec 7, 2007, at 11:17 PM, Bill Wendling wrote: > Author: void > Date: Sat Dec 8 01:17:56 2007 > New Revision: 44702 > > URL: http://llvm.org/viewvc/llvm-project?rev=44702&view=rev > Log: > Renaming: > > isTriviallyReMaterializable -> hasNoSideEffects > isReallyTriviallyReMaterializable -> isTriviallyReMaterializable > > Modified: > llvm/trunk/include/llvm/Target/TargetInstrInfo.h > llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp > llvm/trunk/lib/CodeGen/MachineLICM.cpp > llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > llvm/trunk/lib/Target/X86/X86InstrInfo.h > > Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=44702&r1=44701&r2=44702&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Sat Dec 8 > 01:17:56 2007 > @@ -288,24 +288,24 @@ > return get(Opcode).Flags & M_HAS_OPTIONAL_DEF; > } > > - /// isTriviallyReMaterializable - Return true if the instruction > is trivially > + /// hasNoSideEffects - Return true if the instruction is trivially > /// rematerializable, meaning it has no side effects and requires > no operands > /// that aren't always available. > - bool isTriviallyReMaterializable(MachineInstr *MI) const { > + bool hasNoSideEffects(MachineInstr *MI) const { > return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) && > - isReallyTriviallyReMaterializable(MI); > + isTriviallyReMaterializable(MI); > } > > protected: > - /// isReallyTriviallyReMaterializable - For instructions with > opcodes for > - /// which the M_REMATERIALIZABLE flag is set, this function tests > whether the > - /// instruction itself is actually trivially rematerializable, > considering > - /// its operands. This is used for targets that have > instructions that are > - /// only trivially rematerializable for specific uses. This > predicate must > - /// return false if the instruction has any side effects other than > - /// producing a value, or if it requres any address registers > that are not > - /// always available. > - virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) > const { > + /// isTriviallyReMaterializable - For instructions with opcodes > for which the > + /// M_REMATERIALIZABLE flag is set, this function tests whether the > + /// instruction itself is actually trivially rematerializable, > considering its > + /// operands. This is used for targets that have instructions > that are only > + /// trivially rematerializable for specific uses. This predicate > must return > + /// false if the instruction has any side effects other than > producing a > + /// value, or if it requres any address registers that are not > always > + /// available. > + virtual bool isTriviallyReMaterializable(MachineInstr *MI) const { > return true; > } > > > Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44702&r1=44701&r2=44702&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) > +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Sat Dec 8 > 01:17:56 2007 > @@ -613,7 +613,7 @@ > return false; > > isLoad = false; > - if (tii_->isTriviallyReMaterializable(MI)) { > + if (tii_->hasNoSideEffects(MI)) { > isLoad = MI->getInstrDescriptor()->Flags & M_LOAD_FLAG; > return true; > } > > Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=44702&r1=44701&r2=44702&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) > +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Sat Dec 8 01:17:56 2007 > @@ -120,7 +120,7 @@ > if (TID->ImplicitUses || !I.getNumOperands()) return false; > > MachineOpCode Opcode = TID->Opcode; > - return TII->isTriviallyReMaterializable(&I) && > + return TII->hasNoSideEffects(&I) && > // FIXME: Below necessary? > !(TII->isReturn(Opcode) || > TII->isTerminatorInstr(Opcode) || > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=44702&r1=44701&r2=44702&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Dec 8 01:17:56 > 2007 > @@ -116,7 +116,7 @@ > } > > > -bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr > *MI) const { > +bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) > const { > switch (MI->getOpcode()) { > default: break; > case X86::MOV8rm: > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=44702&r1=44701&r2=44702&view=diff > > === > === > === > ===================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Sat Dec 8 01:17:56 2007 > @@ -239,7 +239,7 @@ > unsigned& destReg) const; > unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) > const; > unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) > const; > - bool isReallyTriviallyReMaterializable(MachineInstr *MI) const; > + bool isTriviallyReMaterializable(MachineInstr *MI) const; > > /// convertToThreeAddress - This method must be implemented by > targets that > /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, > the target > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Sat Dec 8 15:59:32 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 21:59:32 -0000 Subject: [llvm-commits] [llvm] r44719 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Message-ID: <200712082159.lB8LxWEd014288@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 15:59:32 2007 New Revision: 44719 URL: http://llvm.org/viewvc/llvm-project?rev=44719&view=rev Log: reorganize header to separate into functional blocks. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44719&r1=44718&r2=44719&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 15:59:32 2007 @@ -125,6 +125,15 @@ void RemapNode(SDOperand &N); + // Common routines. + SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); + SDOperand HandleMemIntrinsic(SDNode *N); + void SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); + + //===--------------------------------------------------------------------===// + // Promotion Support: LegalizeTypesPromote.cpp + //===--------------------------------------------------------------------===// + SDOperand GetPromotedOp(SDOperand Op) { SDOperand &PromotedOp = PromotedNodes[Op]; RemapNode(PromotedOp); @@ -132,7 +141,7 @@ return PromotedOp; } void SetPromotedOp(SDOperand Op, SDOperand Result); - + /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final /// size. SDOperand GetPromotedZExtOp(SDOperand Op) { @@ -140,23 +149,7 @@ Op = GetPromotedOp(Op); return DAG.getZeroExtendInReg(Op, OldVT); } - - void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); - void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi); - - SDOperand GetScalarizedOp(SDOperand Op) { - SDOperand &ScalarOp = ScalarizedNodes[Op]; - RemapNode(ScalarOp); - assert(ScalarOp.Val && "Operand wasn't scalarized?"); - return ScalarOp; - } - void SetScalarizedOp(SDOperand Op, SDOperand Result); - - // Common routines. - SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); - SDOperand HandleMemIntrinsic(SDNode *N); - void SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); - + // Result Promotion. void PromoteResult(SDNode *N, unsigned ResNo); SDOperand PromoteResult_UNDEF(SDNode *N); @@ -176,6 +169,30 @@ SDOperand PromoteResult_SELECT (SDNode *N); SDOperand PromoteResult_SELECT_CC(SDNode *N); + // Operand Promotion. + bool PromoteOperand(SDNode *N, unsigned OperandNo); + SDOperand PromoteOperand_ANY_EXTEND(SDNode *N); + SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N); + SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N); + SDOperand PromoteOperand_TRUNCATE(SDNode *N); + SDOperand PromoteOperand_FP_EXTEND(SDNode *N); + SDOperand PromoteOperand_FP_ROUND(SDNode *N); + SDOperand PromoteOperand_INT_TO_FP(SDNode *N); + SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo); + + void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code); + + //===--------------------------------------------------------------------===// + // Expansion Support: LegalizeTypesExpand.cpp + //===--------------------------------------------------------------------===// + + void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); + void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi); + // Result Expansion. void ExpandResult(SDNode *N, unsigned ResNo); void ExpandResult_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi); @@ -203,34 +220,6 @@ SDOperand &Lo, SDOperand &Hi); bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi); - // Result Vector Scalarization: <1 x ty> -> ty. - void ScalarizeResult(SDNode *N, unsigned OpNo); - SDOperand ScalarizeRes_UNDEF(SDNode *N); - SDOperand ScalarizeRes_LOAD(LoadSDNode *N); - SDOperand ScalarizeRes_BinOp(SDNode *N); - SDOperand ScalarizeRes_UnaryOp(SDNode *N); - SDOperand ScalarizeRes_FPOWI(SDNode *N); - SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N); - SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N); - SDOperand ScalarizeRes_SELECT(SDNode *N); - - // Operand Promotion. - bool PromoteOperand(SDNode *N, unsigned OperandNo); - SDOperand PromoteOperand_ANY_EXTEND(SDNode *N); - SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N); - SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N); - SDOperand PromoteOperand_TRUNCATE(SDNode *N); - SDOperand PromoteOperand_FP_EXTEND(SDNode *N); - SDOperand PromoteOperand_FP_ROUND(SDNode *N); - SDOperand PromoteOperand_INT_TO_FP(SDNode *N); - SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo); - SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo); - - void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code); - // Operand Expansion. bool ExpandOperand(SDNode *N, unsigned OperandNo); SDOperand ExpandOperand_TRUNCATE(SDNode *N); @@ -240,10 +229,33 @@ SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N); SDOperand ExpandOperand_SETCC(SDNode *N); SDOperand ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo); - + void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, ISD::CondCode &CCCode); + //===--------------------------------------------------------------------===// + // Scalarization Support: LegalizeTypesScalarize.cpp + //===--------------------------------------------------------------------===// + + SDOperand GetScalarizedOp(SDOperand Op) { + SDOperand &ScalarOp = ScalarizedNodes[Op]; + RemapNode(ScalarOp); + assert(ScalarOp.Val && "Operand wasn't scalarized?"); + return ScalarOp; + } + void SetScalarizedOp(SDOperand Op, SDOperand Result); + + // Result Vector Scalarization: <1 x ty> -> ty. + void ScalarizeResult(SDNode *N, unsigned OpNo); + SDOperand ScalarizeRes_UNDEF(SDNode *N); + SDOperand ScalarizeRes_LOAD(LoadSDNode *N); + SDOperand ScalarizeRes_BinOp(SDNode *N); + SDOperand ScalarizeRes_UnaryOp(SDNode *N); + SDOperand ScalarizeRes_FPOWI(SDNode *N); + SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N); + SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N); + SDOperand ScalarizeRes_SELECT(SDNode *N); + // Operand Vector Scalarization: <1 x ty> -> ty. bool ScalarizeOperand(SDNode *N, unsigned OpNo); SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); From sabre at nondot.org Sat Dec 8 16:17:34 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 22:17:34 -0000 Subject: [llvm-commits] [llvm] r44720 - /llvm/trunk/lib/System/Unix/SUS/ Message-ID: <200712082217.lB8MHYhT015016@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 16:17:33 2007 New Revision: 44720 URL: http://llvm.org/viewvc/llvm-project?rev=44720&view=rev Log: Remove dead file and directory. Removed: llvm/trunk/lib/System/Unix/SUS/ From natebegeman at mac.com Sat Dec 8 16:29:25 2007 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 08 Dec 2007 22:29:25 -0000 Subject: [llvm-commits] [llvm] r44721 - /llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200712082229.lB8MTPoi015568@zion.cs.uiuc.edu> Author: sampo Date: Sat Dec 8 16:29:19 2007 New Revision: 44721 URL: http://llvm.org/viewvc/llvm-project?rev=44721&view=rev Log: Project cleanups Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj?rev=44721&r1=44720&r2=44721&view=diff ============================================================================== --- llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj (original) +++ llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Sat Dec 8 16:29:19 2007 @@ -631,7 +631,6 @@ DE66EE8408ABEE3500323D32 /* Program.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Program.inc; sourceTree = ""; }; DE66EE8508ABEE3500323D32 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = ""; }; DE66EE8608ABEE3500323D32 /* Signals.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Signals.inc; sourceTree = ""; }; - DE66EE8808ABEE3500323D32 /* Process.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Process.cpp; sourceTree = ""; }; DE66EE8908ABEE3500323D32 /* TimeValue.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TimeValue.inc; sourceTree = ""; }; DE66EE8A08ABEE3500323D32 /* Unix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Unix.h; sourceTree = ""; }; DE66EE8C08ABEE3500323D32 /* DynamicLibrary.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DynamicLibrary.inc; sourceTree = ""; }; @@ -1088,10 +1087,18 @@ DE66F38C08ABF35300323D32 /* CREDITS.TXT */, CFD99AA80AFE827B0068D19C /* LICENSE.TXT */, CFD99AAD0AFE827B0068D19C /* README.txt */, + 721CA1750D0B44D200D5004F /* Products */, ); name = LLVM; sourceTree = ""; }; + 721CA1750D0B44D200D5004F /* Products */ = { + isa = PBXGroup; + children = ( + ); + name = Products; + sourceTree = ""; + }; 9F68EB030C77AD2C004AA152 /* lib/Bitcode */ = { isa = PBXGroup; children = ( @@ -1683,21 +1690,12 @@ DE66EE8408ABEE3500323D32 /* Program.inc */, DE66EE8508ABEE3500323D32 /* README.txt */, DE66EE8608ABEE3500323D32 /* Signals.inc */, - DE66EE8708ABEE3500323D32 /* SUS */, DE66EE8908ABEE3500323D32 /* TimeValue.inc */, DE66EE8A08ABEE3500323D32 /* Unix.h */, ); path = Unix; sourceTree = ""; }; - DE66EE8708ABEE3500323D32 /* SUS */ = { - isa = PBXGroup; - children = ( - DE66EE8808ABEE3500323D32 /* Process.cpp */, - ); - path = SUS; - sourceTree = ""; - }; DE66EE8B08ABEE3500323D32 /* Win32 */ = { isa = PBXGroup; children = ( @@ -2735,7 +2733,7 @@ buildPhases = ( ); buildToolPath = /usr/bin/make; - buildWorkingDirectory = /llvm/llvm/utils/TableGen; + buildWorkingDirectory = "${SRCROOT}/../utils/TableGen"; dependencies = ( ); name = "LLVM TableGen"; @@ -2777,7 +2775,7 @@ buildPhases = ( ); buildToolPath = /usr/bin/make; - buildWorkingDirectory = /Volumes/Big2/llvm/llvm; + buildWorkingDirectory = "$(SRCROOT)/../"; dependencies = ( ); name = LLVM; @@ -2793,6 +2791,7 @@ compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* LLVM */; + productRefGroup = 721CA1750D0B44D200D5004F /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( @@ -2870,23 +2869,6 @@ }; name = Release; }; - CF0329BA08D1BE530030FD33 /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM lib"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; CF0329C408D1BEC40030FD33 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2925,23 +2907,6 @@ }; name = Release; }; - CF0329C608D1BEC40030FD33 /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM llc"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; CF0329C808D1BEC40030FD33 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2980,23 +2945,6 @@ }; name = Release; }; - CF0329CA08D1BEC40030FD33 /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM full llc"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; CF490E850907CDAB0072DB1C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3035,23 +2983,6 @@ }; name = Release; }; - CF490E870907CDAB0072DB1C /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM llc"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; CFDF86BF0ADE819D00D40A3D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3090,23 +3021,6 @@ }; name = Release; }; - CFDF86C10ADE819D00D40A3D /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM lib"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; CFDF86C80ADE81D000D40A3D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3145,23 +3059,6 @@ }; name = Release; }; - CFDF86CA0ADE81D000D40A3D /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM llc"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; CFDF86D60ADE820000D40A3D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3200,23 +3097,6 @@ }; name = Release; }; - CFDF86D80ADE820000D40A3D /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "LLVM full llc"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Default; - }; DE66EC4D08ABE78900323D32 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3247,33 +3127,23 @@ }; name = Release; }; - DE66EC4F08ABE78900323D32 /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - PRODUCT_NAME = LLVM; - }; - name = Default; - }; DE66EC5108ABE78900323D32 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_OPTIMIZATION_LEVEL = 0; + USER_HEADER_SEARCH_PATHS = "../include/**"; }; name = Debug; }; DE66EC5208ABE78900323D32 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + USER_HEADER_SEARCH_PATHS = "../include/**"; }; name = Release; }; - DE66EC5308ABE78900323D32 /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Default; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -3282,90 +3152,81 @@ buildConfigurations = ( CF0329B808D1BE530030FD33 /* Debug */, CF0329B908D1BE530030FD33 /* Release */, - CF0329BA08D1BE530030FD33 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; CF0329C308D1BEC40030FD33 /* Build configuration list for PBXLegacyTarget "LLVM llc" */ = { isa = XCConfigurationList; buildConfigurations = ( CF0329C408D1BEC40030FD33 /* Debug */, CF0329C508D1BEC40030FD33 /* Release */, - CF0329C608D1BEC40030FD33 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; CF0329C708D1BEC40030FD33 /* Build configuration list for PBXAggregateTarget "LLVM full llc" */ = { isa = XCConfigurationList; buildConfigurations = ( CF0329C808D1BEC40030FD33 /* Debug */, CF0329C908D1BEC40030FD33 /* Release */, - CF0329CA08D1BEC40030FD33 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; CF490E840907CDAB0072DB1C /* Build configuration list for PBXLegacyTarget "LLVM TableGen" */ = { isa = XCConfigurationList; buildConfigurations = ( CF490E850907CDAB0072DB1C /* Debug */, CF490E860907CDAB0072DB1C /* Release */, - CF490E870907CDAB0072DB1C /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; CFDF86BE0ADE819D00D40A3D /* Build configuration list for PBXLegacyTarget "LLVM lib release" */ = { isa = XCConfigurationList; buildConfigurations = ( CFDF86BF0ADE819D00D40A3D /* Debug */, CFDF86C00ADE819D00D40A3D /* Release */, - CFDF86C10ADE819D00D40A3D /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; CFDF86C70ADE81D000D40A3D /* Build configuration list for PBXLegacyTarget "LLVM llc release" */ = { isa = XCConfigurationList; buildConfigurations = ( CFDF86C80ADE81D000D40A3D /* Debug */, CFDF86C90ADE81D000D40A3D /* Release */, - CFDF86CA0ADE81D000D40A3D /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; CFDF86D50ADE820000D40A3D /* Build configuration list for PBXAggregateTarget "LLVM full llc release" */ = { isa = XCConfigurationList; buildConfigurations = ( CFDF86D60ADE820000D40A3D /* Debug */, CFDF86D70ADE820000D40A3D /* Release */, - CFDF86D80ADE820000D40A3D /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; DE66EC4C08ABE78900323D32 /* Build configuration list for PBXLegacyTarget "LLVM" */ = { isa = XCConfigurationList; buildConfigurations = ( DE66EC4D08ABE78900323D32 /* Debug */, DE66EC4E08ABE78900323D32 /* Release */, - DE66EC4F08ABE78900323D32 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; DE66EC5008ABE78900323D32 /* Build configuration list for PBXProject "LLVM" */ = { isa = XCConfigurationList; buildConfigurations = ( DE66EC5108ABE78900323D32 /* Debug */, DE66EC5208ABE78900323D32 /* Release */, - DE66EC5308ABE78900323D32 /* Default */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; From wmatyjewicz at fastmail.fm Sat Dec 8 16:35:28 2007 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Sat, 08 Dec 2007 23:35:28 +0100 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) Message-ID: <475B1C30.5020800@fastmail.fm> Hi, It seems that this problem is caused by a copy-paste bug in BasicAliasAnalysis.cpp. The first part of the diff is of a cosmetic nature. The second fixes the bug. -Wojtek -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: PR1782.diff Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071208/dd8bb4ef/attachment.pl From sabre at nondot.org Sat Dec 8 16:37:41 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 22:37:41 -0000 Subject: [llvm-commits] [llvm] r44722 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypes.h LegalizeTypesSplit.cpp Message-ID: <200712082237.lB8Mbgcj016118@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 16:37:41 2007 New Revision: 44722 URL: http://llvm.org/viewvc/llvm-project?rev=44722&view=rev Log: add scaffolding for splitting of vectors. Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=44722&r1=44721&r2=44722&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sat Dec 8 16:37:41 2007 @@ -68,8 +68,8 @@ ExpandResult(N, i); else if (MVT::getVectorNumElements(ResultVT) == 1) ScalarizeResult(N, i); // Scalarize the single-element vector. - else // Split the vector in half. - assert(0 && "Vector splitting not implemented"); + else + SplitResult(N, i); // Split the vector in half. goto NodeDone; } else { assert(Action == Legal && "Unknown action!"); @@ -96,8 +96,7 @@ // Scalarize the single-element vector. NeedsRevisit = ScalarizeOperand(N, i); } else { - // Split the vector in half. - assert(0 && "Vector splitting not implemented"); + NeedsRevisit = SplitOperand(N, i); // Split the vector in half. } break; } else { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44722&r1=44721&r2=44722&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 16:37:41 2007 @@ -260,6 +260,19 @@ bool ScalarizeOperand(SDNode *N, unsigned OpNo); SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); + //===--------------------------------------------------------------------===// + // Vector Splitting Support: LegalizeTypesSplit.cpp + //===--------------------------------------------------------------------===// + + void GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); + void SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi); + + // Result Vector Splitting: <128 x ty> -> 2 x <64 x ty>. + void SplitResult(SDNode *N, unsigned OpNo); + + // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. + bool SplitOperand(SDNode *N, unsigned OpNo); + }; } // end namespace llvm. Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=44722&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (added) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Sat Dec 8 16:37:41 2007 @@ -0,0 +1,122 @@ +//===-- LegalizeTypesSplit.cpp - Vector Splitting for LegalizeTypes -------===// +// +// 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 vector splitting support for LegalizeTypes. Vector +// splitting is the act of changing a computation in an invalid vector type to +// be a computation in multiple vectors of a smaller type. For example, +// implementing <128 x f32> operations in terms of two <64 x f32> operations. +// +//===----------------------------------------------------------------------===// + +#include "LegalizeTypes.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Result Vector Splitting +//===----------------------------------------------------------------------===// + +/// SplitResult - This method is called when the specified result of the +/// specified node is found to need vector splitting. At this point, the node +/// may also have invalid operands or may have other results that need +/// legalization, we just know that (at least) one result needs vector +/// splitting. +void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { + DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); + SDOperand Lo, Hi; + Lo = Hi = SDOperand(); + +#if 0 + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } +#endif + + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "SplitResult #" << ResNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to split the result of this operator!"); + abort(); + +#if 0 + case ISD::UNDEF: SplitResult_UNDEF(N, Lo, Hi); break; +#endif + } + + // If Lo/Hi is null, the sub-method took care of registering results etc. + if (Lo.Val) + SetSplitOp(SDOperand(N, ResNo), Lo, Hi); +} + + +//===----------------------------------------------------------------------===// +// Operand Vector Splitting +//===----------------------------------------------------------------------===// + +/// SplitOperand - This method is called when the specified operand of the +/// specified node is found to need vector splitting. At this point, all of the +/// result types of the node are known to be legal, but other operands of the +/// node may need legalization as well as the specified one. +bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) { + DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n"); + SDOperand Res(0, 0); + +#if 0 + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, 0), DAG); +#endif + + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "SplitOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to split this operator's operand!"); + abort(); +#if 0 + case ISD::STORE: + Res = ExpandOperand_STORE(cast(N), OpNo); + break; +#endif + } + } + + // If the result is null, the sub-method took care of registering results etc. + if (!Res.Val) return false; + + // If the result is N, the sub-method updated N in place. Check to see if any + // operands are new, and if so, mark them. + if (Res.Val == N) { + // Mark N as new and remark N and its operands. This allows us to correctly + // revisit N if it needs another step of promotion and allows us to visit + // any new operands to N. + N->setNodeId(NewNode); + MarkNewNodes(N); + return true; + } + + assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + "Invalid operand expansion"); + + ReplaceValueWith(SDOperand(N, 0), Res); + return false; +} From sabre at nondot.org Sat Dec 8 16:40:18 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 22:40:18 -0000 Subject: [llvm-commits] [llvm] r44723 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypes.h Message-ID: <200712082240.lB8MeI1f016355@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 16:40:18 2007 New Revision: 44723 URL: http://llvm.org/viewvc/llvm-project?rev=44723&view=rev Log: implement some methods. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=44723&r1=44722&r2=44723&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sat Dec 8 16:40:18 2007 @@ -320,8 +320,7 @@ Hi = Entry.second; } -void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, - SDOperand Hi) { +void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi) { // Remember that this is the result of the node. std::pair &Entry = ExpandedNodes[Op]; assert(Entry.first.Val == 0 && "Node already expanded"); @@ -335,6 +334,30 @@ MarkNewNodes(Hi.Val); } +void DAGTypeLegalizer::GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { + std::pair &Entry = SplitNodes[Op]; + RemapNode(Entry.first); + RemapNode(Entry.second); + assert(Entry.first.Val && "Operand isn't split"); + Lo = Entry.first; + Hi = Entry.second; +} + +void DAGTypeLegalizer::SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi) { + // Remember that this is the result of the node. + std::pair &Entry = SplitNodes[Op]; + assert(Entry.first.Val == 0 && "Node already split"); + Entry.first = Lo; + Entry.second = Hi; + + // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant. + if (Lo.Val->getNodeId() == NewNode) + MarkNewNodes(Lo.Val); + if (Hi.Val->getNodeId() == NewNode) + MarkNewNodes(Hi.Val); +} + + SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT) { // Create the stack frame object. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44723&r1=44722&r2=44723&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 16:40:18 2007 @@ -97,6 +97,10 @@ /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the /// scalar value of type 'ty' to use. DenseMap ScalarizedNodes; + + /// SplitNodes - For nodes that need to be split this map indicates + /// which operands are the expanded version of the input. + DenseMap > SplitNodes; /// ReplacedNodes - For nodes that have been replaced with another, /// indicates the replacement node to use. From sabre at nondot.org Sat Dec 8 17:08:49 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 23:08:49 -0000 Subject: [llvm-commits] [llvm] r44724 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeTypesSplit.cpp Message-ID: <200712082308.lB8N8oU5018993@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 17:08:49 2007 New Revision: 44724 URL: http://llvm.org/viewvc/llvm-project?rev=44724&view=rev Log: implement vector splitting of load, undef, and binops. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44724&r1=44723&r2=44724&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 17:08:49 2007 @@ -273,6 +273,10 @@ // Result Vector Splitting: <128 x ty> -> 2 x <64 x ty>. void SplitResult(SDNode *N, unsigned OpNo); + + void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi); // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=44724&r1=44723&r2=44724&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Sat Dec 8 17:08:49 2007 @@ -17,6 +17,24 @@ #include "LegalizeTypes.h" using namespace llvm; +/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector +/// type that needs to be split. This handles non-power of two vectors. +static void GetSplitDestVTs(MVT::ValueType InVT, + MVT::ValueType &Lo, MVT::ValueType &Hi) { + MVT::ValueType NewEltVT = MVT::getVectorElementType(InVT); + unsigned NumElements = MVT::getVectorNumElements(InVT); + if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector. + NumElements >>= 1; + Lo = Hi = MVT::getVectorType(NewEltVT, NumElements); + } else { // Non-power-of-two vectors. + unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1); + unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; + Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo); + Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi); + } +} + + //===----------------------------------------------------------------------===// // Result Vector Splitting //===----------------------------------------------------------------------===// @@ -29,7 +47,6 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); SDOperand Lo, Hi; - Lo = Hi = SDOperand(); #if 0 // See if the target wants to custom expand this node. @@ -54,9 +71,24 @@ assert(0 && "Do not know how to split the result of this operator!"); abort(); -#if 0 - case ISD::UNDEF: SplitResult_UNDEF(N, Lo, Hi); break; -#endif + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + case ISD::LOAD: SplitRes_LOAD(cast(N), Lo, Hi); break; + case ISD::ADD: + case ISD::SUB: + case ISD::MUL: + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::FDIV: + case ISD::FPOW: + case ISD::AND: + case ISD::OR: + case ISD::XOR: + case ISD::UREM: + case ISD::SREM: + case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -64,6 +96,54 @@ SetSplitOp(SDOperand(N, ResNo), Lo, Hi); } +void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + + Lo = DAG.getNode(ISD::UNDEF, LoVT); + Hi = DAG.getNode(ISD::UNDEF, HiVT); +} + +void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD, + SDOperand &Lo, SDOperand &Hi) { + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT); + + SDOperand Ch = LD->getChain(); + SDOperand Ptr = LD->getBasePtr(); + const Value *SV = LD->getSrcValue(); + int SVOffset = LD->getSrcValueOffset(); + unsigned Alignment = LD->getAlignment(); + bool isVolatile = LD->isVolatile(); + + Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); + unsigned IncrementSize = MVT::getSizeInBits(LoVT)/8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + SVOffset += IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); + Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); + + // Build a factor node to remember that this load is independent of the + // other one. + SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(LD, 1), TF); +} + +void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + SDOperand LHSLo, LHSHi; + GetSplitOp(N->getOperand(0), LHSLo, LHSHi); + SDOperand RHSLo, RHSHi; + GetSplitOp(N->getOperand(1), RHSLo, RHSHi); + + Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo); + Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi); +} + //===----------------------------------------------------------------------===// // Operand Vector Splitting From sabre at nondot.org Sat Dec 8 17:24:28 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 23:24:28 -0000 Subject: [llvm-commits] [llvm] r44725 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeTypesSplit.cpp Message-ID: <200712082324.lB8NOSUt020113@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 17:24:26 2007 New Revision: 44725 URL: http://llvm.org/viewvc/llvm-project?rev=44725&view=rev Log: Implement splitting support for store, allowing us to compile: %f8 = type <8 x float> define void @test_f8(%f8* %P, %f8* %Q, %f8* %S) { %p = load %f8* %P ; <%f8> [#uses=1] %q = load %f8* %Q ; <%f8> [#uses=1] %R = add %f8 %p, %q ; <%f8> [#uses=1] store %f8 %R, %f8* %S ret void } into: _test_f8: movaps 16(%rdi), %xmm0 addps 16(%rsi), %xmm0 movaps (%rdi), %xmm1 addps (%rsi), %xmm1 movaps %xmm0, 16(%rdx) movaps %xmm1, (%rdx) ret Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44725&r1=44724&r2=44725&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 17:24:26 2007 @@ -281,6 +281,7 @@ // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); + SDOperand SplitOperand_STORE(StoreSDNode *N, unsigned OpNo); }; } // end namespace llvm. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=44725&r1=44724&r2=44725&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Sat Dec 8 17:24:26 2007 @@ -172,11 +172,9 @@ #endif assert(0 && "Do not know how to split this operator's operand!"); abort(); -#if 0 case ISD::STORE: - Res = ExpandOperand_STORE(cast(N), OpNo); + Res = SplitOperand_STORE(cast(N), OpNo); break; -#endif } } @@ -200,3 +198,28 @@ ReplaceValueWith(SDOperand(N, 0), Res); return false; } + +SDOperand DAGTypeLegalizer::SplitOperand_STORE(StoreSDNode *N, unsigned OpNo) { + assert(OpNo == 1 && "Can only split the stored value"); + + SDOperand Ch = N->getChain(); + SDOperand Ptr = N->getBasePtr(); + int SVOffset = N->getSrcValueOffset(); + unsigned Alignment = N->getAlignment(); + bool isVol = N->isVolatile(); + SDOperand Lo, Hi; + GetSplitOp(N->getOperand(1), Lo, Hi); + + unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8; + + Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, isVol, Alignment); + + // Increment the pointer to the other half. + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + + Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, + isVol, MinAlign(Alignment, IncrementSize)); + return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); +} + From sabre at nondot.org Sat Dec 8 17:58:27 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 08 Dec 2007 23:58:27 -0000 Subject: [llvm-commits] [llvm] r44726 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeTypesSplit.cpp Message-ID: <200712082358.lB8NwR8O022098@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 17:58:27 2007 New Revision: 44726 URL: http://llvm.org/viewvc/llvm-project?rev=44726&view=rev Log: add many new cases to SplitResult. SplitResult now handles all the cases that LegalizeDAG does. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44726&r1=44725&r2=44726&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 17:58:27 2007 @@ -276,7 +276,17 @@ void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi); void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, SDOperand &Hi); + + void SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi); void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi); // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=44726&r1=44725&r2=44726&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Sat Dec 8 17:58:27 2007 @@ -71,8 +71,26 @@ assert(0 && "Do not know how to split the result of this operator!"); abort(); - case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; - case ISD::LOAD: SplitRes_LOAD(cast(N), Lo, Hi); break; + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + case ISD::LOAD: SplitRes_LOAD(cast(N), Lo, Hi); break; + case ISD::BUILD_PAIR: SplitRes_BUILD_PAIR(N, Lo, Hi); break; + case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; + case ISD::VECTOR_SHUFFLE: SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break; + case ISD::BUILD_VECTOR: SplitRes_BUILD_VECTOR(N, Lo, Hi); break; + case ISD::CONCAT_VECTORS: SplitRes_CONCAT_VECTORS(N, Lo, Hi); break; + case ISD::BIT_CONVERT: SplitRes_BIT_CONVERT(N, Lo, Hi); break; + case ISD::CTTZ: + case ISD::CTLZ: + case ISD::CTPOP: + case ISD::FNEG: + case ISD::FABS: + case ISD::FSQRT: + case ISD::FSIN: + case ISD::FCOS: + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: SplitRes_UnOp(N, Lo, Hi); break; case ISD::ADD: case ISD::SUB: case ISD::MUL: @@ -88,7 +106,9 @@ case ISD::XOR: case ISD::UREM: case ISD::SREM: - case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break; + case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break; + case ISD::FPOWI: SplitRes_FPOWI(N, Lo, Hi); break; + case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -134,6 +154,124 @@ ReplaceValueWith(SDOperand(LD, 1), TF); } +void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + Lo = N->getOperand(0); + Hi = N->getOperand(1); +} + +void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + GetSplitOp(N->getOperand(0), Lo, Hi); + unsigned Index = cast(N->getOperand(2))->getValue(); + SDOperand ScalarOp = N->getOperand(1); + unsigned LoNumElts = MVT::getVectorNumElements(Lo.getValueType()); + if (Index < LoNumElts) + Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, ScalarOp, + N->getOperand(2)); + else + Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, ScalarOp, + DAG.getConstant(Index - LoNumElts, TLI.getPointerTy())); + +} + +void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Build the low part. + SDOperand Mask = N->getOperand(2); + SmallVector Ops; + MVT::ValueType PtrVT = TLI.getPointerTy(); + + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + MVT::ValueType EltVT = MVT::getVectorElementType(LoVT); + unsigned LoNumElts = MVT::getVectorNumElements(LoVT); + unsigned NumElements = Mask.getNumOperands(); + + // Insert all of the elements from the input that are needed. We use + // buildvector of extractelement here because the input vectors will have + // to be legalized, so this makes the code simpler. + for (unsigned i = 0; i != LoNumElts; ++i) { + unsigned Idx = cast(Mask.getOperand(i))->getValue(); + SDOperand InVec = N->getOperand(0); + if (Idx >= NumElements) { + InVec = N->getOperand(1); + Idx -= NumElements; + } + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec, + DAG.getConstant(Idx, PtrVT))); + } + Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size()); + Ops.clear(); + + for (unsigned i = LoNumElts; i != NumElements; ++i) { + unsigned Idx = cast(Mask.getOperand(i))->getValue(); + SDOperand InVec = N->getOperand(0); + if (Idx >= NumElements) { + InVec = N->getOperand(1); + Idx -= NumElements; + } + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec, + DAG.getConstant(Idx, PtrVT))); + } + Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size()); +} + +void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + unsigned LoNumElts = MVT::getVectorNumElements(LoVT); + SmallVector LoOps(N->op_begin(), N->op_begin()+LoNumElts); + Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size()); + + SmallVector HiOps(N->op_begin()+LoNumElts, N->op_end()); + Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size()); +} + +void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // FIXME: Handle non-power-of-two vectors? + unsigned NumSubvectors = N->getNumOperands() / 2; + if (NumSubvectors == 1) { + Lo = N->getOperand(0); + Hi = N->getOperand(1); + return; + } + + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + + SmallVector LoOps(N->op_begin(), N->op_begin()+NumSubvectors); + Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size()); + + SmallVector HiOps(N->op_begin()+NumSubvectors, N->op_end()); + Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size()); +} + +void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // We know the result is a vector. The input may be either a vector or a + // scalar value. + SDOperand InOp = N->getOperand(0); + if (MVT::isVector(InOp.getValueType()) && + MVT::getVectorNumElements(InOp.getValueType()) != 1) { + // If this is a vector, split the vector and convert each of the pieces now. + GetSplitOp(InOp, Lo, Hi); + + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + + Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi); + return; + } + + // Lower the bit-convert to a store/load from the stack, then split the load. + SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); + SplitRes_LOAD(cast(Op.Val), Lo, Hi); +} + void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { SDOperand LHSLo, LHSHi; GetSplitOp(N->getOperand(0), LHSLo, LHSHi); @@ -144,6 +282,33 @@ Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi); } +void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + // Get the dest types. This doesn't always match input types, e.g. int_to_fp. + MVT::ValueType LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + + GetSplitOp(N->getOperand(0), Lo, Hi); + Lo = DAG.getNode(N->getOpcode(), LoVT, Lo); + Hi = DAG.getNode(N->getOpcode(), HiVT, Hi); +} + +void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + GetSplitOp(N->getOperand(0), Lo, Hi); + Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1)); + Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1)); +} + + +void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){ + SDOperand LL, LH, RL, RH; + GetSplitOp(N->getOperand(1), LL, LH); + GetSplitOp(N->getOperand(2), RL, RH); + + SDOperand Cond = N->getOperand(0); + Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL); + Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH); +} + //===----------------------------------------------------------------------===// // Operand Vector Splitting From isanbard at gmail.com Sat Dec 8 17:58:46 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 08 Dec 2007 23:58:46 -0000 Subject: [llvm-commits] [llvm] r44727 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineLICM.cpp lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h tools/Makefile utils/emacs/tablegen-mode.el Message-ID: <200712082358.lB8NwlfG022124@zion.cs.uiuc.edu> Author: void Date: Sat Dec 8 17:58:46 2007 New Revision: 44727 URL: http://llvm.org/viewvc/llvm-project?rev=44727&view=rev Log: Reverting 44702. It wasn't correct to rename them. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h llvm/trunk/tools/Makefile llvm/trunk/utils/emacs/tablegen-mode.el Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Sat Dec 8 17:58:46 2007 @@ -288,24 +288,24 @@ return get(Opcode).Flags & M_HAS_OPTIONAL_DEF; } - /// hasNoSideEffects - Return true if the instruction is trivially + /// isTriviallyReMaterializable - Return true if the instruction is trivially /// rematerializable, meaning it has no side effects and requires no operands /// that aren't always available. - bool hasNoSideEffects(MachineInstr *MI) const { + bool isTriviallyReMaterializable(MachineInstr *MI) const { return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) && - isTriviallyReMaterializable(MI); + isReallyTriviallyReMaterializable(MI); } protected: - /// isTriviallyReMaterializable - For instructions with opcodes for which the - /// M_REMATERIALIZABLE flag is set, this function tests whether the - /// instruction itself is actually trivially rematerializable, considering its - /// operands. This is used for targets that have instructions that are only - /// trivially rematerializable for specific uses. This predicate must return - /// false if the instruction has any side effects other than producing a - /// value, or if it requres any address registers that are not always - /// available. - virtual bool isTriviallyReMaterializable(MachineInstr *MI) const { + /// isReallyTriviallyReMaterializable - For instructions with opcodes for + /// which the M_REMATERIALIZABLE flag is set, this function tests whether the + /// instruction itself is actually trivially rematerializable, considering + /// its operands. This is used for targets that have instructions that are + /// only trivially rematerializable for specific uses. This predicate must + /// return false if the instruction has any side effects other than + /// producing a value, or if it requres any address registers that are not + /// always available. + virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const { return true; } Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Sat Dec 8 17:58:46 2007 @@ -613,7 +613,7 @@ return false; isLoad = false; - if (tii_->hasNoSideEffects(MI)) { + if (tii_->isTriviallyReMaterializable(MI)) { isLoad = MI->getInstrDescriptor()->Flags & M_LOAD_FLAG; return true; } Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Sat Dec 8 17:58:46 2007 @@ -39,7 +39,7 @@ cl::desc("Perform loop-invariant code motion on machine code")); } -STATISTIC(NumHoisted, "Number of machine instructions hoisted out of loop"); +STATISTIC(NumHoisted, "Number of machine instructions hoisted out of loops"); namespace { class VISIBILITY_HIDDEN MachineLICM : public MachineFunctionPass { @@ -93,11 +93,11 @@ /// void MapVirtualRegisterDefs(const MachineFunction &MF); - /// isInSubLoop - A little predicate that returns true if the specified + /// IsInSubLoop - A little predicate that returns true if the specified /// basic block is in a subloop of the current one, not the current one /// itself. /// - bool isInSubLoop(MachineBasicBlock *BB) { + bool IsInSubLoop(MachineBasicBlock *BB) { assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop"); for (MachineLoop::iterator @@ -120,7 +120,7 @@ if (TID->ImplicitUses || !I.getNumOperands()) return false; MachineOpCode Opcode = TID->Opcode; - return TII->hasNoSideEffects(&I) && + return TII->isTriviallyReMaterializable(&I) && // FIXME: Below necessary? !(TII->isReturn(Opcode) || TII->isTerminatorInstr(Opcode) || @@ -132,12 +132,12 @@ TII->isStore(Opcode)); } - /// isLoopInvariantInst - Returns true if the instruction is loop + /// IsLoopInvariantInst - Returns true if the instruction is loop /// invariant. I.e., all virtual register operands are defined outside of /// the loop, physical registers aren't accessed (explicitly or implicitly), /// and the instruction is hoistable. /// - bool isLoopInvariantInst(MachineInstr &I); + bool IsLoopInvariantInst(MachineInstr &I); /// FindPredecessors - Get all of the predecessors of the loop that are not /// back-edges. @@ -246,7 +246,7 @@ // Only need to process the contents of this block if it is not part of a // subloop (which would already have been processed). - if (!isInSubLoop(BB)) + if (!IsInSubLoop(BB)) for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { MachineInstr &MI = *I++; @@ -263,12 +263,12 @@ HoistRegion(Children[I]); } -/// isLoopInvariantInst - Returns true if the instruction is loop +/// IsLoopInvariantInst - Returns true if the instruction is loop /// invariant. I.e., all virtual register operands are defined outside of the /// loop, physical registers aren't accessed (explicitly or implicitly), and the /// instruction is hoistable. /// -bool MachineLICM::isLoopInvariantInst(MachineInstr &I) { +bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { if (!CanHoistInst(I)) return false; // The instruction is loop invariant if all of its operands are loop-invariant @@ -300,7 +300,7 @@ /// that is safe to hoist, this instruction is called to do the dirty work. /// void MachineLICM::Hoist(MachineInstr &MI) { - if (!isLoopInvariantInst(MI)) return; + if (!IsLoopInvariantInst(MI)) return; std::vector Preds; @@ -316,9 +316,9 @@ // the loop header. MachineBasicBlock *MBB = Preds.front(); - // FIXME: We are assuming at first that the basic blocks coming into this loop - // have only one successor each. This isn't the case in general because we - // haven't broken critical edges or added preheaders. + // FIXME: We are assuming at first that the basic block coming into this loop + // has only one successor. This isn't the case in general because we haven't + // broken critical edges or added preheaders. if (MBB->succ_size() != 1) return; assert(*MBB->succ_begin() == CurLoop->getHeader() && "The predecessor doesn't feed directly into the loop header!"); Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Dec 8 17:58:46 2007 @@ -116,7 +116,7 @@ } -bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const { +bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const { switch (MI->getOpcode()) { default: break; case X86::MOV8rm: Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Sat Dec 8 17:58:46 2007 @@ -239,7 +239,7 @@ unsigned& destReg) const; unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; - bool isTriviallyReMaterializable(MachineInstr *MI) const; + bool isReallyTriviallyReMaterializable(MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target Modified: llvm/trunk/tools/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/tools/Makefile (original) +++ llvm/trunk/tools/Makefile Sat Dec 8 17:58:46 2007 @@ -16,8 +16,8 @@ llc llvm-ranlib llvm-ar llvm-nm \ llvm-ld llvmc llvm-prof llvm-link \ lli gccas gccld llvm-extract llvm-db llvm2cpp \ - bugpoint llvm-bcanalyzer llvm-stub - + bugpoint llvm-bcanalyzer llvm-stub cfe + include $(LEVEL)/Makefile.config Modified: llvm/trunk/utils/emacs/tablegen-mode.el URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/emacs/tablegen-mode.el?rev=44727&r1=44726&r2=44727&view=diff ============================================================================== --- llvm/trunk/utils/emacs/tablegen-mode.el (original) +++ llvm/trunk/utils/emacs/tablegen-mode.el Sat Dec 8 17:58:46 2007 @@ -16,7 +16,7 @@ (defvar tablegen-font-lock-keywords (let ((kw (mapconcat 'identity - '("class" "def" "defm" "field" "in" "include" + '("class" "defm" "def" "field" "include" "in" "let" "multiclass") "\\|")) (type-kw (mapconcat 'identity @@ -49,15 +49,16 @@ ;; ---------------------- Syntax table --------------------------- ;; Shamelessly ripped from jasmin.el -;; URL: http://www.neilvandyke.org/jasmin-emacs/jasmin.el.html +;; URL: http://www.neilvandyke.org/jasmin-emacs/jasmin.el (if (not tablegen-mode-syntax-table) (progn (setq tablegen-mode-syntax-table (make-syntax-table)) - (mapcar (function (lambda (n) - (modify-syntax-entry (aref n 0) - (aref n 1) - tablegen-mode-syntax-table))) + (mapcar (function + (lambda (n) + (modify-syntax-entry (aref n 0) + (aref n 1) + tablegen-mode-syntax-table))) '( ;; whitespace (` ') [?\^m " "] @@ -66,8 +67,6 @@ [?\t " "] [?\ " "] ;; word constituents (`w') - ;;[?< "w"] - ;;[?> "w"] [?\% "w"] ;;[?_ "w "] ;; comments @@ -78,15 +77,17 @@ ;; symbol constituents (`_') ;; punctuation (`.') ;; open paren (`(') - [?\( "("] - [?\[ "("] - [?\{ "("] + [?\( "("] + [?\[ "("] + [?\{ "("] + [?\< "("] ;; close paren (`)') - [?\) ")"] - [?\] ")"] - [?\} ")"] + [?\) ")"] + [?\] ")"] + [?\} ")"] + [?\> ")"] ;; string quote ('"') - [?\" "\""] + [?\" "\""] )))) ;; --------------------- Abbrev table ----------------------------- @@ -101,11 +102,10 @@ (if (not tablegen-mode-map) () ; Do not change the keymap if it is already set up. (setq tablegen-mode-map (make-sparse-keymap)) - (define-key tablegen-mode-map "\t" 'tab-to-tab-stop) + (define-key tablegen-mode-map "\t" 'tab-to-tab-stop) (define-key tablegen-mode-map "\es" 'center-line) (define-key tablegen-mode-map "\eS" 'center-paragraph)) - (defun tablegen-mode () "Major mode for editing TableGen description files. \\{tablegen-mode-map} @@ -115,10 +115,10 @@ (use-local-map tablegen-mode-map) ; Provides the local keymap. (setq major-mode 'tablegen-mode) - (make-local-variable 'font-lock-defaults) + (make-local-variable 'font-lock-defaults) (setq major-mode 'tablegen-mode ; This is how describe-mode ; finds the doc string to print. - mode-name "TableGen" ; This name goes into the modeline. + mode-name "TableGen" ; This name goes into the modeline. font-lock-defaults `(tablegen-font-lock-keywords)) (setq local-abbrev-table tablegen-mode-abbrev-table) From sabre at nondot.org Sat Dec 8 18:06:20 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 09 Dec 2007 00:06:20 -0000 Subject: [llvm-commits] [llvm] r44728 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeTypesExpand.cpp LegalizeTypesSplit.cpp Message-ID: <200712090006.lB906Ko4022672@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 18:06:19 2007 New Revision: 44728 URL: http://llvm.org/viewvc/llvm-project?rev=44728&view=rev Log: Add support for splitting the operand of a return instruction. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=44728&r1=44727&r2=44728&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sat Dec 8 18:06:19 2007 @@ -291,7 +291,8 @@ // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); - SDOperand SplitOperand_STORE(StoreSDNode *N, unsigned OpNo); + SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo); + SDOperand SplitOp_RET(SDNode *N, unsigned OpNo); }; } // end namespace llvm. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp?rev=44728&r1=44727&r2=44728&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp Sat Dec 8 18:06:19 2007 @@ -1043,59 +1043,15 @@ if (!N->isTruncatingStore()) { unsigned IncrementSize = 0; + GetExpandedOp(N->getValue(), Lo, Hi); + IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8; - // If this is a vector type, then we have to calculate the increment as - // the product of the element size in bytes, and the number of elements - // in the high half of the vector. - if (MVT::isVector(N->getValue().getValueType())) { - assert(0 && "Vectors not supported yet"); - #if 0 - SDNode *InVal = ST->getValue().Val; - unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); - MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); - - // Figure out if there is a simple type corresponding to this Vector - // type. If so, convert to the vector type. - MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems); - if (TLI.isTypeLegal(TVT)) { - // Turn this into a normal store of the vector type. - Tmp3 = LegalizeOp(Node->getOperand(1)); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - Result = LegalizeOp(Result); - break; - } else if (NumElems == 1) { - // Turn this into a normal store of the scalar type. - Tmp3 = ScalarizeVectorOp(Node->getOperand(1)); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - // The scalarized value type may not be legal, e.g. it might require - // promotion or expansion. Relegalize the scalar store. - return LegalizeOp(Result); - } else { - SplitVectorOp(Node->getOperand(1), Lo, Hi); - IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8; - } - #endif - } else { - GetExpandedOp(N->getValue(), Lo, Hi); - IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0; - - if (!TLI.isLittleEndian()) - std::swap(Lo, Hi); - } + if (!TLI.isLittleEndian()) + std::swap(Lo, Hi); Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, isVolatile, Alignment); - assert(Hi.Val && "FIXME: int <-> float should be handled with promote!"); - #if 0 - if (Hi.Val == NULL) { - // Must be int <-> float one-to-one expansion. - return Lo; - } - #endif - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=44728&r1=44727&r2=44728&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Sat Dec 8 18:06:19 2007 @@ -337,9 +337,8 @@ #endif assert(0 && "Do not know how to split this operator's operand!"); abort(); - case ISD::STORE: - Res = SplitOperand_STORE(cast(N), OpNo); - break; + case ISD::STORE: Res = SplitOp_STORE(cast(N), OpNo); break; + case ISD::RET: Res = SplitOp_RET(N, OpNo); break; } } @@ -364,7 +363,7 @@ return false; } -SDOperand DAGTypeLegalizer::SplitOperand_STORE(StoreSDNode *N, unsigned OpNo) { +SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) { assert(OpNo == 1 && "Can only split the stored value"); SDOperand Ch = N->getChain(); @@ -388,3 +387,15 @@ return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); } +SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) { + assert(N->getNumOperands() == 3 &&"Can only handle ret of one vector so far"); + // FIXME: Returns of gcc generic vectors larger than a legal vector + // type should be returned by reference! + SDOperand Lo, Hi; + GetSplitOp(N->getOperand(1), Lo, Hi); + + SDOperand Chain = N->getOperand(0); // The chain. + SDOperand Sign = N->getOperand(2); // Signness + + return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign); +} From clattner at apple.com Sat Dec 8 18:21:59 2007 From: clattner at apple.com (Chris Lattner) Date: Sat, 8 Dec 2007 16:21:59 -0800 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) In-Reply-To: <475B1C30.5020800@fastmail.fm> References: <475B1C30.5020800@fastmail.fm> Message-ID: On Dec 8, 2007, at 2:35 PM, Wojciech Matyjewicz wrote: > Hi, > > It seems that this problem is caused by a copy-paste bug in > BasicAliasAnalysis.cpp. The first part of the diff is of a cosmetic > nature. The second fixes the bug. This patch looks excellent, thanks! Unfortunately though, the patch does not apply. Can you please attach it instead of including it inline in the email? Thanks, -Chris From clattner at apple.com Sat Dec 8 18:24:18 2007 From: clattner at apple.com (Chris Lattner) Date: Sat, 8 Dec 2007 16:24:18 -0800 Subject: [llvm-commits] [llvm] r44705 - in /llvm/trunk: include/llvm/Support/StringPool.h lib/Support/StringPool.cpp In-Reply-To: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> References: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> Message-ID: <4D685F81-FA8B-446E-9422-801C47FC3917@apple.com> On Dec 8, 2007, at 9:07 AM, Gordon Henriksen wrote: > Author: gordon > Date: Sat Dec 8 11:07:47 2007 > New Revision: 44705 > > URL: http://llvm.org/viewvc/llvm-project?rev=44705&view=rev > Log: > Adding a StringPool data structure, which GC will use. Looks great Gordon, one other nit-pick: > +#include Please #include LLVM headers with ""'s when in the llvm source base, thanks! -Chris From sabre at nondot.org Sat Dec 8 18:27:29 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 8 Dec 2007 18:27:29 -0600 Subject: [llvm-commits] CVS: llvm-www/ProjectsWithLLVM/index.html Message-ID: <200712090027.lB90RTwx023728@zion.cs.uiuc.edu> Changes in directory llvm-www/ProjectsWithLLVM: index.html updated: 1.39 -> 1.40 --- Log message: add puzzle solving project. --- Diffs of the changes: (+36 -0) index.html | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+) Index: llvm-www/ProjectsWithLLVM/index.html diff -u llvm-www/ProjectsWithLLVM/index.html:1.39 llvm-www/ProjectsWithLLVM/index.html:1.40 --- llvm-www/ProjectsWithLLVM/index.html:1.39 Tue Jul 31 19:03:33 2007 +++ llvm-www/ProjectsWithLLVM/index.html Sat Dec 8 18:26:42 2007 @@ -35,6 +35,7 @@

    + + +
    +By Fernando Pereira and Jens Palsberg, UCLA. +
    + +
    +

    +In this project, we have shown that register allocation can be viewed +as solving a collection of puzzles. +We model the register file as a puzzle board and +the program variables as puzzle pieces; +pre-coloring and register aliasing fit in naturally. +For architectures such as x86, SPARC V8, and StrongARM, +we can solve the puzzles in polynomial time, and we have augmented +the puzzle solver with a simple heuristic for spilling. +For SPEC CPU2000, our implementation is as fast as +the extended version of linear scan used by LLVM. +Our implementation produces Pentium code that is of similar quality to the +code produced by the slower, state-of-the-art iterated register coalescing +algorithm of George and Appel augmented with extensions by Smith, Ramsey, and +Holloway. +

    + +

    +Project + page with a link to a tool that verifies the output of LLVM's register + allocator. +

    + +
    + +
    Faust Real-Time Signal Processing System
    From sabre at nondot.org Sat Dec 8 18:27:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 09 Dec 2007 00:27:38 -0000 Subject: [llvm-commits] [llvm] r44729 - /llvm/trunk/tools/Makefile Message-ID: <200712090027.lB90RcHi023749@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 8 18:27:38 2007 New Revision: 44729 URL: http://llvm.org/viewvc/llvm-project?rev=44729&view=rev Log: Fix accidental commit by Bill. Modified: llvm/trunk/tools/Makefile Modified: llvm/trunk/tools/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=44729&r1=44728&r2=44729&view=diff ============================================================================== --- llvm/trunk/tools/Makefile (original) +++ llvm/trunk/tools/Makefile Sat Dec 8 18:27:38 2007 @@ -16,7 +16,7 @@ llc llvm-ranlib llvm-ar llvm-nm \ llvm-ld llvmc llvm-prof llvm-link \ lli gccas gccld llvm-extract llvm-db llvm2cpp \ - bugpoint llvm-bcanalyzer llvm-stub cfe + bugpoint llvm-bcanalyzer llvm-stub include $(LEVEL)/Makefile.config From wmatyjewicz at fastmail.fm Sat Dec 8 18:58:55 2007 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Sun, 09 Dec 2007 01:58:55 +0100 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) In-Reply-To: References: <475B1C30.5020800@fastmail.fm> Message-ID: <475B3DCF.2030706@fastmail.fm> Chris Lattner wrote: > > Unfortunately though, the patch > does not apply. Can you please attach it instead of including it > inline in the email? Chris, could you check my previous post one more time, please. The patch should be attached to it. At least, I have received this post with an attachment from listserv. I have just tried to apply the patch (patch -p0 < PR1782.diff from llvm source root dir) and it worked. -Wojtek From gordonhenriksen at mac.com Sat Dec 8 19:10:14 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 8 Dec 2007 20:10:14 -0500 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) In-Reply-To: <475B3DCF.2030706@fastmail.fm> References: <475B1C30.5020800@fastmail.fm> <475B3DCF.2030706@fastmail.fm> Message-ID: On 2007-12-08, at 19:58, Wojciech Matyjewicz wrote: > Chris Lattner wrote: >> > >> Unfortunately though, the patch does not apply. Can you please >> attach it instead of including it inline in the email? > > Chris, could you check my previous post one more time, please. The > patch should be attached to it. At least, I have received this post > with an attachment from listserv. I have just tried to apply the > patch (patch -p0 < PR1782.diff from llvm source root dir) and it > worked. Thunderbird sent the attachment with the MIME header Content- Disposition: inline, which Apple Mail always expands and displays inline (i.e., not as an attachment). The original attachment is in the listserv archives. http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056082.html Wojtek, you might try (a.) using ".patch" in the hopes of eliciting Content-Type: application/octet-stream which will always appear as an attachment, (b.) compressing the attachment, or (c.) looking for a setting in Thunderbird to use Content-Disposition: attachment for attachments. ? Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071208/6576e4de/attachment.html From gordonhenriksen at mac.com Sat Dec 8 19:12:08 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 09 Dec 2007 01:12:08 -0000 Subject: [llvm-commits] [llvm] r44732 - /llvm/trunk/include/llvm/Support/StringPool.h Message-ID: <200712090112.lB91C8Qd025929@zion.cs.uiuc.edu> Author: gordon Date: Sat Dec 8 19:12:08 2007 New Revision: 44732 URL: http://llvm.org/viewvc/llvm-project?rev=44732&view=rev Log: Fix a very silly typo. Modified: llvm/trunk/include/llvm/Support/StringPool.h Modified: llvm/trunk/include/llvm/Support/StringPool.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringPool.h?rev=44732&r1=44731&r2=44732&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StringPool.h (original) +++ llvm/trunk/include/llvm/Support/StringPool.h Sat Dec 8 19:12:08 2007 @@ -29,7 +29,7 @@ #ifndef LLVM_SUPPORT_STRINGPOOL_H #define LLVM_SUPPORT_STRINGPOOL_H -#include +#include "llvm/ADT/StringMap.h" #include #include From gordonhenriksen at mac.com Sat Dec 8 19:14:34 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sat, 8 Dec 2007 20:14:34 -0500 Subject: [llvm-commits] [llvm] r44705 - in /llvm/trunk: include/llvm/Support/StringPool.h lib/Support/StringPool.cpp In-Reply-To: <4D685F81-FA8B-446E-9422-801C47FC3917@apple.com> References: <200712081707.lB8H7p32028814@zion.cs.uiuc.edu> <4D685F81-FA8B-446E-9422-801C47FC3917@apple.com> Message-ID: On 2007-12-08, at 19:24, Chris Lattner wrote: > On Dec 8, 2007, at 9:07 AM, Gordon Henriksen wrote: > >> +#include > > Please #include LLVM headers with ""'s when in the llvm source base, > thanks! Indubitably. Fixed. ? Gordon From wmatyjewicz at fastmail.fm Sat Dec 8 19:52:17 2007 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Sun, 09 Dec 2007 02:52:17 +0100 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) In-Reply-To: References: <475B1C30.5020800@fastmail.fm> <475B3DCF.2030706@fastmail.fm> Message-ID: <475B4A51.1070000@fastmail.fm> Gordon Henriksen wrote: > Wojtek, you might try /(a.)/ using ".patch" in the hopes of eliciting > Content-Type: application/octet-stream which will always appear as an > attachment, /(b.)/ compressing the attachment, or /(c.)/ looking for a > setting in Thunderbird to use Content-Disposition: attachment for > attachments. Thanks, Gordon! I've applied the (c.) approach. Hope, everyone can see the attachment now. -Wojtek -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: PR1782.diff Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071209/9234c89d/attachment.pl From sabre at nondot.org Sun Dec 9 01:35:14 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 09 Dec 2007 07:35:14 -0000 Subject: [llvm-commits] [llvm] r44733 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll Message-ID: <200712090735.lB97ZEU7012099@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 9 01:35:13 2007 New Revision: 44733 URL: http://llvm.org/viewvc/llvm-project?rev=44733&view=rev Log: Fix PR1782, patch by Wojtek Matyjewicz! Added: llvm/trunk/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=44733&r1=44732&r2=44733&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Sun Dec 9 01:35:13 2007 @@ -730,8 +730,8 @@ if (const ArrayType *AT = dyn_cast(BasePtr1Ty)) { if (Op1C->getZExtValue() >= AT->getNumElements()) return MayAlias; // Be conservative with out-of-range accesses - } else if (const VectorType *PT = dyn_cast(BasePtr1Ty)) { - if (Op1C->getZExtValue() >= PT->getNumElements()) + } else if (const VectorType *VT = dyn_cast(BasePtr1Ty)) { + if (Op1C->getZExtValue() >= VT->getNumElements()) return MayAlias; // Be conservative with out-of-range accesses } @@ -756,10 +756,10 @@ if (Op2) { if (const ConstantInt *Op2C = dyn_cast(Op2)) { // If this is an array index, make sure the array element is in range. - if (const ArrayType *AT = dyn_cast(BasePtr1Ty)) { + if (const ArrayType *AT = dyn_cast(BasePtr2Ty)) { if (Op2C->getZExtValue() >= AT->getNumElements()) return MayAlias; // Be conservative with out-of-range accesses - } else if (const VectorType *VT = dyn_cast(BasePtr1Ty)) { + } else if (const VectorType *VT = dyn_cast(BasePtr2Ty)) { if (Op2C->getZExtValue() >= VT->getNumElements()) return MayAlias; // Be conservative with out-of-range accesses } Added: llvm/trunk/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll?rev=44733&view=auto ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll (added) +++ llvm/trunk/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll Sun Dec 9 01:35:13 2007 @@ -0,0 +1,31 @@ +; RUN: llvm-as < %s | opt -gvn -disable-output +; PR1782 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.device = type { [20 x i8] } + %struct.pci_device_id = type { i32, i32, i32, i32, i32, i32, i64 } + %struct.usb_bus = type { %struct.device* } + %struct.usb_hcd = type { %struct.usb_bus, [0 x i64] } + at pci_ids = external constant [1 x %struct.pci_device_id] ; <[1 x %struct.pci_device_id]*> [#uses=1] + + at __mod_pci_device_table = alias [1 x %struct.pci_device_id]* @pci_ids ; <[1 x %struct.pci_device_id]*> [#uses=0] + +define i32 @ehci_pci_setup(%struct.usb_hcd* %hcd) { +entry: + %tmp14 = getelementptr %struct.usb_hcd* %hcd, i32 0, i32 0, i32 0 ; <%struct.device**> [#uses=1] + %tmp15 = load %struct.device** %tmp14, align 8 ; <%struct.device*> [#uses=0] + br i1 false, label %bb25, label %return + +bb25: ; preds = %entry + br i1 false, label %cond_true, label %return + +cond_true: ; preds = %bb25 + %tmp601 = getelementptr %struct.usb_hcd* %hcd, i32 0, i32 1, i64 2305843009213693951 ; [#uses=1] + %tmp67 = bitcast i64* %tmp601 to %struct.device** ; <%struct.device**> [#uses=1] + %tmp68 = load %struct.device** %tmp67, align 8 ; <%struct.device*> [#uses=0] + ret i32 undef + +return: ; preds = %bb25, %entry + ret i32 undef +} From clattner at apple.com Sun Dec 9 01:35:59 2007 From: clattner at apple.com (Chris Lattner) Date: Sat, 8 Dec 2007 23:35:59 -0800 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) In-Reply-To: <475B4A51.1070000@fastmail.fm> References: <475B1C30.5020800@fastmail.fm> <475B3DCF.2030706@fastmail.fm> <475B4A51.1070000@fastmail.fm> Message-ID: On Dec 8, 2007, at 5:52 PM, Wojciech Matyjewicz wrote: > Gordon Henriksen wrote: > >> Wojtek, you might try /(a.)/ using ".patch" in the hopes of eliciting >> Content-Type: application/octet-stream which will always appear as an >> attachment, /(b.)/ compressing the attachment, or /(c.)/ looking >> for a >> setting in Thunderbird to use Content-Disposition: attachment for >> attachments. > > Thanks, Gordon! I've applied the (c.) approach. Hope, everyone can see > the attachment now. Yep, it looks Gordon was right :). Thanks again Wojtek, I applied the patch. Please close the PR, -Chris From isanbard at gmail.com Sun Dec 9 04:45:36 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 9 Dec 2007 02:45:36 -0800 Subject: [llvm-commits] [llvm] r44687 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/MachineLICM.cpp lib/Target/PowerPC/PPCInstrInfo.td In-Reply-To: <200712080933.07034.baldrick@free.fr> References: <200712072142.lB7LgWK3026283@zion.cs.uiuc.edu> <200712080933.07034.baldrick@free.fr> Message-ID: <4D1B3030-C052-4271-A611-D32A9B459FD6@gmail.com> On Dec 8, 2007, at 12:33 AM, Duncan Sands wrote: > Hi Bill, presumably you are using alias analysis at the > codegen level. I noticed some time ago that in several > places code doing multiple stores to successive locations > does not set the SVOffset value correctly: it used the same > SVOffset for all the stores. Probably the same is true for > loads. I think this can result in wrong alias analysis > deductions. Probably someone should audit code for this... > Hi Duncan, Thanks for pointing this out. I'll go over it when I'm doing the load/ store instructions in my pass. -bw From isanbard at gmail.com Sun Dec 9 05:13:34 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 9 Dec 2007 03:13:34 -0800 Subject: [llvm-commits] [llvm] r44729 - /llvm/trunk/tools/Makefile In-Reply-To: <200712090027.lB90RcHi023749@zion.cs.uiuc.edu> References: <200712090027.lB90RcHi023749@zion.cs.uiuc.edu> Message-ID: <68B3E0BD-D213-48F8-8160-1C1D797FF60E@gmail.com> Sorry :-( -bw On Dec 8, 2007, at 4:27 PM, Chris Lattner wrote: > Author: lattner > Date: Sat Dec 8 18:27:38 2007 > New Revision: 44729 > > URL: http://llvm.org/viewvc/llvm-project?rev=44729&view=rev > Log: > Fix accidental commit by Bill. > > Modified: > llvm/trunk/tools/Makefile > > Modified: llvm/trunk/tools/Makefile > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile? > rev=44729&r1=44728&r2=44729&view=diff > > ====================================================================== > ======== > --- llvm/trunk/tools/Makefile (original) > +++ llvm/trunk/tools/Makefile Sat Dec 8 18:27:38 2007 > @@ -16,7 +16,7 @@ > llc llvm-ranlib llvm-ar llvm-nm \ > llvm-ld llvmc llvm-prof llvm-link \ > lli gccas gccld llvm-extract llvm-db llvm2cpp \ > - bugpoint llvm-bcanalyzer llvm-stub cfe > + bugpoint llvm-bcanalyzer llvm-stub > > > include $(LEVEL)/Makefile.config > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gordonhenriksen at mac.com Sun Dec 9 09:03:02 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 09 Dec 2007 15:03:02 -0000 Subject: [llvm-commits] [llvm] r44738 - /llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll Message-ID: <200712091503.lB9F32Vl006429@zion.cs.uiuc.edu> Author: gordon Date: Sun Dec 9 09:03:01 2007 New Revision: 44738 URL: http://llvm.org/viewvc/llvm-project?rev=44738&view=rev Log: Upgrading this test to 2.0 .ll syntax. Modified: llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll Modified: llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll?rev=44738&r1=44737&r2=44738&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll (original) +++ llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll Sun Dec 9 09:03:01 2007 @@ -1,54 +1,53 @@ -; RUN: llvm-upgrade < %s | llvm-as | llc +; RUN: llvm-as < %s | llc -implementation -declare sbyte* %llvm_gc_allocate(uint) -declare void %llvm_gc_initialize(uint) +declare i8* @llvm_gc_allocate(i32) +declare void @llvm_gc_initialize(i32) -declare void %llvm.gcroot(sbyte**, sbyte*) -declare void %llvm.gcwrite(sbyte*, sbyte*, sbyte**) +declare void @llvm.gcroot(i8**, i8*) +declare void @llvm.gcwrite(i8*, i8*, i8**) -int %main() { +define i32 @main() { entry: - %A = alloca sbyte* - %B = alloca sbyte** + %A = alloca i8* + %B = alloca i8** - call void %llvm_gc_initialize(uint 1048576) ; Start with 1MB heap + call void @llvm_gc_initialize(i32 1048576) ; Start with 1MB heap ;; void *A; - call void %llvm.gcroot(sbyte** %A, sbyte* null) + call void @llvm.gcroot(i8** %A, i8* null) ;; A = gcalloc(10); - %Aptr = call sbyte* %llvm_gc_allocate(uint 10) - store sbyte* %Aptr, sbyte** %A + %Aptr = call i8* @llvm_gc_allocate(i32 10) + store i8* %Aptr, i8** %A ;; void **B; - %tmp.1 = cast sbyte*** %B to sbyte ** - call void %llvm.gcroot(sbyte** %tmp.1, sbyte* null) + %tmp.1 = bitcast i8*** %B to i8** + call void @llvm.gcroot(i8** %tmp.1, i8* null) ;; B = gcalloc(4); - %B = call sbyte* %llvm_gc_allocate(uint 8) - %tmp.2 = cast sbyte* %B to sbyte** - store sbyte** %tmp.2, sbyte*** %B + %B.upgrd.1 = call i8* @llvm_gc_allocate(i32 8) + %tmp.2 = bitcast i8* %B.upgrd.1 to i8** + store i8** %tmp.2, i8*** %B ;; *B = A; - %B.1 = load sbyte*** %B - %A.1 = load sbyte** %A - call void %llvm.gcwrite(sbyte* %A.1, sbyte* %B, sbyte** %B.1) + %B.1 = load i8*** %B + %A.1 = load i8** %A + call void @llvm.gcwrite(i8* %A.1, i8* %B.upgrd.1, i8** %B.1) br label %AllocLoop AllocLoop: - %i = phi uint [ 0, %entry ], [ %indvar.next, %AllocLoop ] + %i = phi i32 [ 0, %entry ], [ %indvar.next, %AllocLoop ] ;; Allocated mem: allocated memory is immediately dead. - call sbyte* %llvm_gc_allocate(uint 100) + call i8* @llvm_gc_allocate(i32 100) - %indvar.next = add uint %i, 1 - %exitcond = seteq uint %indvar.next, 10000000 - br bool %exitcond, label %Exit, label %AllocLoop + %indvar.next = add i32 %i, 1 + %exitcond = icmp eq i32 %indvar.next, 10000000 + br i1 %exitcond, label %Exit, label %AllocLoop Exit: - ret int 0 + ret i32 0 } -declare void %__main() +declare void @__main() From sabre at nondot.org Sun Dec 9 11:56:35 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 09 Dec 2007 17:56:35 -0000 Subject: [llvm-commits] [llvm] r44740 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Message-ID: <200712091756.lB9HuZFB016994@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 9 11:56:34 2007 New Revision: 44740 URL: http://llvm.org/viewvc/llvm-project?rev=44740&view=rev Log: Duncan points out that the subtraction is unneeded since hte code knows the vector is not pow2 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=44740&r1=44739&r2=44740&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Sun Dec 9 11:56:34 2007 @@ -27,7 +27,7 @@ NumElements >>= 1; Lo = Hi = MVT::getVectorType(NewEltVT, NumElements); } else { // Non-power-of-two vectors. - unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1); + unsigned NewNumElts_Lo = 1 << Log2_32(NumElements); unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo); Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi); From gordonhenriksen at mac.com Sun Dec 9 16:46:10 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 09 Dec 2007 22:46:10 -0000 Subject: [llvm-commits] [llvm] r44747 - in /llvm/trunk: include/llvm/ lib/VMCore/ Message-ID: <200712092246.lB9MkBYY002183@zion.cs.uiuc.edu> Author: gordon Date: Sun Dec 9 16:46:10 2007 New Revision: 44747 URL: http://llvm.org/viewvc/llvm-project?rev=44747&view=rev Log: Devirtualizing Value destructor (PR889). Patch by Pawel Kunio! Modified: llvm/trunk/include/llvm/Argument.h llvm/trunk/include/llvm/BasicBlock.h llvm/trunk/include/llvm/Constant.h llvm/trunk/include/llvm/Constants.h llvm/trunk/include/llvm/Function.h llvm/trunk/include/llvm/GlobalAlias.h llvm/trunk/include/llvm/GlobalValue.h llvm/trunk/include/llvm/GlobalVariable.h llvm/trunk/include/llvm/InlineAsm.h llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/include/llvm/Instruction.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/IntrinsicInst.h llvm/trunk/include/llvm/User.h llvm/trunk/include/llvm/Value.h llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Constants.cpp llvm/trunk/lib/VMCore/Function.cpp llvm/trunk/lib/VMCore/InlineAsm.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/include/llvm/Argument.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Argument.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Argument.h (original) +++ llvm/trunk/include/llvm/Argument.h Sun Dec 9 16:46:10 2007 @@ -35,6 +35,11 @@ friend class SymbolTableListTraits; void setParent(Function *parent); +protected: + static void destroyThis(Argument*v) { + Value::destroyThis(v); + } + friend class Value; public: /// Argument ctor - If Function argument is specified, this argument is /// inserted at the end of the argument list for the function. Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Sun Dec 9 16:46:10 2007 @@ -65,6 +65,9 @@ BasicBlock(const BasicBlock &); // Do not implement void operator=(const BasicBlock &); // Do not implement +protected: + static void destroyThis(BasicBlock*); + friend class Value; public: /// Instruction iterators... typedef InstListType::iterator iterator; @@ -76,7 +79,6 @@ /// explicit BasicBlock(const std::string &Name = "", Function *Parent = 0, BasicBlock *InsertBefore = 0); - ~BasicBlock(); /// getParent - Return the enclosing method, or null if none /// @@ -206,6 +208,33 @@ const BasicBlock *getPrev() const { return Prev; } }; +/// DummyInst - An instance of this class is used to mark the end of the +/// instruction list. This is not a real instruction. +class DummyInst : public Instruction { +protected: + static void destroyThis(DummyInst* v) { + Instruction::destroyThis(v); + } + friend class Value; +public: + DummyInst(); + + Instruction *clone() const { + assert(0 && "Cannot clone EOL");abort(); + return 0; + } + const char *getOpcodeName() const { return "*end-of-list-inst*"; } + + // Methods for support type inquiry through isa, cast, and dyn_cast... + static inline bool classof(const DummyInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == OtherOpsEnd; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + inline int ilist_traits::getListOffset() { return BasicBlock::getInstListOffset(); Modified: llvm/trunk/include/llvm/Constant.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constant.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constant.h (original) +++ llvm/trunk/include/llvm/Constant.h Sun Dec 9 16:46:10 2007 @@ -43,6 +43,10 @@ : User(Ty, vty, Ops, NumOps) {} void destroyConstantImpl(); + static void destroyThis(Constant*v) { + User::destroyThis(v); + } + friend class Value; public: /// Static constructor to get a '0' constant of arbitrary type... /// Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Sun Dec 9 16:46:10 2007 @@ -46,6 +46,11 @@ ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT ConstantInt(const IntegerType *Ty, const APInt& V); APInt Val; +protected: + static void destroyThis(ConstantInt*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// Return the constant as an APInt value reference. This allows clients to /// obtain a copy of the value, with all its precision in tact. @@ -218,6 +223,10 @@ ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT protected: ConstantFP(const Type *Ty, const APFloat& V); + static void destroyThis(ConstantFP*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static ConstantFP *get(const Type *Ty, const APFloat& V); @@ -266,6 +275,11 @@ protected: explicit ConstantAggregateZero(const Type *Ty) : Constant(Ty, ConstantAggregateZeroVal, 0, 0) {} + + static void destroyThis(ConstantAggregateZero*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - static factory method for creating a null aggregate. It is /// illegal to call this method with a non-aggregate type. @@ -295,7 +309,8 @@ ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT protected: ConstantArray(const ArrayType *T, const std::vector &Val); - ~ConstantArray(); + static void destroyThis(ConstantArray*); + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const ArrayType *T, const std::vector &); @@ -361,7 +376,8 @@ ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT protected: ConstantStruct(const StructType *T, const std::vector &Val); - ~ConstantStruct(); + static void destroyThis(ConstantStruct*); + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value /// @@ -405,7 +421,8 @@ ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT protected: ConstantVector(const VectorType *T, const std::vector &Val); - ~ConstantVector(); + static void destroyThis(ConstantVector*v); + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const VectorType *T, const std::vector &); @@ -462,7 +479,10 @@ explicit ConstantPointerNull(const PointerType *T) : Constant(reinterpret_cast(T), Value::ConstantPointerNullVal, 0, 0) {} - + static void destroyThis(ConstantPointerNull*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - Static factory methods - Return objects of the specified value @@ -524,6 +544,10 @@ static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1, Constant *V2, Constant *Mask); + static void destroyThis(ConstantExpr* v) { + Constant::destroyThis(v); + } + friend class Value; public: // Static methods to construct a ConstantExpr of different kinds. Note that // these methods may return a object that is not an instance of the @@ -709,6 +733,10 @@ UndefValue(const UndefValue &); // DO NOT IMPLEMENT protected: explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {} + static void destroyThis(UndefValue*v) { + Constant::destroyThis(v); + } + friend class Value; public: /// get() - Static factory methods - Return an 'undef' object of the specified /// type. @@ -728,6 +756,120 @@ } }; +/// GetElementPtrConstantExpr - Helper class for Constants.cpp, +/// used behind the scenes to implement getelementpr constant exprs. +class GetElementPtrConstantExpr : public ConstantExpr { +protected: + static void destroyThis(GetElementPtrConstantExpr*v) { + delete [] v->OperandList; + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, + const Type *DestTy); +}; + +/// UnaryConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement unary constant exprs. +class UnaryConstantExpr : public ConstantExpr { + Use Op; +protected: + static void destroyThis(UnaryConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty); +}; + +/// BinaryConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement binary constant exprs. +class BinaryConstantExpr : public ConstantExpr { + Use Ops[2]; +protected: + static void destroyThis(BinaryConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) + : ConstantExpr(C1->getType(), Opcode, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + } +}; + +/// SelectConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement select constant exprs. +class SelectConstantExpr : public ConstantExpr { + Use Ops[3]; +protected: + static void destroyThis(SelectConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3); +}; + +/// ExtractElementConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement extractelement constant exprs. +class ExtractElementConstantExpr : public ConstantExpr { + Use Ops[2]; +protected: + static void destroyThis(ExtractElementConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + ExtractElementConstantExpr(Constant *C1, Constant *C2); +}; + +/// InsertElementConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + Use Ops[3]; +protected: + static void destroyThis(InsertElementConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3); +}; + +/// ShuffleVectorConstantExpr - Helper class for Constants.cpp, used +/// behind the scenes to implement shufflevector constant exprs. +class ShuffleVectorConstantExpr : public ConstantExpr { + Use Ops[3]; +protected: + static void destroyThis(ShuffleVectorConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3); +}; + + + +// CompareConstantExpr - Helper class for Constants.cpp, used +// behind the scenes to implement ICmp and FCmp constant expressions. This is +// needed in order to store the predicate value for these instructions. +class CompareConstantExpr : public ConstantExpr { +protected: + static void destroyThis(CompareConstantExpr*v) { + ConstantExpr::destroyThis(v); + } + friend class Value; +public: + unsigned short predicate; + Use Ops[2]; + CompareConstantExpr(unsigned opc, unsigned short pred, + Constant* LHS, Constant* RHS); +}; + } // End llvm namespace #endif Modified: llvm/trunk/include/llvm/Function.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Function.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Function.h (original) +++ llvm/trunk/include/llvm/Function.h Sun Dec 9 16:46:10 2007 @@ -53,6 +53,9 @@ }; class Function : public GlobalValue, public Annotable { +protected: + static void destroyThis(Function*v); + friend class Value; public: typedef iplist ArgumentListType; typedef iplist BasicBlockListType; @@ -109,7 +112,6 @@ /// Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &N = "", Module *M = 0); - ~Function(); const Type *getReturnType() const; // Return the type of the ret val const FunctionType *getFunctionType() const; // Return the FunctionType for me Modified: llvm/trunk/include/llvm/GlobalAlias.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalAlias.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalAlias.h (original) +++ llvm/trunk/include/llvm/GlobalAlias.h Sun Dec 9 16:46:10 2007 @@ -43,6 +43,11 @@ const GlobalAlias *getPrev() const { return Prev; } Use Aliasee; +protected: + static void destroyThis(GlobalAlias*v) { + GlobalValue::destroyThis(v); + } + friend class Value; public: /// GlobalAlias ctor - If a parent module is specified, the alias is /// automatically inserted into the end of the specified module's alias list. Modified: llvm/trunk/include/llvm/GlobalValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalValue.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalValue.h (original) +++ llvm/trunk/include/llvm/GlobalValue.h Sun Dec 9 16:46:10 2007 @@ -63,11 +63,12 @@ unsigned Visibility : 2; // The visibility style of this global unsigned Alignment : 16; // Alignment of this symbol, must be power of two std::string Section; // Section to emit this into, empty mean default -public: - ~GlobalValue() { - removeDeadConstantUsers(); // remove any dead constants using this. - } + static void destroyThis(GlobalValue*v) { + v->removeDeadConstantUsers(); // remove any dead constants using this. + Constant::destroyThis(v); + } +public: unsigned getAlignment() const { return Alignment; } void setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); Modified: llvm/trunk/include/llvm/GlobalVariable.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalVariable.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalVariable.h (original) +++ llvm/trunk/include/llvm/GlobalVariable.h Sun Dec 9 16:46:10 2007 @@ -45,6 +45,11 @@ bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"? Use Initializer; +protected: + static void destroyThis(GlobalVariable*v) { + GlobalValue::destroyThis(v); + } + friend class Value; public: /// GlobalVariable ctor - If a parent module is specified, the global is /// automatically inserted into the end of the specified modules global list. Modified: llvm/trunk/include/llvm/InlineAsm.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InlineAsm.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/InlineAsm.h (original) +++ llvm/trunk/include/llvm/InlineAsm.h Sun Dec 9 16:46:10 2007 @@ -36,9 +36,12 @@ InlineAsm(const FunctionType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects); - virtual ~InlineAsm(); +protected: + static void destroyThis(InlineAsm*v) { + Value::destroyThis(v); + } + friend class Value; public: - /// InlineAsm::get - Return the the specified uniqued inline asm string. /// static InlineAsm *get(const FunctionType *Ty, const std::string &AsmString, Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Sun Dec 9 16:46:10 2007 @@ -38,14 +38,16 @@ Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} - // Out of line virtual method, so the vtable, etc has a home. - ~TerminatorInst(); - /// Virtual methods - Terminators should overload these and provide inline /// overrides of non-V methods. virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; + + static void destroyThis(TerminatorInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: virtual Instruction *clone() const = 0; @@ -94,10 +96,12 @@ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE) : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this_()) { } -public: - // Out of line virtual method, so the vtable, etc has a home. - ~UnaryInstruction(); + static void destroyThis(UnaryInstruction* v) { + Instruction::destroyThis(v); + } + friend class Value; +public: // Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { assert(i == 0 && "getOperand() out of range!"); @@ -136,6 +140,11 @@ const std::string &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd); + + static void destroyThis(BinaryOperator* v) { + Instruction::destroyThis(v); + } + friend class Value; public: /// Transparently provide more efficient getOperand methods. @@ -272,6 +281,12 @@ : UnaryInstruction(Ty, iType, S, InsertAtEnd) { setName(Name); } + +protected: + static void destroyThis(CastInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: /// Provides a way to construct any of the CastInst subclasses using an /// opcode instead of the subclass's constructor. The opcode must be in the @@ -493,6 +508,10 @@ Use Ops[2]; // CmpInst instructions always have 2 operands, optimize + static void destroyThis(CmpInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: /// Construct a compare instruction, given the opcode, the predicate and /// the two operands. Optionally (if InstBefore is specified) insert the Modified: llvm/trunk/include/llvm/Instruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.h (original) +++ llvm/trunk/include/llvm/Instruction.h Sun Dec 9 16:46:10 2007 @@ -42,10 +42,10 @@ Instruction *InsertBefore = 0); Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); + + static void destroyThis(Instruction*v); + friend class Value; public: - // Out of line virtual method, so the vtable, etc has a home. - ~Instruction(); - /// mayWriteToMemory - Return true if this instruction may modify memory. /// bool mayWriteToMemory() const; Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Sun Dec 9 16:46:10 2007 @@ -47,9 +47,6 @@ AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd); public: - // Out of line virtual method, so the vtable, etc has a home. - virtual ~AllocationInst(); - /// isArrayAllocation - Return true if there is an allocation size parameter /// to the allocation instruction that is not 1. /// @@ -190,6 +187,11 @@ /// class FreeInst : public UnaryInstruction { void AssertOK(); +protected: + static void destroyThis(FreeInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); FreeInst(Value *Ptr, BasicBlock *InsertAfter); @@ -230,6 +232,11 @@ #endif } void AssertOK(); +protected: + static void destroyThis(LoadInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); @@ -305,6 +312,11 @@ #endif } void AssertOK(); +protected: + static void destroyThis(StoreInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); @@ -443,6 +455,9 @@ } } +protected: + static void destroyThis(GetElementPtrInst*v); + friend class Value; public: /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing @@ -477,7 +492,6 @@ const std::string &Name = "", Instruction *InsertBefore =0); GetElementPtrInst(Value *Ptr, Value *Idx, const std::string &Name, BasicBlock *InsertAtEnd); - ~GetElementPtrInst(); virtual GetElementPtrInst *clone() const; @@ -556,6 +570,11 @@ /// vectors of integrals. The two operands must be the same type. /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { +protected: + static void destroyThis(ICmpInst* v) { + CmpInst::destroyThis(v); + } + friend class Value; public: /// This enumeration lists the possible predicates for the ICmpInst. The /// values in the range 0-31 are reserved for FCmpInst while values in the @@ -712,6 +731,11 @@ /// vectors of floating point values. The operands must be identical types. /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { +protected: + static void destroyThis(FCmpInst* v) { + CmpInst::destroyThis(v); + } + friend class Value; public: /// This enumeration lists the possible predicates for the FCmpInst. Values /// in the range 0-31 are reserved for FCmpInst. @@ -857,6 +881,9 @@ setName(Name); } +protected: + static void destroyThis(CallInst*v); + friend class Value; public: /// Construct a CallInst given a range of arguments. InputIterator /// must be a random-access iterator pointing to contiguous storage @@ -897,7 +924,6 @@ explicit CallInst(Value *F, const std::string &Name = "", Instruction *InsertBefore = 0); CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd); - ~CallInst(); virtual CallInst *clone() const; @@ -989,6 +1015,11 @@ : Instruction(SI.getType(), SI.getOpcode(), Ops, 3) { init(SI.Ops[0], SI.Ops[1], SI.Ops[2]); } +protected: + static void destroyThis(SelectInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1044,6 +1075,11 @@ class VAArgInst : public UnaryInstruction { VAArgInst(const VAArgInst &VAA) : UnaryInstruction(VAA.getType(), VAArg, VAA.getOperand(0)) {} +protected: + static void destroyThis(VAArgInst* v) { + UnaryInstruction::destroyThis(v); + } + friend class Value; public: VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1083,6 +1119,11 @@ Ops[1].init(EE.Ops[1], this); } +protected: + static void destroyThis(ExtractElementInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name = "", Instruction *InsertBefore = 0); @@ -1130,6 +1171,11 @@ class InsertElementInst : public Instruction { Use Ops[3]; InsertElementInst(const InsertElementInst &IE); +protected: + static void destroyThis(InsertElementInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const std::string &Name = "",Instruction *InsertBefore = 0); @@ -1184,6 +1230,11 @@ class ShuffleVectorInst : public Instruction { Use Ops[3]; ShuffleVectorInst(const ShuffleVectorInst &IE); +protected: + static void destroyThis(ShuffleVectorInst* v) { + Instruction::destroyThis(v); + } + friend class Value; public: ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const std::string &Name = "", Instruction *InsertBefor = 0); @@ -1238,6 +1289,9 @@ /// the number actually in use. unsigned ReservedSpace; PHINode(const PHINode &PN); +protected: + static void destroyThis(PHINode*); + friend class Value; public: explicit PHINode(const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1252,8 +1306,6 @@ setName(Name); } - ~PHINode(); - /// reserveOperandSpace - This method can be used to avoid repeated /// reallocation of PHI operand lists by reserving space for the correct /// number of operands before adding them. Unlike normal vector reserves, @@ -1522,6 +1574,9 @@ SwitchInst(const SwitchInst &RI); void init(Value *Value, BasicBlock *Default, unsigned NumCases); void resizeOperands(unsigned No); +protected: + static void destroyThis(SwitchInst*v); + friend class Value; public: /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can @@ -1536,7 +1591,6 @@ /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); - ~SwitchInst(); // Accessor Methods for Switch stmt @@ -1664,6 +1718,9 @@ setName(Name); } +protected: + static void destroyThis(InvokeInst*v); + friend class Value; public: /// Construct an InvokeInst given a range of arguments. /// InputIterator must be a random-access iterator pointing to @@ -1701,8 +1758,6 @@ typename std::iterator_traits::iterator_category()); } - ~InvokeInst(); - virtual InvokeInst *clone() const; /// getCallingConv/setCallingConv - Get or set the calling convention of this @@ -1872,6 +1927,11 @@ TruncInst(const TruncInst &CI) : CastInst(CI.getType(), Trunc, CI.getOperand(0)) { } +protected: + static void destroyThis(TruncInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics TruncInst( @@ -1912,6 +1972,11 @@ ZExtInst(const ZExtInst &CI) : CastInst(CI.getType(), ZExt, CI.getOperand(0)) { } +protected: + static void destroyThis(ZExtInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics ZExtInst( @@ -1952,6 +2017,11 @@ SExtInst(const SExtInst &CI) : CastInst(CI.getType(), SExt, CI.getOperand(0)) { } +protected: + static void destroyThis(SExtInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics SExtInst( @@ -1991,6 +2061,11 @@ FPTruncInst(const FPTruncInst &CI) : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) { } +protected: + static void destroyThis(FPTruncInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPTruncInst( @@ -2030,6 +2105,11 @@ FPExtInst(const FPExtInst &CI) : CastInst(CI.getType(), FPExt, CI.getOperand(0)) { } +protected: + static void destroyThis(FPExtInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPExtInst( @@ -2069,6 +2149,11 @@ UIToFPInst(const UIToFPInst &CI) : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) { } +protected: + static void destroyThis(UIToFPInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics UIToFPInst( @@ -2108,6 +2193,11 @@ SIToFPInst(const SIToFPInst &CI) : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) { } +protected: + static void destroyThis(SIToFPInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics SIToFPInst( @@ -2147,6 +2237,11 @@ FPToUIInst(const FPToUIInst &CI) : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) { } +protected: + static void destroyThis(FPToUIInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPToUIInst( @@ -2186,6 +2281,11 @@ FPToSIInst(const FPToSIInst &CI) : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) { } +protected: + static void destroyThis(FPToSIInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPToSIInst( @@ -2225,6 +2325,11 @@ IntToPtrInst(const IntToPtrInst &CI) : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) { } +protected: + static void destroyThis(IntToPtrInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics IntToPtrInst( @@ -2264,6 +2369,11 @@ PtrToIntInst(const PtrToIntInst &CI) : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) { } +protected: + static void destroyThis(PtrToIntInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics PtrToIntInst( @@ -2303,6 +2413,11 @@ BitCastInst(const BitCastInst &CI) : CastInst(CI.getType(), BitCast, CI.getOperand(0)) { } +protected: + static void destroyThis(BitCastInst* v) { + CastInst::destroyThis(v); + } + friend class Value; public: /// @brief Constructor with insert-before-instruction semantics BitCastInst( Modified: llvm/trunk/include/llvm/IntrinsicInst.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicInst.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicInst.h (original) +++ llvm/trunk/include/llvm/IntrinsicInst.h Sun Dec 9 16:46:10 2007 @@ -38,6 +38,11 @@ IntrinsicInst(); // DO NOT IMPLEMENT IntrinsicInst(const IntrinsicInst&); // DO NOT IMPLEMENT void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT + protected: + static void destroyThis(IntrinsicInst* v) { + CallInst::destroyThis(v); + } + friend class Value; public: /// StripPointerCasts - This static method strips off any unneeded pointer @@ -85,6 +90,11 @@ } static Value *StripCast(Value *C); + protected: + static void destroyThis(DbgInfoIntrinsic* v) { + IntrinsicInst::destroyThis(v); + } + friend class Value; }; /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction. @@ -114,6 +124,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgStopPointInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// DbgFuncStartInst - This represents the llvm.dbg.func.start instruction. @@ -129,6 +144,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgFuncStartInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// DbgRegionStartInst - This represents the llvm.dbg.region.start @@ -144,6 +164,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgRegionStartInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// DbgRegionEndInst - This represents the llvm.dbg.region.end instruction. @@ -175,6 +200,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(DbgDeclareInst* v) { + DbgInfoIntrinsic::destroyThis(v); + } + friend class Value; }; /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. @@ -228,6 +258,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemIntrinsic* v) { + IntrinsicInst::destroyThis(v); + } + friend class Value; }; @@ -259,6 +294,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemCpyInst* v) { + MemIntrinsic::destroyThis(v); + } + friend class Value; }; /// MemMoveInst - This class wraps the llvm.memmove intrinsic. @@ -288,6 +328,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemMoveInst* v) { + MemIntrinsic::destroyThis(v); + } + friend class Value; }; /// MemSetInst - This class wraps the llvm.memset intrinsic. @@ -312,6 +357,11 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + protected: + static void destroyThis(MemSetInst* v) { + MemIntrinsic::destroyThis(v); + } + friend class Value; }; } Modified: llvm/trunk/include/llvm/User.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/User.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/User.h (original) +++ llvm/trunk/include/llvm/User.h Sun Dec 9 16:46:10 2007 @@ -37,6 +37,10 @@ /// unsigned NumOperands; + static void destroyThis(User*v) { + Value::destroyThis(v); + } + friend class Value; public: User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps) : Value(Ty, vty), OperandList(OpList), NumOperands(NumOps) {} Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Sun Dec 9 16:46:10 2007 @@ -66,8 +66,11 @@ friend class SymbolTable; // Allow SymbolTable to directly poke Name. ValueName *Name; +private: void operator=(const Value &); // Do not implement Value(const Value &); // Do not implement +protected: + static void destroyThis(Value*); public: Value(const Type *Ty, unsigned scid); Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Sun Dec 9 16:46:10 2007 @@ -30,31 +30,9 @@ return 0; } - -namespace { - /// DummyInst - An instance of this class is used to mark the end of the - /// instruction list. This is not a real instruction. - struct VISIBILITY_HIDDEN DummyInst : public Instruction { - DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd, 0, 0) { - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(this); - } - - Instruction *clone() const { - assert(0 && "Cannot clone EOL");abort(); - return 0; - } - const char *getOpcodeName() const { return "*end-of-list-inst*"; } - - // Methods for support type inquiry through isa, cast, and dyn_cast... - static inline bool classof(const DummyInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == OtherOpsEnd; - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } - }; +DummyInst::DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd, 0, 0) { + // This should not be garbage monitored. + LeakDetector::removeGarbageObject(this); } Instruction *ilist_traits::createSentinel() { @@ -88,10 +66,12 @@ } -BasicBlock::~BasicBlock() { - assert(getParent() == 0 && "BasicBlock still linked into the program!"); - dropAllReferences(); - InstList.clear(); +void BasicBlock::destroyThis(BasicBlock*v) +{ + assert(v->getParent() == 0 && "BasicBlock still linked into the program!"); + v->dropAllReferences(); + v->InstList.clear(); + Value::destroyThis(v); } void BasicBlock::setParent(Function *parent) { Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Sun Dec 9 16:46:10 2007 @@ -356,8 +356,9 @@ } } -ConstantArray::~ConstantArray() { - delete [] OperandList; +void ConstantArray::destroyThis(ConstantArray*v) { + delete [] v->OperandList; + Constant::destroyThis(v); } ConstantStruct::ConstantStruct(const StructType *T, @@ -379,8 +380,9 @@ } } -ConstantStruct::~ConstantStruct() { - delete [] OperandList; +void ConstantStruct::destroyThis(ConstantStruct*v) { + delete [] v->OperandList; + Constant::destroyThis(v); } @@ -399,125 +401,68 @@ } } -ConstantVector::~ConstantVector() { - delete [] OperandList; +void ConstantVector::destroyThis(ConstantVector*v) { + delete [] v->OperandList; + Constant::destroyThis(v); +} + +UnaryConstantExpr::UnaryConstantExpr(unsigned Opcode, + Constant *C, const Type *Ty) + : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) { +} + +SelectConstantExpr::SelectConstantExpr(Constant *C1, + Constant *C2, Constant *C3) + : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); +} + +ExtractElementConstantExpr::ExtractElementConstantExpr(Constant *C1, + Constant *C2) + : ConstantExpr(cast(C1->getType())->getElementType(), + Instruction::ExtractElement, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); +} + +InsertElementConstantExpr::InsertElementConstantExpr(Constant *C1, + Constant *C2, + Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); +} + +ShuffleVectorConstantExpr::ShuffleVectorConstantExpr(Constant *C1, + Constant *C2, + Constant *C3) + : ConstantExpr(C1->getType(), Instruction::ShuffleVector, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); +} + +CompareConstantExpr::CompareConstantExpr(unsigned opc, unsigned short pred, + Constant* LHS, Constant* RHS) + : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) { + OperandList[0].init(LHS, this); + OperandList[1].init(RHS, this); +} + +GetElementPtrConstantExpr::GetElementPtrConstantExpr(Constant *C, + const std::vector + &IdxList, const Type *DestTy) +: ConstantExpr(DestTy, Instruction::GetElementPtr, + new Use[IdxList.size()+1], IdxList.size()+1) +{ + OperandList[0].init(C, this); + for (unsigned i = 0, E = IdxList.size(); i != E; ++i) + OperandList[i+1].init(IdxList[i], this); } -// We declare several classes private to this file, so use an anonymous -// namespace -namespace { - -/// UnaryConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement unary constant exprs. -class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr { - Use Op; -public: - UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) - : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {} -}; - -/// BinaryConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement binary constant exprs. -class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr { - Use Ops[2]; -public: - BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) - : ConstantExpr(C1->getType(), Opcode, Ops, 2) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - } -}; - -/// SelectConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement select constant exprs. -class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr { - Use Ops[3]; -public: - SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); - } -}; - -/// ExtractElementConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// extractelement constant exprs. -class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr { - Use Ops[2]; -public: - ExtractElementConstantExpr(Constant *C1, Constant *C2) - : ConstantExpr(cast(C1->getType())->getElementType(), - Instruction::ExtractElement, Ops, 2) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - } -}; - -/// InsertElementConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// insertelement constant exprs. -class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr { - Use Ops[3]; -public: - InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C1->getType(), Instruction::InsertElement, - Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); - } -}; - -/// ShuffleVectorConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// shufflevector constant exprs. -class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr { - Use Ops[3]; -public: - ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C1->getType(), Instruction::ShuffleVector, - Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); - } -}; - -/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is -/// used behind the scenes to implement getelementpr constant exprs. -struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr { - GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, - const Type *DestTy) - : ConstantExpr(DestTy, Instruction::GetElementPtr, - new Use[IdxList.size()+1], IdxList.size()+1) { - OperandList[0].init(C, this); - for (unsigned i = 0, E = IdxList.size(); i != E; ++i) - OperandList[i+1].init(IdxList[i], this); - } - ~GetElementPtrConstantExpr() { - delete [] OperandList; - } -}; - -// CompareConstantExpr - This class is private to Constants.cpp, and is used -// behind the scenes to implement ICmp and FCmp constant expressions. This is -// needed in order to store the predicate value for these instructions. -struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr { - unsigned short predicate; - Use Ops[2]; - CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, - Constant* LHS, Constant* RHS) - : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) { - OperandList[0].init(LHS, this); - OperandList[1].init(RHS, this); - } -}; - -} // end anonymous namespace - - // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into // Constant.h Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Sun Dec 9 16:46:10 2007 @@ -287,16 +287,17 @@ ParentModule->getFunctionList().push_back(this); } -Function::~Function() { - dropAllReferences(); // After this it is safe to delete instructions. +void Function::destroyThis(Function*v) { + v->dropAllReferences(); // After this it is safe to delete instructions. // Delete all of the method arguments and unlink from symbol table... - ArgumentList.clear(); - delete SymTab; + v->ArgumentList.clear(); + delete v->SymTab; // Drop our reference to the parameter attributes, if any. - if (ParamAttrs) - ParamAttrs->dropRef(); + if (v->ParamAttrs) + v->ParamAttrs->dropRef(); + GlobalValue::destroyThis(v); } void Function::BuildLazyArguments() const { Modified: llvm/trunk/lib/VMCore/InlineAsm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/InlineAsm.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/InlineAsm.cpp (original) +++ llvm/trunk/lib/VMCore/InlineAsm.cpp Sun Dec 9 16:46:10 2007 @@ -17,12 +17,6 @@ #include using namespace llvm; -// Implement the first virtual method in this class in this file so the -// InlineAsm vtable is emitted here. -InlineAsm::~InlineAsm() { -} - - // NOTE: when memoizing the function type, we have to be careful to handle the // case when the type gets refined. Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Sun Dec 9 16:46:10 2007 @@ -46,8 +46,8 @@ // Out of line virtual method, so the vtable, etc has a home. -Instruction::~Instruction() { - assert(Parent == 0 && "Instruction still linked in the program!"); +void Instruction::destroyThis(Instruction*v) { + assert(v->Parent == 0 && "Instruction still linked in the program!"); } Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Sun Dec 9 16:46:10 2007 @@ -67,20 +67,6 @@ } - -//===----------------------------------------------------------------------===// -// TerminatorInst Class -//===----------------------------------------------------------------------===// - -// Out of line virtual method, so the vtable, etc has a home. -TerminatorInst::~TerminatorInst() { -} - -// Out of line virtual method, so the vtable, etc has a home. -UnaryInstruction::~UnaryInstruction() { -} - - //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -96,8 +82,9 @@ } } -PHINode::~PHINode() { - delete [] OperandList; +void PHINode::destroyThis(PHINode*v) { + delete [] v->OperandList; + Instruction::destroyThis(v); } // removeIncomingValue - Remove an incoming value. This is useful if a @@ -214,10 +201,11 @@ // CallInst Implementation //===----------------------------------------------------------------------===// -CallInst::~CallInst() { - delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); +void CallInst::destroyThis(CallInst*v) { + delete [] v->OperandList; + if (v->ParamAttrs) + v->ParamAttrs->dropRef(); + Instruction::destroyThis(v); } void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { @@ -406,10 +394,11 @@ // InvokeInst Implementation //===----------------------------------------------------------------------===// -InvokeInst::~InvokeInst() { - delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); +void InvokeInst::destroyThis(InvokeInst*v) { + delete [] v->OperandList; + if (v->ParamAttrs) + v->ParamAttrs->dropRef(); + TerminatorInst::destroyThis(v); } void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, @@ -683,10 +672,6 @@ setName(Name); } -// Out of line virtual method, so the vtable, etc has a home. -AllocationInst::~AllocationInst() { -} - bool AllocationInst::isArrayAllocation() const { if (ConstantInt *CI = dyn_cast(getOperand(0))) return CI->getZExtValue() != 1; @@ -951,8 +936,8 @@ setName(Name); } -GetElementPtrInst::~GetElementPtrInst() { - delete[] OperandList; +void GetElementPtrInst::destroyThis(GetElementPtrInst*v) { + delete[] v->OperandList; } // getIndexedType - Returns the type of the element that would be loaded with @@ -2469,8 +2454,9 @@ } } -SwitchInst::~SwitchInst() { - delete [] OperandList; +void SwitchInst::destroyThis(SwitchInst*v) { + delete [] v->OperandList; + TerminatorInst::destroyThis(v); } Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=44747&r1=44746&r2=44747&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Sun Dec 9 16:46:10 2007 @@ -18,6 +18,11 @@ #include "llvm/ValueSymbolTable.h" #include "llvm/Support/Debug.h" #include "llvm/Support/LeakDetector.h" +#include "llvm/Constants.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/InstrTypes.h" #include using namespace llvm; @@ -39,7 +44,233 @@ "Cannot create non-first-class values except for constants!"); } -Value::~Value() { +Value::~Value() +{ + switch(SubclassID) + { + case ArgumentVal: + Argument::destroyThis(cast(this)); + break; + case BasicBlockVal: + BasicBlock::destroyThis(cast(this)); + break; + case FunctionVal: + Function::destroyThis(cast(this)); + break; + case GlobalAliasVal: + GlobalAlias::destroyThis(cast(this)); + break; + case GlobalVariableVal: + GlobalVariable::destroyThis(cast(this)); + break; + case UndefValueVal: + UndefValue::destroyThis(cast(this)); + break; + case ConstantExprVal: + { + ConstantExpr* CE = dyn_cast(this); + if(CE->getOpcode() == Instruction::GetElementPtr) + { + GetElementPtrConstantExpr* GECE = + dyn_cast(CE); + GetElementPtrConstantExpr::destroyThis(GECE); + } + else if(CE->getOpcode() == Instruction::ExtractElement) + { + ExtractElementConstantExpr* EECE = + dyn_cast(CE); + ExtractElementConstantExpr::destroyThis(EECE); + } + else if(CE->getOpcode() == Instruction::InsertElement) + { + InsertElementConstantExpr* IECE = + dyn_cast(CE); + InsertElementConstantExpr::destroyThis(IECE); + } + else if(CE->getOpcode() == Instruction::Select) + { + SelectConstantExpr* SCE = dyn_cast(CE); + SelectConstantExpr::destroyThis(SCE); + } + else if(CE->getOpcode() == Instruction::ShuffleVector) + { + ShuffleVectorConstantExpr* SVCE = + dyn_cast(CE); + ShuffleVectorConstantExpr::destroyThis(SVCE); + } + else if(BinaryConstantExpr* BCE = dyn_cast(this)) + BinaryConstantExpr::destroyThis(BCE); + else if(UnaryConstantExpr* UCE = dyn_cast(this)) + UnaryConstantExpr::destroyThis(UCE); + else if(CompareConstantExpr* CCE = dyn_cast(this)) + CompareConstantExpr::destroyThis(CCE); + else + assert(0 && "Unknown ConstantExpr-inherited class in ~Value."); + } + break; + case ConstantAggregateZeroVal: + ConstantAggregateZero::destroyThis(cast(this)); + break; + case ConstantIntVal: + ConstantInt::destroyThis(cast(this)); + break; + case ConstantFPVal: + ConstantFP::destroyThis(cast(this)); + break; + case ConstantArrayVal: + ConstantArray::destroyThis(cast(this)); + break; + case ConstantStructVal: + ConstantStruct::destroyThis(cast(this)); + break; + case ConstantVectorVal: + ConstantVector::destroyThis(cast(this)); + break; + case ConstantPointerNullVal: + ConstantPointerNull::destroyThis(cast(this)); + break; + case InlineAsmVal: + InlineAsm::destroyThis(cast(this)); + break; + + default: + if (BinaryOperator *BO = dyn_cast(this)) + BinaryOperator::destroyThis(BO); + else if (CallInst *CI = dyn_cast(this)) + { + if(IntrinsicInst* II = dyn_cast(this)) + { + if(DbgInfoIntrinsic* DII = dyn_cast(this)) + { + if(DbgDeclareInst* DDI = dyn_cast(this)) + DbgDeclareInst::destroyThis(DDI); + else if(DbgFuncStartInst* DFSI = dyn_cast(this)) + DbgFuncStartInst::destroyThis(DFSI); + else if(DbgRegionEndInst* DREI = dyn_cast(this)) + DbgRegionEndInst::destroyThis(DREI); + else if(DbgRegionStartInst* DRSI = dyn_cast(this)) + DbgRegionStartInst::destroyThis(DRSI); + else if(DbgStopPointInst* DSPI = dyn_cast(this)) + DbgStopPointInst::destroyThis(DSPI); + else + assert(0 && "Unknown DbgInfo-inherited class in ~Value."); + } + else if(MemIntrinsic* MI = dyn_cast(this)) + { + if(MemCpyInst* MCI = dyn_cast(this)) + MemCpyInst::destroyThis(MCI); + else if(MemMoveInst* MMI = dyn_cast(this)) + MemMoveInst::destroyThis(MMI); + else if(MemSetInst* MSI = dyn_cast(this)) + MemSetInst::destroyThis(MSI); + else + assert(0 && "Unknown MemIntrinsic-inherited class in ~Value."); + } + else + assert(0 && "Unknown IntrinsicInst-inherited class in ~Value."); + } + else + assert(0 && "Unknown CallInst-inherited class in ~Value."); + } + else if (CmpInst *CI = dyn_cast(this)) + { + if (FCmpInst *FCI = dyn_cast(this)) + FCmpInst::destroyThis(FCI); + else if (ICmpInst *ICI = dyn_cast(this)) + ICmpInst::destroyThis(ICI); + else + assert(0 && "Unknown CmpInst-inherited class in ~Value."); + } + else if (ExtractElementInst *EEI = dyn_cast(this)) + ExtractElementInst::destroyThis(EEI); + else if (GetElementPtrInst *GEP = dyn_cast(this)) + GetElementPtrInst::destroyThis(GEP); + else if (InsertElementInst* IE = dyn_cast(this)) + InsertElementInst::destroyThis(IE); + else if (PHINode *PN = dyn_cast(this)) + PHINode::destroyThis(PN); + else if (SelectInst *SI = dyn_cast(this)) + SelectInst::destroyThis(SI); + else if (ShuffleVectorInst *SVI = dyn_cast(this)) + ShuffleVectorInst::destroyThis(SVI); + else if (StoreInst *SI = dyn_cast(this)) + StoreInst::destroyThis(SI); + else if (TerminatorInst *TI = dyn_cast(this)) + { + if (BranchInst* BI = dyn_cast(this)) + BranchInst::destroyThis(BI); + else if (InvokeInst* II = dyn_cast(this)) + InvokeInst::destroyThis(II); + else if (ReturnInst* RI = dyn_cast(this)) + ReturnInst::destroyThis(RI); + else if (SwitchInst *SI = dyn_cast(this)) + SwitchInst::destroyThis(SI); + else if (UnreachableInst *UI = dyn_cast(this)) + UnreachableInst::destroyThis(UI); + else if (UnwindInst *UI = dyn_cast(this)) + UnwindInst::destroyThis(UI); + else + assert(0 && "Unknown TerminatorInst-inherited class in ~Value."); + } + else if(UnaryInstruction* UI = dyn_cast(this)) + { + if(AllocationInst* AI = dyn_cast(this)) + { + if(AllocaInst* AI = dyn_cast(this)) + AllocaInst::destroyThis(AI); + else if(MallocInst* MI = dyn_cast(this)) + MallocInst::destroyThis(MI); + else + assert(0 && "Unknown AllocationInst-inherited class in ~Value."); + } + else if(CastInst* CI = dyn_cast(this)) + { + if(BitCastInst* BCI = dyn_cast(this)) + BitCastInst::destroyThis(BCI); + else if(FPExtInst* FPEI = dyn_cast(this)) + FPExtInst::destroyThis(FPEI); + else if(FPToSIInst* FPSII = dyn_cast(this)) + FPToSIInst::destroyThis(FPSII); + else if(FPToUIInst* FPUII = dyn_cast(this)) + FPToUIInst::destroyThis(FPUII); + else if(FPTruncInst* FPTI = dyn_cast(this)) + FPTruncInst::destroyThis(FPTI); + else if(IntToPtrInst* I2PI = dyn_cast(this)) + IntToPtrInst::destroyThis(I2PI); + else if(PtrToIntInst* P2II = dyn_cast(this)) + PtrToIntInst::destroyThis(P2II); + else if(SExtInst* SEI = dyn_cast(this)) + SExtInst::destroyThis(SEI); + else if(SIToFPInst* SIFPI = dyn_cast(this)) + SIToFPInst::destroyThis(SIFPI); + else if(TruncInst* TI = dyn_cast(this)) + TruncInst::destroyThis(TI); + else if(UIToFPInst* UIFPI = dyn_cast(this)) + UIToFPInst::destroyThis(UIFPI); + else if(ZExtInst* ZEI = dyn_cast(this)) + ZExtInst::destroyThis(ZEI); + else + assert(0 && "Unknown CastInst-inherited class in ~Value."); + } + else if(FreeInst* FI = dyn_cast(this)) + FreeInst::destroyThis(FI); + else if(LoadInst* LI = dyn_cast(this)) + LoadInst::destroyThis(LI); + else if(VAArgInst* VAI = dyn_cast(this)) + VAArgInst::destroyThis(VAI); + else + assert(0 && "Unknown UnaryInstruction-inherited class in ~Value."); + } + else if (DummyInst *DI = dyn_cast(this)) + DummyInst::destroyThis(DI); + else + assert(0 && "Unknown Instruction-inherited class in ~Value."); + break; + } +} + +void Value::destroyThis(Value*v) +{ #ifndef NDEBUG // Only in -g mode... // Check to make sure that there are no uses of this value that are still // around when the value is destroyed. If there are, then we have a dangling @@ -47,22 +278,22 @@ // still being referenced. The value in question should be printed as // a // - if (!use_empty()) { - DOUT << "While deleting: " << *Ty << " %" << Name << "\n"; - for (use_iterator I = use_begin(), E = use_end(); I != E; ++I) + if (!v->use_empty()) { + DOUT << "While deleting: " << *v->Ty << " %" << v->Name << "\n"; + for (use_iterator I = v->use_begin(), E = v->use_end(); I != E; ++I) DOUT << "Use still stuck around after Def is destroyed:" << **I << "\n"; } #endif - assert(use_empty() && "Uses remain when a value is destroyed!"); + assert(v->use_empty() && "Uses remain when a value is destroyed!"); // If this value is named, destroy the name. This should not be in a symtab // at this point. - if (Name) - Name->Destroy(); + if (v->Name) + v->Name->Destroy(); // There should be no uses of this object anymore, remove it. - LeakDetector::removeGarbageObject(this); + LeakDetector::removeGarbageObject(v); } /// hasNUses - Return true if this Value has exactly N users. From gordonhenriksen at mac.com Sun Dec 9 16:50:11 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 9 Dec 2007 17:50:11 -0500 Subject: [llvm-commits] PR889 final version In-Reply-To: References: Message-ID: <9324B061-24AE-4D30-BEC9-BA9C6008613F@mac.com> On Dec 3, 2007, at 17:59, pawel kunio wrote: > Whoah, pretty strange I get neither of those. I'm using compiler > from vs 2008 beta2 'orcas'. What compiler should I use to be more in > sync with the one used by You for verification? btw, I had a deeper > look into the Value class hierarchy and it seems that to remove all > vtables there will be a need to flatten Instruction hierarchy with > regard to the clone virtual method as well as Constant > destroyConstant,isNullValue,replaceUsesOfWithOnConstant methods) and > GlobalValue (isDeclaration method). Those as well as print and dump > methods will probably be blocking the Value destructor from being de- > virtualized. > > Anyway, please find the patch attached with the Value destructor > virtualized temporarily and with added 'class' clause to friend > Value declarations. Thanks Pawel! I've applied your patch as rev 44747 here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056105.html Thanks again, Gordon P.S. The line endings in your patch were a bit problematic. All of the file contents themselves had Unix line endings, but the the diff structures (@@ X,Y and Index: etc.) were all in DOS format. It'd help save a bit of confusion if you can sort that for future submissions. From wmatyjewicz at fastmail.fm Sun Dec 9 16:57:29 2007 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Sun, 09 Dec 2007 23:57:29 +0100 Subject: [llvm-commits] RFC: patch for PR1782 (BasicAliasAnalyis) In-Reply-To: References: <475B1C30.5020800@fastmail.fm> <475B3DCF.2030706@fastmail.fm> <475B4A51.1070000@fastmail.fm> Message-ID: <475C72D9.9000505@fastmail.fm> Chris Lattner wrote: > Yep, it looks Gordon was right :). Thanks again Wojtek, I applied the > patch. Please close the PR, Before I close the PR, I would like to discuss one more issue discovered while working on it. Suppose, we have a target with 32-bit pointers and the following instructions: %p = getelementptr i32* %x, i32 -1 %q = getelementptr i32* %x, i32 1073741823 ;(1073741823 == 2^30 - 1) TargetData::getIndexedOffset() uses 64-bit arithmetic to perform offset computation and return 64-bit values. Hence, it will return -4 as an offset for %p, and 2^32 - 4 for %q. Based on these offsets, it may seem that %p and %q point to different memory objects. However, they don't, taking into account that pointers are 32-bit long. I guess, such a large positive index in GEP as seen above can be introduced by -instcombine pass. BasicAA seems to be affected by the issue. For the attached example opt -aa-eval says that %p and %q don't alias. I think, the simplest way to fix it is to truncate the computed offset to the target pointer size before returning it in TargetData::getIndexedOffset(). If you think this is the correct approach, I may prepare a patch. -Wojtek -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: example.ll Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071209/e5ef51a0/attachment.pl From gordonhenriksen at mac.com Sun Dec 9 17:36:48 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 9 Dec 2007 18:36:48 -0500 Subject: [llvm-commits] Deleting the Value vtable In-Reply-To: <9324B061-24AE-4D30-BEC9-BA9C6008613F@mac.com> References: <9324B061-24AE-4D30-BEC9-BA9C6008613F@mac.com> Message-ID: <3B63125F-A744-4C10-A7BB-D26A5BE1581C@mac.com> On Dec 9, 2007, at 17:50, Gordon Henriksen wrote: > On Dec 3, 2007, at 17:59, pawel kunio wrote: > >> Whoah, pretty strange I get neither of those. I'm using compiler >> from vs 2008 beta2 'orcas'. What compiler should I use to be more >> in sync with the one used by You for verification? btw, I had a >> deeper look into the Value class hierarchy and it seems that to >> remove all vtables there will be a need to flatten Instruction >> hierarchy with regard to the clone virtual method as well as >> Constant destroyConstant,isNullValue,replaceUsesOfWithOnConstant >> methods) and GlobalValue (isDeclaration method). Those as well as >> print and dump methods will probably be blocking the Value >> destructor from being de-virtualized. >> >> Anyway, please find the patch attached with the Value destructor >> virtualized temporarily and with added 'class' clause to friend >> Value declarations. > > Thanks Pawel! I've applied your patch as rev 44747 here: > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056105.html Since there are some other methods to devirtualize deeper in the class hierarchy, I wonder if it might make sense to write the dispatch once instead of repeating it several times. Here are some ideas off the top of my head? // Dispatch to static methods. #define NONVIRTUAL_DISPATCH1(V, F) \ if (Foo *W = dyn_cast(V)) W->F(); \ else if (Bar *W = dyn_cast(V)) W->F(); \ else if (Baz *W = dyn_cast(V)) W->F(); // Dispatch to static methods. #define NONVIRTUAL_DISPATCH2(V, F) \ if (Foo *W = dyn_cast(V)) Foo::F(W); \ else if (Bar *W = dyn_cast(V)) Bar::F(W); \ else if (Baz *W = dyn_cast(V)) Baz::F(W); // Dispatch to operator() overloads on a template operand. template void NonvirtualDispatch3(Value *V) { Algo A; NonvirtualDispatch3(V, A); }; template void NonvirtualDispatch3(Value *V, Algo &A) { if (Foo *W = dyn_cast(V)) A(W); else if (Bar *W = dyn_cast(V)) A(W); else if (Baz *W = dyn_cast(V)) A(W); }; I don't like promoting methods to classes, so NovirtualDispatch3 is initially unattractive to me. However, there are practical benefits. It allows separate compilation by defining the operator()(Foo*) overload in Foo.c. The declarations must be visible for an algorithm invoked from Value, though. It can dispatch algorithms that take arguments by passing an Algo instance using the second overload. Overloads on the V parameter could dispatch over subtypes. These properties make it applicable for users of Value, not just its implementation. All of these techniques can follow the class hierarchy automatically. In the first two cases, a base class will provide a default implementation. In the lattermost case, undefined overloads will fall back to the base class. ? Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071209/7d838792/attachment.html From clattner at apple.com Sun Dec 9 18:02:38 2007 From: clattner at apple.com (Chris Lattner) Date: Sun, 9 Dec 2007 16:02:38 -0800 Subject: [llvm-commits] Deleting the Value vtable In-Reply-To: <3B63125F-A744-4C10-A7BB-D26A5BE1581C@mac.com> References: <9324B061-24AE-4D30-BEC9-BA9C6008613F@mac.com> <3B63125F-A744-4C10-A7BB-D26A5BE1581C@mac.com> Message-ID: <60D23EED-39E0-4F28-8575-6E01020FC63D@apple.com> >> Thanks Pawel! I've applied your patch as rev 44747 here: >> >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056105.html > > > Since there are some other methods to devirtualize deeper in the > class hierarchy, I wonder if it might make sense to write the > dispatch once instead of repeating it several times. Here are some > ideas off the top of my head? Why not something like InstVisitor? Right now it only supports instructions, but it could be extended. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071209/b69c4c76/attachment.html From gordonhenriksen at mac.com Sun Dec 9 18:12:23 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Sun, 9 Dec 2007 19:12:23 -0500 Subject: [llvm-commits] Deleting the Value vtable In-Reply-To: <60D23EED-39E0-4F28-8575-6E01020FC63D@apple.com> References: <9324B061-24AE-4D30-BEC9-BA9C6008613F@mac.com> <3B63125F-A744-4C10-A7BB-D26A5BE1581C@mac.com> <60D23EED-39E0-4F28-8575-6E01020FC63D@apple.com> Message-ID: On 2007-12-09, at 19:02, Chris Lattner wrote: >>> Thanks Pawel! I've applied your patch as rev 44747 here: >>> >>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071203/056105.html >> >> >> Since there are some other methods to devirtualize deeper in the >> class hierarchy, I wonder if it might make sense to write the >> dispatch once instead of repeating it several times. Here are some >> ideas off the top of my head? > > Why not something like InstVisitor? Right now it only supports > instructions, but it could be extended. Indeed it could. It's isomorphic to the last option minus the sugar of dispatch(Value);. ? Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071209/9af1a3f8/attachment.html From sabre at nondot.org Sun Dec 9 19:48:30 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 10 Dec 2007 01:48:30 -0000 Subject: [llvm-commits] [llvm] r44755 - /llvm/trunk/lib/VMCore/Value.cpp Message-ID: <200712100148.lBA1mURS012218@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 9 19:48:29 2007 New Revision: 44755 URL: http://llvm.org/viewvc/llvm-project?rev=44755&view=rev Log: Fix a big problem in the recent dtor refactoring work, now it passes 2007-11-19-InlineAsm.ll Modified: llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=44755&r1=44754&r2=44755&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Sun Dec 9 19:48:29 2007 @@ -137,41 +137,7 @@ if (BinaryOperator *BO = dyn_cast(this)) BinaryOperator::destroyThis(BO); else if (CallInst *CI = dyn_cast(this)) - { - if(IntrinsicInst* II = dyn_cast(this)) - { - if(DbgInfoIntrinsic* DII = dyn_cast(this)) - { - if(DbgDeclareInst* DDI = dyn_cast(this)) - DbgDeclareInst::destroyThis(DDI); - else if(DbgFuncStartInst* DFSI = dyn_cast(this)) - DbgFuncStartInst::destroyThis(DFSI); - else if(DbgRegionEndInst* DREI = dyn_cast(this)) - DbgRegionEndInst::destroyThis(DREI); - else if(DbgRegionStartInst* DRSI = dyn_cast(this)) - DbgRegionStartInst::destroyThis(DRSI); - else if(DbgStopPointInst* DSPI = dyn_cast(this)) - DbgStopPointInst::destroyThis(DSPI); - else - assert(0 && "Unknown DbgInfo-inherited class in ~Value."); - } - else if(MemIntrinsic* MI = dyn_cast(this)) - { - if(MemCpyInst* MCI = dyn_cast(this)) - MemCpyInst::destroyThis(MCI); - else if(MemMoveInst* MMI = dyn_cast(this)) - MemMoveInst::destroyThis(MMI); - else if(MemSetInst* MSI = dyn_cast(this)) - MemSetInst::destroyThis(MSI); - else - assert(0 && "Unknown MemIntrinsic-inherited class in ~Value."); - } - else - assert(0 && "Unknown IntrinsicInst-inherited class in ~Value."); - } - else - assert(0 && "Unknown CallInst-inherited class in ~Value."); - } + CallInst::destroyThis(CI); else if (CmpInst *CI = dyn_cast(this)) { if (FCmpInst *FCI = dyn_cast(this)) @@ -222,32 +188,30 @@ MallocInst::destroyThis(MI); else assert(0 && "Unknown AllocationInst-inherited class in ~Value."); - } - else if(CastInst* CI = dyn_cast(this)) - { - if(BitCastInst* BCI = dyn_cast(this)) + } else if(CastInst* CI = dyn_cast(this)) { + if(BitCastInst* BCI = dyn_cast(CI)) BitCastInst::destroyThis(BCI); - else if(FPExtInst* FPEI = dyn_cast(this)) + else if(FPExtInst* FPEI = dyn_cast(CI)) FPExtInst::destroyThis(FPEI); - else if(FPToSIInst* FPSII = dyn_cast(this)) + else if(FPToSIInst* FPSII = dyn_cast(CI)) FPToSIInst::destroyThis(FPSII); - else if(FPToUIInst* FPUII = dyn_cast(this)) + else if(FPToUIInst* FPUII = dyn_cast(CI)) FPToUIInst::destroyThis(FPUII); - else if(FPTruncInst* FPTI = dyn_cast(this)) + else if(FPTruncInst* FPTI = dyn_cast(CI)) FPTruncInst::destroyThis(FPTI); - else if(IntToPtrInst* I2PI = dyn_cast(this)) + else if(IntToPtrInst* I2PI = dyn_cast(CI)) IntToPtrInst::destroyThis(I2PI); - else if(PtrToIntInst* P2II = dyn_cast(this)) + else if(PtrToIntInst* P2II = dyn_cast(CI)) PtrToIntInst::destroyThis(P2II); - else if(SExtInst* SEI = dyn_cast(this)) + else if(SExtInst* SEI = dyn_cast(CI)) SExtInst::destroyThis(SEI); - else if(SIToFPInst* SIFPI = dyn_cast(this)) + else if(SIToFPInst* SIFPI = dyn_cast(CI)) SIToFPInst::destroyThis(SIFPI); - else if(TruncInst* TI = dyn_cast(this)) + else if(TruncInst* TI = dyn_cast(CI)) TruncInst::destroyThis(TI); - else if(UIToFPInst* UIFPI = dyn_cast(this)) + else if(UIToFPInst* UIFPI = dyn_cast(CI)) UIToFPInst::destroyThis(UIFPI); - else if(ZExtInst* ZEI = dyn_cast(this)) + else if(ZExtInst* ZEI = dyn_cast(CI)) ZExtInst::destroyThis(ZEI); else assert(0 && "Unknown CastInst-inherited class in ~Value."); From sabre at nondot.org Sun Dec 9 19:51:22 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 10 Dec 2007 01:51:22 -0000 Subject: [llvm-commits] [llvm] r44756 - /llvm/trunk/lib/VMCore/Value.cpp Message-ID: <200712100151.lBA1pNSi012318@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 9 19:51:22 2007 New Revision: 44756 URL: http://llvm.org/viewvc/llvm-project?rev=44756&view=rev Log: fix some warnings. Modified: llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=44756&r1=44755&r2=44756&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Sun Dec 9 19:51:22 2007 @@ -140,9 +140,9 @@ CallInst::destroyThis(CI); else if (CmpInst *CI = dyn_cast(this)) { - if (FCmpInst *FCI = dyn_cast(this)) + if (FCmpInst *FCI = dyn_cast(CI)) FCmpInst::destroyThis(FCI); - else if (ICmpInst *ICI = dyn_cast(this)) + else if (ICmpInst *ICI = dyn_cast(CI)) ICmpInst::destroyThis(ICI); else assert(0 && "Unknown CmpInst-inherited class in ~Value."); @@ -163,28 +163,25 @@ StoreInst::destroyThis(SI); else if (TerminatorInst *TI = dyn_cast(this)) { - if (BranchInst* BI = dyn_cast(this)) + if (BranchInst* BI = dyn_cast(TI)) BranchInst::destroyThis(BI); - else if (InvokeInst* II = dyn_cast(this)) + else if (InvokeInst* II = dyn_cast(TI)) InvokeInst::destroyThis(II); - else if (ReturnInst* RI = dyn_cast(this)) + else if (ReturnInst* RI = dyn_cast(TI)) ReturnInst::destroyThis(RI); - else if (SwitchInst *SI = dyn_cast(this)) + else if (SwitchInst *SI = dyn_cast(TI)) SwitchInst::destroyThis(SI); - else if (UnreachableInst *UI = dyn_cast(this)) + else if (UnreachableInst *UI = dyn_cast(TI)) UnreachableInst::destroyThis(UI); - else if (UnwindInst *UI = dyn_cast(this)) + else if (UnwindInst *UI = dyn_cast(TI)) UnwindInst::destroyThis(UI); else assert(0 && "Unknown TerminatorInst-inherited class in ~Value."); - } - else if(UnaryInstruction* UI = dyn_cast(this)) - { - if(AllocationInst* AI = dyn_cast(this)) - { - if(AllocaInst* AI = dyn_cast(this)) + } else if(UnaryInstruction* UI = dyn_cast(this)) { + if(AllocationInst* AI = dyn_cast(UI)) { + if(AllocaInst* AI = dyn_cast(UI)) AllocaInst::destroyThis(AI); - else if(MallocInst* MI = dyn_cast(this)) + else if(MallocInst* MI = dyn_cast(UI)) MallocInst::destroyThis(MI); else assert(0 && "Unknown AllocationInst-inherited class in ~Value."); From sabre at nondot.org Sun Dec 9 19:51:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 10 Dec 2007 01:51:38 -0000 Subject: [llvm-commits] [llvm] r44757 - /llvm/trunk/include/llvm/IntrinsicInst.h Message-ID: <200712100151.lBA1pc1n012335@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 9 19:51:38 2007 New Revision: 44757 URL: http://llvm.org/viewvc/llvm-project?rev=44757&view=rev Log: remove some dead code. Modified: llvm/trunk/include/llvm/IntrinsicInst.h Modified: llvm/trunk/include/llvm/IntrinsicInst.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicInst.h?rev=44757&r1=44756&r2=44757&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicInst.h (original) +++ llvm/trunk/include/llvm/IntrinsicInst.h Sun Dec 9 19:51:38 2007 @@ -38,11 +38,6 @@ IntrinsicInst(); // DO NOT IMPLEMENT IntrinsicInst(const IntrinsicInst&); // DO NOT IMPLEMENT void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT - protected: - static void destroyThis(IntrinsicInst* v) { - CallInst::destroyThis(v); - } - friend class Value; public: /// StripPointerCasts - This static method strips off any unneeded pointer @@ -90,11 +85,6 @@ } static Value *StripCast(Value *C); - protected: - static void destroyThis(DbgInfoIntrinsic* v) { - IntrinsicInst::destroyThis(v); - } - friend class Value; }; /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction. @@ -124,11 +114,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(DbgStopPointInst* v) { - DbgInfoIntrinsic::destroyThis(v); - } - friend class Value; }; /// DbgFuncStartInst - This represents the llvm.dbg.func.start instruction. @@ -144,11 +129,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(DbgFuncStartInst* v) { - DbgInfoIntrinsic::destroyThis(v); - } - friend class Value; }; /// DbgRegionStartInst - This represents the llvm.dbg.region.start @@ -164,11 +144,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(DbgRegionStartInst* v) { - DbgInfoIntrinsic::destroyThis(v); - } - friend class Value; }; /// DbgRegionEndInst - This represents the llvm.dbg.region.end instruction. @@ -200,11 +175,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(DbgDeclareInst* v) { - DbgInfoIntrinsic::destroyThis(v); - } - friend class Value; }; /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. @@ -258,11 +228,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(MemIntrinsic* v) { - IntrinsicInst::destroyThis(v); - } - friend class Value; }; @@ -294,11 +259,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(MemCpyInst* v) { - MemIntrinsic::destroyThis(v); - } - friend class Value; }; /// MemMoveInst - This class wraps the llvm.memmove intrinsic. @@ -328,11 +288,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(MemMoveInst* v) { - MemIntrinsic::destroyThis(v); - } - friend class Value; }; /// MemSetInst - This class wraps the llvm.memset intrinsic. @@ -357,11 +312,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - protected: - static void destroyThis(MemSetInst* v) { - MemIntrinsic::destroyThis(v); - } - friend class Value; }; } From gordonhenriksen at mac.com Sun Dec 9 20:14:32 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 10 Dec 2007 02:14:32 -0000 Subject: [llvm-commits] [llvm] r44760 - in /llvm/trunk: include/llvm/ lib/VMCore/ Message-ID: <200712100214.lBA2EXrn013278@zion.cs.uiuc.edu> Author: gordon Date: Sun Dec 9 20:14:30 2007 New Revision: 44760 URL: http://llvm.org/viewvc/llvm-project?rev=44760&view=rev Log: Reverting dtor devirtualization patch. _sabre_: it has a major problem: by the time ~Value is run, all of the "parts" of the derived classes have been destroyed _sabre_: the vtable lives to fight another day Modified: llvm/trunk/include/llvm/Argument.h llvm/trunk/include/llvm/BasicBlock.h llvm/trunk/include/llvm/Constant.h llvm/trunk/include/llvm/Constants.h llvm/trunk/include/llvm/Function.h llvm/trunk/include/llvm/GlobalAlias.h llvm/trunk/include/llvm/GlobalValue.h llvm/trunk/include/llvm/GlobalVariable.h llvm/trunk/include/llvm/InlineAsm.h llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/include/llvm/Instruction.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/User.h llvm/trunk/include/llvm/Value.h llvm/trunk/lib/VMCore/BasicBlock.cpp llvm/trunk/lib/VMCore/Constants.cpp llvm/trunk/lib/VMCore/Function.cpp llvm/trunk/lib/VMCore/InlineAsm.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/include/llvm/Argument.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Argument.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Argument.h (original) +++ llvm/trunk/include/llvm/Argument.h Sun Dec 9 20:14:30 2007 @@ -35,11 +35,6 @@ friend class SymbolTableListTraits; void setParent(Function *parent); -protected: - static void destroyThis(Argument*v) { - Value::destroyThis(v); - } - friend class Value; public: /// Argument ctor - If Function argument is specified, this argument is /// inserted at the end of the argument list for the function. Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Sun Dec 9 20:14:30 2007 @@ -65,9 +65,6 @@ BasicBlock(const BasicBlock &); // Do not implement void operator=(const BasicBlock &); // Do not implement -protected: - static void destroyThis(BasicBlock*); - friend class Value; public: /// Instruction iterators... typedef InstListType::iterator iterator; @@ -79,6 +76,7 @@ /// explicit BasicBlock(const std::string &Name = "", Function *Parent = 0, BasicBlock *InsertBefore = 0); + ~BasicBlock(); /// getParent - Return the enclosing method, or null if none /// @@ -208,33 +206,6 @@ const BasicBlock *getPrev() const { return Prev; } }; -/// DummyInst - An instance of this class is used to mark the end of the -/// instruction list. This is not a real instruction. -class DummyInst : public Instruction { -protected: - static void destroyThis(DummyInst* v) { - Instruction::destroyThis(v); - } - friend class Value; -public: - DummyInst(); - - Instruction *clone() const { - assert(0 && "Cannot clone EOL");abort(); - return 0; - } - const char *getOpcodeName() const { return "*end-of-list-inst*"; } - - // Methods for support type inquiry through isa, cast, and dyn_cast... - static inline bool classof(const DummyInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == OtherOpsEnd; - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - inline int ilist_traits::getListOffset() { return BasicBlock::getInstListOffset(); Modified: llvm/trunk/include/llvm/Constant.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constant.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constant.h (original) +++ llvm/trunk/include/llvm/Constant.h Sun Dec 9 20:14:30 2007 @@ -43,10 +43,6 @@ : User(Ty, vty, Ops, NumOps) {} void destroyConstantImpl(); - static void destroyThis(Constant*v) { - User::destroyThis(v); - } - friend class Value; public: /// Static constructor to get a '0' constant of arbitrary type... /// Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Sun Dec 9 20:14:30 2007 @@ -46,11 +46,6 @@ ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT ConstantInt(const IntegerType *Ty, const APInt& V); APInt Val; -protected: - static void destroyThis(ConstantInt*v) { - Constant::destroyThis(v); - } - friend class Value; public: /// Return the constant as an APInt value reference. This allows clients to /// obtain a copy of the value, with all its precision in tact. @@ -223,10 +218,6 @@ ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT protected: ConstantFP(const Type *Ty, const APFloat& V); - static void destroyThis(ConstantFP*v) { - Constant::destroyThis(v); - } - friend class Value; public: /// get() - Static factory methods - Return objects of the specified value static ConstantFP *get(const Type *Ty, const APFloat& V); @@ -275,11 +266,6 @@ protected: explicit ConstantAggregateZero(const Type *Ty) : Constant(Ty, ConstantAggregateZeroVal, 0, 0) {} - - static void destroyThis(ConstantAggregateZero*v) { - Constant::destroyThis(v); - } - friend class Value; public: /// get() - static factory method for creating a null aggregate. It is /// illegal to call this method with a non-aggregate type. @@ -309,8 +295,7 @@ ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT protected: ConstantArray(const ArrayType *T, const std::vector &Val); - static void destroyThis(ConstantArray*); - friend class Value; + ~ConstantArray(); public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const ArrayType *T, const std::vector &); @@ -376,8 +361,7 @@ ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT protected: ConstantStruct(const StructType *T, const std::vector &Val); - static void destroyThis(ConstantStruct*); - friend class Value; + ~ConstantStruct(); public: /// get() - Static factory methods - Return objects of the specified value /// @@ -421,8 +405,7 @@ ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT protected: ConstantVector(const VectorType *T, const std::vector &Val); - static void destroyThis(ConstantVector*v); - friend class Value; + ~ConstantVector(); public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const VectorType *T, const std::vector &); @@ -479,10 +462,7 @@ explicit ConstantPointerNull(const PointerType *T) : Constant(reinterpret_cast(T), Value::ConstantPointerNullVal, 0, 0) {} - static void destroyThis(ConstantPointerNull*v) { - Constant::destroyThis(v); - } - friend class Value; + public: /// get() - Static factory methods - Return objects of the specified value @@ -544,10 +524,6 @@ static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1, Constant *V2, Constant *Mask); - static void destroyThis(ConstantExpr* v) { - Constant::destroyThis(v); - } - friend class Value; public: // Static methods to construct a ConstantExpr of different kinds. Note that // these methods may return a object that is not an instance of the @@ -733,10 +709,6 @@ UndefValue(const UndefValue &); // DO NOT IMPLEMENT protected: explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {} - static void destroyThis(UndefValue*v) { - Constant::destroyThis(v); - } - friend class Value; public: /// get() - Static factory methods - Return an 'undef' object of the specified /// type. @@ -756,120 +728,6 @@ } }; -/// GetElementPtrConstantExpr - Helper class for Constants.cpp, -/// used behind the scenes to implement getelementpr constant exprs. -class GetElementPtrConstantExpr : public ConstantExpr { -protected: - static void destroyThis(GetElementPtrConstantExpr*v) { - delete [] v->OperandList; - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, - const Type *DestTy); -}; - -/// UnaryConstantExpr - Helper class for Constants.cpp, used -/// behind the scenes to implement unary constant exprs. -class UnaryConstantExpr : public ConstantExpr { - Use Op; -protected: - static void destroyThis(UnaryConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty); -}; - -/// BinaryConstantExpr - Helper class for Constants.cpp, used -/// behind the scenes to implement binary constant exprs. -class BinaryConstantExpr : public ConstantExpr { - Use Ops[2]; -protected: - static void destroyThis(BinaryConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) - : ConstantExpr(C1->getType(), Opcode, Ops, 2) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - } -}; - -/// SelectConstantExpr - Helper class for Constants.cpp, used -/// behind the scenes to implement select constant exprs. -class SelectConstantExpr : public ConstantExpr { - Use Ops[3]; -protected: - static void destroyThis(SelectConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3); -}; - -/// ExtractElementConstantExpr - Helper class for Constants.cpp, used -/// behind the scenes to implement extractelement constant exprs. -class ExtractElementConstantExpr : public ConstantExpr { - Use Ops[2]; -protected: - static void destroyThis(ExtractElementConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - ExtractElementConstantExpr(Constant *C1, Constant *C2); -}; - -/// InsertElementConstantExpr - Helper class for Constants.cpp, used -/// behind the scenes to implement insertelement constant exprs. -class InsertElementConstantExpr : public ConstantExpr { - Use Ops[3]; -protected: - static void destroyThis(InsertElementConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3); -}; - -/// ShuffleVectorConstantExpr - Helper class for Constants.cpp, used -/// behind the scenes to implement shufflevector constant exprs. -class ShuffleVectorConstantExpr : public ConstantExpr { - Use Ops[3]; -protected: - static void destroyThis(ShuffleVectorConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3); -}; - - - -// CompareConstantExpr - Helper class for Constants.cpp, used -// behind the scenes to implement ICmp and FCmp constant expressions. This is -// needed in order to store the predicate value for these instructions. -class CompareConstantExpr : public ConstantExpr { -protected: - static void destroyThis(CompareConstantExpr*v) { - ConstantExpr::destroyThis(v); - } - friend class Value; -public: - unsigned short predicate; - Use Ops[2]; - CompareConstantExpr(unsigned opc, unsigned short pred, - Constant* LHS, Constant* RHS); -}; - } // End llvm namespace #endif Modified: llvm/trunk/include/llvm/Function.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Function.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Function.h (original) +++ llvm/trunk/include/llvm/Function.h Sun Dec 9 20:14:30 2007 @@ -53,9 +53,6 @@ }; class Function : public GlobalValue, public Annotable { -protected: - static void destroyThis(Function*v); - friend class Value; public: typedef iplist ArgumentListType; typedef iplist BasicBlockListType; @@ -112,6 +109,7 @@ /// Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &N = "", Module *M = 0); + ~Function(); const Type *getReturnType() const; // Return the type of the ret val const FunctionType *getFunctionType() const; // Return the FunctionType for me Modified: llvm/trunk/include/llvm/GlobalAlias.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalAlias.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalAlias.h (original) +++ llvm/trunk/include/llvm/GlobalAlias.h Sun Dec 9 20:14:30 2007 @@ -43,11 +43,6 @@ const GlobalAlias *getPrev() const { return Prev; } Use Aliasee; -protected: - static void destroyThis(GlobalAlias*v) { - GlobalValue::destroyThis(v); - } - friend class Value; public: /// GlobalAlias ctor - If a parent module is specified, the alias is /// automatically inserted into the end of the specified module's alias list. Modified: llvm/trunk/include/llvm/GlobalValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalValue.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalValue.h (original) +++ llvm/trunk/include/llvm/GlobalValue.h Sun Dec 9 20:14:30 2007 @@ -63,12 +63,11 @@ unsigned Visibility : 2; // The visibility style of this global unsigned Alignment : 16; // Alignment of this symbol, must be power of two std::string Section; // Section to emit this into, empty mean default - - static void destroyThis(GlobalValue*v) { - v->removeDeadConstantUsers(); // remove any dead constants using this. - Constant::destroyThis(v); - } public: + ~GlobalValue() { + removeDeadConstantUsers(); // remove any dead constants using this. + } + unsigned getAlignment() const { return Alignment; } void setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); Modified: llvm/trunk/include/llvm/GlobalVariable.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalVariable.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalVariable.h (original) +++ llvm/trunk/include/llvm/GlobalVariable.h Sun Dec 9 20:14:30 2007 @@ -45,11 +45,6 @@ bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"? Use Initializer; -protected: - static void destroyThis(GlobalVariable*v) { - GlobalValue::destroyThis(v); - } - friend class Value; public: /// GlobalVariable ctor - If a parent module is specified, the global is /// automatically inserted into the end of the specified modules global list. Modified: llvm/trunk/include/llvm/InlineAsm.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InlineAsm.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/InlineAsm.h (original) +++ llvm/trunk/include/llvm/InlineAsm.h Sun Dec 9 20:14:30 2007 @@ -36,12 +36,9 @@ InlineAsm(const FunctionType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects); -protected: - static void destroyThis(InlineAsm*v) { - Value::destroyThis(v); - } - friend class Value; + virtual ~InlineAsm(); public: + /// InlineAsm::get - Return the the specified uniqued inline asm string. /// static InlineAsm *get(const FunctionType *Ty, const std::string &AsmString, Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Sun Dec 9 20:14:30 2007 @@ -38,16 +38,14 @@ Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} + // Out of line virtual method, so the vtable, etc has a home. + ~TerminatorInst(); + /// Virtual methods - Terminators should overload these and provide inline /// overrides of non-V methods. virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; - - static void destroyThis(TerminatorInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: virtual Instruction *clone() const = 0; @@ -96,12 +94,10 @@ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE) : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this_()) { } - - static void destroyThis(UnaryInstruction* v) { - Instruction::destroyThis(v); - } - friend class Value; public: + // Out of line virtual method, so the vtable, etc has a home. + ~UnaryInstruction(); + // Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { assert(i == 0 && "getOperand() out of range!"); @@ -140,11 +136,6 @@ const std::string &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd); - - static void destroyThis(BinaryOperator* v) { - Instruction::destroyThis(v); - } - friend class Value; public: /// Transparently provide more efficient getOperand methods. @@ -281,12 +272,6 @@ : UnaryInstruction(Ty, iType, S, InsertAtEnd) { setName(Name); } - -protected: - static void destroyThis(CastInst* v) { - UnaryInstruction::destroyThis(v); - } - friend class Value; public: /// Provides a way to construct any of the CastInst subclasses using an /// opcode instead of the subclass's constructor. The opcode must be in the @@ -508,10 +493,6 @@ Use Ops[2]; // CmpInst instructions always have 2 operands, optimize - static void destroyThis(CmpInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: /// Construct a compare instruction, given the opcode, the predicate and /// the two operands. Optionally (if InstBefore is specified) insert the Modified: llvm/trunk/include/llvm/Instruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.h (original) +++ llvm/trunk/include/llvm/Instruction.h Sun Dec 9 20:14:30 2007 @@ -42,10 +42,10 @@ Instruction *InsertBefore = 0); Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); - - static void destroyThis(Instruction*v); - friend class Value; public: + // Out of line virtual method, so the vtable, etc has a home. + ~Instruction(); + /// mayWriteToMemory - Return true if this instruction may modify memory. /// bool mayWriteToMemory() const; Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Sun Dec 9 20:14:30 2007 @@ -47,6 +47,9 @@ AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd); public: + // Out of line virtual method, so the vtable, etc has a home. + virtual ~AllocationInst(); + /// isArrayAllocation - Return true if there is an allocation size parameter /// to the allocation instruction that is not 1. /// @@ -187,11 +190,6 @@ /// class FreeInst : public UnaryInstruction { void AssertOK(); -protected: - static void destroyThis(FreeInst* v) { - UnaryInstruction::destroyThis(v); - } - friend class Value; public: explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); FreeInst(Value *Ptr, BasicBlock *InsertAfter); @@ -232,11 +230,6 @@ #endif } void AssertOK(); -protected: - static void destroyThis(LoadInst* v) { - UnaryInstruction::destroyThis(v); - } - friend class Value; public: LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); @@ -312,11 +305,6 @@ #endif } void AssertOK(); -protected: - static void destroyThis(StoreInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); @@ -455,9 +443,6 @@ } } -protected: - static void destroyThis(GetElementPtrInst*v); - friend class Value; public: /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing @@ -492,6 +477,7 @@ const std::string &Name = "", Instruction *InsertBefore =0); GetElementPtrInst(Value *Ptr, Value *Idx, const std::string &Name, BasicBlock *InsertAtEnd); + ~GetElementPtrInst(); virtual GetElementPtrInst *clone() const; @@ -570,11 +556,6 @@ /// vectors of integrals. The two operands must be the same type. /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { -protected: - static void destroyThis(ICmpInst* v) { - CmpInst::destroyThis(v); - } - friend class Value; public: /// This enumeration lists the possible predicates for the ICmpInst. The /// values in the range 0-31 are reserved for FCmpInst while values in the @@ -731,11 +712,6 @@ /// vectors of floating point values. The operands must be identical types. /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { -protected: - static void destroyThis(FCmpInst* v) { - CmpInst::destroyThis(v); - } - friend class Value; public: /// This enumeration lists the possible predicates for the FCmpInst. Values /// in the range 0-31 are reserved for FCmpInst. @@ -881,9 +857,6 @@ setName(Name); } -protected: - static void destroyThis(CallInst*v); - friend class Value; public: /// Construct a CallInst given a range of arguments. InputIterator /// must be a random-access iterator pointing to contiguous storage @@ -924,6 +897,7 @@ explicit CallInst(Value *F, const std::string &Name = "", Instruction *InsertBefore = 0); CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd); + ~CallInst(); virtual CallInst *clone() const; @@ -1015,11 +989,6 @@ : Instruction(SI.getType(), SI.getOpcode(), Ops, 3) { init(SI.Ops[0], SI.Ops[1], SI.Ops[2]); } -protected: - static void destroyThis(SelectInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1075,11 +1044,6 @@ class VAArgInst : public UnaryInstruction { VAArgInst(const VAArgInst &VAA) : UnaryInstruction(VAA.getType(), VAArg, VAA.getOperand(0)) {} -protected: - static void destroyThis(VAArgInst* v) { - UnaryInstruction::destroyThis(v); - } - friend class Value; public: VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1119,11 +1083,6 @@ Ops[1].init(EE.Ops[1], this); } -protected: - static void destroyThis(ExtractElementInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name = "", Instruction *InsertBefore = 0); @@ -1171,11 +1130,6 @@ class InsertElementInst : public Instruction { Use Ops[3]; InsertElementInst(const InsertElementInst &IE); -protected: - static void destroyThis(InsertElementInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const std::string &Name = "",Instruction *InsertBefore = 0); @@ -1230,11 +1184,6 @@ class ShuffleVectorInst : public Instruction { Use Ops[3]; ShuffleVectorInst(const ShuffleVectorInst &IE); -protected: - static void destroyThis(ShuffleVectorInst* v) { - Instruction::destroyThis(v); - } - friend class Value; public: ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const std::string &Name = "", Instruction *InsertBefor = 0); @@ -1289,9 +1238,6 @@ /// the number actually in use. unsigned ReservedSpace; PHINode(const PHINode &PN); -protected: - static void destroyThis(PHINode*); - friend class Value; public: explicit PHINode(const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) @@ -1306,6 +1252,8 @@ setName(Name); } + ~PHINode(); + /// reserveOperandSpace - This method can be used to avoid repeated /// reallocation of PHI operand lists by reserving space for the correct /// number of operands before adding them. Unlike normal vector reserves, @@ -1574,9 +1522,6 @@ SwitchInst(const SwitchInst &RI); void init(Value *Value, BasicBlock *Default, unsigned NumCases); void resizeOperands(unsigned No); -protected: - static void destroyThis(SwitchInst*v); - friend class Value; public: /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can @@ -1591,6 +1536,7 @@ /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); + ~SwitchInst(); // Accessor Methods for Switch stmt @@ -1718,9 +1664,6 @@ setName(Name); } -protected: - static void destroyThis(InvokeInst*v); - friend class Value; public: /// Construct an InvokeInst given a range of arguments. /// InputIterator must be a random-access iterator pointing to @@ -1758,6 +1701,8 @@ typename std::iterator_traits::iterator_category()); } + ~InvokeInst(); + virtual InvokeInst *clone() const; /// getCallingConv/setCallingConv - Get or set the calling convention of this @@ -1927,11 +1872,6 @@ TruncInst(const TruncInst &CI) : CastInst(CI.getType(), Trunc, CI.getOperand(0)) { } -protected: - static void destroyThis(TruncInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics TruncInst( @@ -1972,11 +1912,6 @@ ZExtInst(const ZExtInst &CI) : CastInst(CI.getType(), ZExt, CI.getOperand(0)) { } -protected: - static void destroyThis(ZExtInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics ZExtInst( @@ -2017,11 +1952,6 @@ SExtInst(const SExtInst &CI) : CastInst(CI.getType(), SExt, CI.getOperand(0)) { } -protected: - static void destroyThis(SExtInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics SExtInst( @@ -2061,11 +1991,6 @@ FPTruncInst(const FPTruncInst &CI) : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) { } -protected: - static void destroyThis(FPTruncInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPTruncInst( @@ -2105,11 +2030,6 @@ FPExtInst(const FPExtInst &CI) : CastInst(CI.getType(), FPExt, CI.getOperand(0)) { } -protected: - static void destroyThis(FPExtInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPExtInst( @@ -2149,11 +2069,6 @@ UIToFPInst(const UIToFPInst &CI) : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) { } -protected: - static void destroyThis(UIToFPInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics UIToFPInst( @@ -2193,11 +2108,6 @@ SIToFPInst(const SIToFPInst &CI) : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) { } -protected: - static void destroyThis(SIToFPInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics SIToFPInst( @@ -2237,11 +2147,6 @@ FPToUIInst(const FPToUIInst &CI) : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) { } -protected: - static void destroyThis(FPToUIInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPToUIInst( @@ -2281,11 +2186,6 @@ FPToSIInst(const FPToSIInst &CI) : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) { } -protected: - static void destroyThis(FPToSIInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics FPToSIInst( @@ -2325,11 +2225,6 @@ IntToPtrInst(const IntToPtrInst &CI) : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) { } -protected: - static void destroyThis(IntToPtrInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics IntToPtrInst( @@ -2369,11 +2264,6 @@ PtrToIntInst(const PtrToIntInst &CI) : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) { } -protected: - static void destroyThis(PtrToIntInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics PtrToIntInst( @@ -2413,11 +2303,6 @@ BitCastInst(const BitCastInst &CI) : CastInst(CI.getType(), BitCast, CI.getOperand(0)) { } -protected: - static void destroyThis(BitCastInst* v) { - CastInst::destroyThis(v); - } - friend class Value; public: /// @brief Constructor with insert-before-instruction semantics BitCastInst( Modified: llvm/trunk/include/llvm/User.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/User.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/User.h (original) +++ llvm/trunk/include/llvm/User.h Sun Dec 9 20:14:30 2007 @@ -37,10 +37,6 @@ /// unsigned NumOperands; - static void destroyThis(User*v) { - Value::destroyThis(v); - } - friend class Value; public: User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps) : Value(Ty, vty), OperandList(OpList), NumOperands(NumOps) {} Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Sun Dec 9 20:14:30 2007 @@ -66,11 +66,8 @@ friend class SymbolTable; // Allow SymbolTable to directly poke Name. ValueName *Name; -private: void operator=(const Value &); // Do not implement Value(const Value &); // Do not implement -protected: - static void destroyThis(Value*); public: Value(const Type *Ty, unsigned scid); Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/BasicBlock.cpp (original) +++ llvm/trunk/lib/VMCore/BasicBlock.cpp Sun Dec 9 20:14:30 2007 @@ -30,9 +30,31 @@ return 0; } -DummyInst::DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd, 0, 0) { - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(this); + +namespace { + /// DummyInst - An instance of this class is used to mark the end of the + /// instruction list. This is not a real instruction. + struct VISIBILITY_HIDDEN DummyInst : public Instruction { + DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd, 0, 0) { + // This should not be garbage monitored. + LeakDetector::removeGarbageObject(this); + } + + Instruction *clone() const { + assert(0 && "Cannot clone EOL");abort(); + return 0; + } + const char *getOpcodeName() const { return "*end-of-list-inst*"; } + + // Methods for support type inquiry through isa, cast, and dyn_cast... + static inline bool classof(const DummyInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == OtherOpsEnd; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; } Instruction *ilist_traits::createSentinel() { @@ -66,12 +88,10 @@ } -void BasicBlock::destroyThis(BasicBlock*v) -{ - assert(v->getParent() == 0 && "BasicBlock still linked into the program!"); - v->dropAllReferences(); - v->InstList.clear(); - Value::destroyThis(v); +BasicBlock::~BasicBlock() { + assert(getParent() == 0 && "BasicBlock still linked into the program!"); + dropAllReferences(); + InstList.clear(); } void BasicBlock::setParent(Function *parent) { Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Sun Dec 9 20:14:30 2007 @@ -356,9 +356,8 @@ } } -void ConstantArray::destroyThis(ConstantArray*v) { - delete [] v->OperandList; - Constant::destroyThis(v); +ConstantArray::~ConstantArray() { + delete [] OperandList; } ConstantStruct::ConstantStruct(const StructType *T, @@ -380,9 +379,8 @@ } } -void ConstantStruct::destroyThis(ConstantStruct*v) { - delete [] v->OperandList; - Constant::destroyThis(v); +ConstantStruct::~ConstantStruct() { + delete [] OperandList; } @@ -401,68 +399,125 @@ } } -void ConstantVector::destroyThis(ConstantVector*v) { - delete [] v->OperandList; - Constant::destroyThis(v); -} - -UnaryConstantExpr::UnaryConstantExpr(unsigned Opcode, - Constant *C, const Type *Ty) - : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) { -} - -SelectConstantExpr::SelectConstantExpr(Constant *C1, - Constant *C2, Constant *C3) - : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); -} - -ExtractElementConstantExpr::ExtractElementConstantExpr(Constant *C1, - Constant *C2) - : ConstantExpr(cast(C1->getType())->getElementType(), - Instruction::ExtractElement, Ops, 2) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); -} - -InsertElementConstantExpr::InsertElementConstantExpr(Constant *C1, - Constant *C2, - Constant *C3) - : ConstantExpr(C1->getType(), Instruction::InsertElement, Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); -} - -ShuffleVectorConstantExpr::ShuffleVectorConstantExpr(Constant *C1, - Constant *C2, - Constant *C3) - : ConstantExpr(C1->getType(), Instruction::ShuffleVector, Ops, 3) { - Ops[0].init(C1, this); - Ops[1].init(C2, this); - Ops[2].init(C3, this); -} - -CompareConstantExpr::CompareConstantExpr(unsigned opc, unsigned short pred, - Constant* LHS, Constant* RHS) - : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) { - OperandList[0].init(LHS, this); - OperandList[1].init(RHS, this); -} - -GetElementPtrConstantExpr::GetElementPtrConstantExpr(Constant *C, - const std::vector - &IdxList, const Type *DestTy) -: ConstantExpr(DestTy, Instruction::GetElementPtr, - new Use[IdxList.size()+1], IdxList.size()+1) -{ - OperandList[0].init(C, this); - for (unsigned i = 0, E = IdxList.size(); i != E; ++i) - OperandList[i+1].init(IdxList[i], this); +ConstantVector::~ConstantVector() { + delete [] OperandList; } +// We declare several classes private to this file, so use an anonymous +// namespace +namespace { + +/// UnaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement unary constant exprs. +class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr { + Use Op; +public: + UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) + : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {} +}; + +/// BinaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement binary constant exprs. +class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr { + Use Ops[2]; +public: + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) + : ConstantExpr(C1->getType(), Opcode, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + } +}; + +/// SelectConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement select constant exprs. +class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr { + Use Ops[3]; +public: + SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); + } +}; + +/// ExtractElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractelement constant exprs. +class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr { + Use Ops[2]; +public: + ExtractElementConstantExpr(Constant *C1, Constant *C2) + : ConstantExpr(cast(C1->getType())->getElementType(), + Instruction::ExtractElement, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + } +}; + +/// InsertElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertelement constant exprs. +class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr { + Use Ops[3]; +public: + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, + Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); + } +}; + +/// ShuffleVectorConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// shufflevector constant exprs. +class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr { + Use Ops[3]; +public: + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::ShuffleVector, + Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); + } +}; + +/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is +/// used behind the scenes to implement getelementpr constant exprs. +struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr { + GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, + const Type *DestTy) + : ConstantExpr(DestTy, Instruction::GetElementPtr, + new Use[IdxList.size()+1], IdxList.size()+1) { + OperandList[0].init(C, this); + for (unsigned i = 0, E = IdxList.size(); i != E; ++i) + OperandList[i+1].init(IdxList[i], this); + } + ~GetElementPtrConstantExpr() { + delete [] OperandList; + } +}; + +// CompareConstantExpr - This class is private to Constants.cpp, and is used +// behind the scenes to implement ICmp and FCmp constant expressions. This is +// needed in order to store the predicate value for these instructions. +struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr { + unsigned short predicate; + Use Ops[2]; + CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, + Constant* LHS, Constant* RHS) + : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) { + OperandList[0].init(LHS, this); + OperandList[1].init(RHS, this); + } +}; + +} // end anonymous namespace + + // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into // Constant.h Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Sun Dec 9 20:14:30 2007 @@ -287,17 +287,16 @@ ParentModule->getFunctionList().push_back(this); } -void Function::destroyThis(Function*v) { - v->dropAllReferences(); // After this it is safe to delete instructions. +Function::~Function() { + dropAllReferences(); // After this it is safe to delete instructions. // Delete all of the method arguments and unlink from symbol table... - v->ArgumentList.clear(); - delete v->SymTab; + ArgumentList.clear(); + delete SymTab; // Drop our reference to the parameter attributes, if any. - if (v->ParamAttrs) - v->ParamAttrs->dropRef(); - GlobalValue::destroyThis(v); + if (ParamAttrs) + ParamAttrs->dropRef(); } void Function::BuildLazyArguments() const { Modified: llvm/trunk/lib/VMCore/InlineAsm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/InlineAsm.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/InlineAsm.cpp (original) +++ llvm/trunk/lib/VMCore/InlineAsm.cpp Sun Dec 9 20:14:30 2007 @@ -17,6 +17,12 @@ #include using namespace llvm; +// Implement the first virtual method in this class in this file so the +// InlineAsm vtable is emitted here. +InlineAsm::~InlineAsm() { +} + + // NOTE: when memoizing the function type, we have to be careful to handle the // case when the type gets refined. Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Sun Dec 9 20:14:30 2007 @@ -46,8 +46,8 @@ // Out of line virtual method, so the vtable, etc has a home. -void Instruction::destroyThis(Instruction*v) { - assert(v->Parent == 0 && "Instruction still linked in the program!"); +Instruction::~Instruction() { + assert(Parent == 0 && "Instruction still linked in the program!"); } Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Sun Dec 9 20:14:30 2007 @@ -67,6 +67,20 @@ } + +//===----------------------------------------------------------------------===// +// TerminatorInst Class +//===----------------------------------------------------------------------===// + +// Out of line virtual method, so the vtable, etc has a home. +TerminatorInst::~TerminatorInst() { +} + +// Out of line virtual method, so the vtable, etc has a home. +UnaryInstruction::~UnaryInstruction() { +} + + //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -82,9 +96,8 @@ } } -void PHINode::destroyThis(PHINode*v) { - delete [] v->OperandList; - Instruction::destroyThis(v); +PHINode::~PHINode() { + delete [] OperandList; } // removeIncomingValue - Remove an incoming value. This is useful if a @@ -201,11 +214,10 @@ // CallInst Implementation //===----------------------------------------------------------------------===// -void CallInst::destroyThis(CallInst*v) { - delete [] v->OperandList; - if (v->ParamAttrs) - v->ParamAttrs->dropRef(); - Instruction::destroyThis(v); +CallInst::~CallInst() { + delete [] OperandList; + if (ParamAttrs) + ParamAttrs->dropRef(); } void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { @@ -394,11 +406,10 @@ // InvokeInst Implementation //===----------------------------------------------------------------------===// -void InvokeInst::destroyThis(InvokeInst*v) { - delete [] v->OperandList; - if (v->ParamAttrs) - v->ParamAttrs->dropRef(); - TerminatorInst::destroyThis(v); +InvokeInst::~InvokeInst() { + delete [] OperandList; + if (ParamAttrs) + ParamAttrs->dropRef(); } void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, @@ -672,6 +683,10 @@ setName(Name); } +// Out of line virtual method, so the vtable, etc has a home. +AllocationInst::~AllocationInst() { +} + bool AllocationInst::isArrayAllocation() const { if (ConstantInt *CI = dyn_cast(getOperand(0))) return CI->getZExtValue() != 1; @@ -936,8 +951,8 @@ setName(Name); } -void GetElementPtrInst::destroyThis(GetElementPtrInst*v) { - delete[] v->OperandList; +GetElementPtrInst::~GetElementPtrInst() { + delete[] OperandList; } // getIndexedType - Returns the type of the element that would be loaded with @@ -2454,9 +2469,8 @@ } } -void SwitchInst::destroyThis(SwitchInst*v) { - delete [] v->OperandList; - TerminatorInst::destroyThis(v); +SwitchInst::~SwitchInst() { + delete [] OperandList; } Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=44760&r1=44759&r2=44760&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Sun Dec 9 20:14:30 2007 @@ -18,11 +18,6 @@ #include "llvm/ValueSymbolTable.h" #include "llvm/Support/Debug.h" #include "llvm/Support/LeakDetector.h" -#include "llvm/Constants.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/InstrTypes.h" #include using namespace llvm; @@ -44,194 +39,7 @@ "Cannot create non-first-class values except for constants!"); } -Value::~Value() -{ - switch(SubclassID) - { - case ArgumentVal: - Argument::destroyThis(cast(this)); - break; - case BasicBlockVal: - BasicBlock::destroyThis(cast(this)); - break; - case FunctionVal: - Function::destroyThis(cast(this)); - break; - case GlobalAliasVal: - GlobalAlias::destroyThis(cast(this)); - break; - case GlobalVariableVal: - GlobalVariable::destroyThis(cast(this)); - break; - case UndefValueVal: - UndefValue::destroyThis(cast(this)); - break; - case ConstantExprVal: - { - ConstantExpr* CE = dyn_cast(this); - if(CE->getOpcode() == Instruction::GetElementPtr) - { - GetElementPtrConstantExpr* GECE = - dyn_cast(CE); - GetElementPtrConstantExpr::destroyThis(GECE); - } - else if(CE->getOpcode() == Instruction::ExtractElement) - { - ExtractElementConstantExpr* EECE = - dyn_cast(CE); - ExtractElementConstantExpr::destroyThis(EECE); - } - else if(CE->getOpcode() == Instruction::InsertElement) - { - InsertElementConstantExpr* IECE = - dyn_cast(CE); - InsertElementConstantExpr::destroyThis(IECE); - } - else if(CE->getOpcode() == Instruction::Select) - { - SelectConstantExpr* SCE = dyn_cast(CE); - SelectConstantExpr::destroyThis(SCE); - } - else if(CE->getOpcode() == Instruction::ShuffleVector) - { - ShuffleVectorConstantExpr* SVCE = - dyn_cast(CE); - ShuffleVectorConstantExpr::destroyThis(SVCE); - } - else if(BinaryConstantExpr* BCE = dyn_cast(this)) - BinaryConstantExpr::destroyThis(BCE); - else if(UnaryConstantExpr* UCE = dyn_cast(this)) - UnaryConstantExpr::destroyThis(UCE); - else if(CompareConstantExpr* CCE = dyn_cast(this)) - CompareConstantExpr::destroyThis(CCE); - else - assert(0 && "Unknown ConstantExpr-inherited class in ~Value."); - } - break; - case ConstantAggregateZeroVal: - ConstantAggregateZero::destroyThis(cast(this)); - break; - case ConstantIntVal: - ConstantInt::destroyThis(cast(this)); - break; - case ConstantFPVal: - ConstantFP::destroyThis(cast(this)); - break; - case ConstantArrayVal: - ConstantArray::destroyThis(cast(this)); - break; - case ConstantStructVal: - ConstantStruct::destroyThis(cast(this)); - break; - case ConstantVectorVal: - ConstantVector::destroyThis(cast(this)); - break; - case ConstantPointerNullVal: - ConstantPointerNull::destroyThis(cast(this)); - break; - case InlineAsmVal: - InlineAsm::destroyThis(cast(this)); - break; - - default: - if (BinaryOperator *BO = dyn_cast(this)) - BinaryOperator::destroyThis(BO); - else if (CallInst *CI = dyn_cast(this)) - CallInst::destroyThis(CI); - else if (CmpInst *CI = dyn_cast(this)) - { - if (FCmpInst *FCI = dyn_cast(CI)) - FCmpInst::destroyThis(FCI); - else if (ICmpInst *ICI = dyn_cast(CI)) - ICmpInst::destroyThis(ICI); - else - assert(0 && "Unknown CmpInst-inherited class in ~Value."); - } - else if (ExtractElementInst *EEI = dyn_cast(this)) - ExtractElementInst::destroyThis(EEI); - else if (GetElementPtrInst *GEP = dyn_cast(this)) - GetElementPtrInst::destroyThis(GEP); - else if (InsertElementInst* IE = dyn_cast(this)) - InsertElementInst::destroyThis(IE); - else if (PHINode *PN = dyn_cast(this)) - PHINode::destroyThis(PN); - else if (SelectInst *SI = dyn_cast(this)) - SelectInst::destroyThis(SI); - else if (ShuffleVectorInst *SVI = dyn_cast(this)) - ShuffleVectorInst::destroyThis(SVI); - else if (StoreInst *SI = dyn_cast(this)) - StoreInst::destroyThis(SI); - else if (TerminatorInst *TI = dyn_cast(this)) - { - if (BranchInst* BI = dyn_cast(TI)) - BranchInst::destroyThis(BI); - else if (InvokeInst* II = dyn_cast(TI)) - InvokeInst::destroyThis(II); - else if (ReturnInst* RI = dyn_cast(TI)) - ReturnInst::destroyThis(RI); - else if (SwitchInst *SI = dyn_cast(TI)) - SwitchInst::destroyThis(SI); - else if (UnreachableInst *UI = dyn_cast(TI)) - UnreachableInst::destroyThis(UI); - else if (UnwindInst *UI = dyn_cast(TI)) - UnwindInst::destroyThis(UI); - else - assert(0 && "Unknown TerminatorInst-inherited class in ~Value."); - } else if(UnaryInstruction* UI = dyn_cast(this)) { - if(AllocationInst* AI = dyn_cast(UI)) { - if(AllocaInst* AI = dyn_cast(UI)) - AllocaInst::destroyThis(AI); - else if(MallocInst* MI = dyn_cast(UI)) - MallocInst::destroyThis(MI); - else - assert(0 && "Unknown AllocationInst-inherited class in ~Value."); - } else if(CastInst* CI = dyn_cast(this)) { - if(BitCastInst* BCI = dyn_cast(CI)) - BitCastInst::destroyThis(BCI); - else if(FPExtInst* FPEI = dyn_cast(CI)) - FPExtInst::destroyThis(FPEI); - else if(FPToSIInst* FPSII = dyn_cast(CI)) - FPToSIInst::destroyThis(FPSII); - else if(FPToUIInst* FPUII = dyn_cast(CI)) - FPToUIInst::destroyThis(FPUII); - else if(FPTruncInst* FPTI = dyn_cast(CI)) - FPTruncInst::destroyThis(FPTI); - else if(IntToPtrInst* I2PI = dyn_cast(CI)) - IntToPtrInst::destroyThis(I2PI); - else if(PtrToIntInst* P2II = dyn_cast(CI)) - PtrToIntInst::destroyThis(P2II); - else if(SExtInst* SEI = dyn_cast(CI)) - SExtInst::destroyThis(SEI); - else if(SIToFPInst* SIFPI = dyn_cast(CI)) - SIToFPInst::destroyThis(SIFPI); - else if(TruncInst* TI = dyn_cast(CI)) - TruncInst::destroyThis(TI); - else if(UIToFPInst* UIFPI = dyn_cast(CI)) - UIToFPInst::destroyThis(UIFPI); - else if(ZExtInst* ZEI = dyn_cast(CI)) - ZExtInst::destroyThis(ZEI); - else - assert(0 && "Unknown CastInst-inherited class in ~Value."); - } - else if(FreeInst* FI = dyn_cast(this)) - FreeInst::destroyThis(FI); - else if(LoadInst* LI = dyn_cast(this)) - LoadInst::destroyThis(LI); - else if(VAArgInst* VAI = dyn_cast(this)) - VAArgInst::destroyThis(VAI); - else - assert(0 && "Unknown UnaryInstruction-inherited class in ~Value."); - } - else if (DummyInst *DI = dyn_cast(this)) - DummyInst::destroyThis(DI); - else - assert(0 && "Unknown Instruction-inherited class in ~Value."); - break; - } -} - -void Value::destroyThis(Value*v) -{ +Value::~Value() { #ifndef NDEBUG // Only in -g mode... // Check to make sure that there are no uses of this value that are still // around when the value is destroyed. If there are, then we have a dangling @@ -239,22 +47,22 @@ // still being referenced. The value in question should be printed as // a // - if (!v->use_empty()) { - DOUT << "While deleting: " << *v->Ty << " %" << v->Name << "\n"; - for (use_iterator I = v->use_begin(), E = v->use_end(); I != E; ++I) + if (!use_empty()) { + DOUT << "While deleting: " << *Ty << " %" << Name << "\n"; + for (use_iterator I = use_begin(), E = use_end(); I != E; ++I) DOUT << "Use still stuck around after Def is destroyed:" << **I << "\n"; } #endif - assert(v->use_empty() && "Uses remain when a value is destroyed!"); + assert(use_empty() && "Uses remain when a value is destroyed!"); // If this value is named, destroy the name. This should not be in a symtab // at this point. - if (v->Name) - v->Name->Destroy(); + if (Name) + Name->Destroy(); // There should be no uses of this object anymore, remove it. - LeakDetector::removeGarbageObject(v); + LeakDetector::removeGarbageObject(this); } /// hasNUses - Return true if this Value has exactly N users. From rspencer at reidspencer.com Sun Dec 9 21:14:08 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Mon, 10 Dec 2007 03:14:08 -0000 Subject: [llvm-commits] [support] r44764 - in /support/trunk/make: Makefile.common Makefile.top Message-ID: <200712100314.lBA3E9vJ018482@zion.cs.uiuc.edu> Author: reid Date: Sun Dec 9 21:14:08 2007 New Revision: 44764 URL: http://llvm.org/viewvc/llvm-project?rev=44764&view=rev Log: Split this spotless target out into the Makefile.top file since it is only relevant at the top level directory. Allow the top level directory to be used as an include file source for projects like HLVM. Added: support/trunk/make/Makefile.top Modified: support/trunk/make/Makefile.common Modified: support/trunk/make/Makefile.common URL: http://llvm.org/viewvc/llvm-project/support/trunk/make/Makefile.common?rev=44764&r1=44763&r2=44764&view=diff ============================================================================== --- support/trunk/make/Makefile.common (original) +++ support/trunk/make/Makefile.common Sun Dec 9 21:14:08 2007 @@ -90,29 +90,6 @@ -$(Verb) $(RM) -f $(BUILT_SOURCES) endif -ifneq ($(OBJ_ROOT),$(SRC_ROOT)) -spotless: - $(Verb) if test -x config.status ; then \ - $(EchoCmd) Wiping out $(OBJ_ROOT) ; \ - $(MKDIR) .spotless.save ; \ - $(MV) config.status .spotless.save ; \ - $(MV) mklib .spotless.save ; \ - $(MV) projects .spotless.save ; \ - $(RM) -rf * ; \ - $(MV) .spotless.save/config.status . ; \ - $(MV) .spotless.save/mklib . ; \ - $(MV) .spotless.save/projects . ; \ - $(RM) -rf .spotless.save ; \ - $(EchoCmd) Rebuilding configuration of $(OBJ_ROOT) ; \ - $(ConfigStatusScript) --recheck $(ConfigureScriptFLAGS) && \ - $(ConfigStatusScript) ; \ - else \ - $(EchoCmd) "make spotless" can only be run from $(OBJ_ROOT); \ - fi -else -spotless: - $(EchoCmd) "spotless target not supported for objdir == srcdir" -endif $(BUILT_SOURCES) : $(ObjMakefiles) @@ -446,8 +423,9 @@ CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_LIMIT_MACROS # All -I flags should go here, so that they don't confuse llvm-config. CPP.Flags += -I$(OBJ_DIR) -I$(SRC_DIR) \ - -I$(OBJ_ROOT)/include \ - -I$(SRC_ROOT)/include \ + -I$(OBJ_ROOT)/include -I$(SRC_ROOT)/include \ + -I$(OBJ_ROOT) -I$(SRC_ROOT) \ + $(patsubst %,-I$(LLVM_TOP)/%/include -I$(LLVM_TOP)/%,$(LLVM_MODULE_DEPENDS_ON)) \ $(CPP.BaseFlags) Compile.C = $(CC) $(CPP.Flags) $(C.Flags) $(CompileCommonOpts) -c Added: support/trunk/make/Makefile.top URL: http://llvm.org/viewvc/llvm-project/support/trunk/make/Makefile.top?rev=44764&view=auto ============================================================================== --- support/trunk/make/Makefile.top (added) +++ support/trunk/make/Makefile.top Sun Dec 9 21:14:08 2007 @@ -0,0 +1,43 @@ +#===-- Makefile.top - Rules for top level directory --------*- Makefile -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file was developed by Reid Spencer group and is distributed under the +# University of Illinois Open Source License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# +# This file is used by all top level directories of LLVM modules. It provides +# the targets that only occur at the top level in addition to Makefile.common +# +#===-----------------------------------------------------------------------====# + +include $(LLVM_TOP)/support/make/Makefile.compile + +#------------------------------------------------------------------------------- +# Provide a spotless target to really blow things away and start from scratch +#------------------------------------------------------------------------------- + +ifneq ($(OBJ_ROOT),$(SRC_ROOT)) +spotless: + $(Verb) if test -x config.status ; then \ + $(EchoCmd) Wiping out $(OBJ_ROOT) ; \ + $(MKDIR) .spotless.save ; \ + $(MV) config.status .spotless.save ; \ + $(MV) mklib .spotless.save ; \ + $(MV) projects .spotless.save ; \ + $(RM) -rf * ; \ + $(MV) .spotless.save/config.status . ; \ + $(MV) .spotless.save/mklib . ; \ + $(MV) .spotless.save/projects . ; \ + $(RM) -rf .spotless.save ; \ + $(EchoCmd) Rebuilding configuration of $(OBJ_ROOT) ; \ + $(ConfigStatusScript) --recheck $(ConfigureScriptFLAGS) && \ + $(ConfigStatusScript) ; \ + else \ + $(EchoCmd) "make spotless" can only be run from $(OBJ_ROOT); \ + fi +else +spotless: + $(EchoCmd) "spotless target not supported for objdir == srcdir" +endif From rspencer at reidspencer.com Sun Dec 9 21:14:50 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Mon, 10 Dec 2007 03:14:50 -0000 Subject: [llvm-commits] [support] r44765 - /support/trunk/Makefile.common.in Message-ID: <200712100314.lBA3Eoqw018511@zion.cs.uiuc.edu> Author: reid Date: Sun Dec 9 21:14:50 2007 New Revision: 44765 URL: http://llvm.org/viewvc/llvm-project?rev=44765&view=rev Log: Make WANT_PROFILING use an immediate assignment like the other variables in this file. Modified: support/trunk/Makefile.common.in Modified: support/trunk/Makefile.common.in URL: http://llvm.org/viewvc/llvm-project/support/trunk/Makefile.common.in?rev=44765&r1=44764&r2=44765&view=diff ============================================================================== --- support/trunk/Makefile.common.in (original) +++ support/trunk/Makefile.common.in Sun Dec 9 21:14:50 2007 @@ -173,7 +173,7 @@ # When ENABLE_PROFILING is enabled, the llvm source base is built with profile # information to allow gprof to be used to get execution frequencies. -WANT_PROFILING = @WANT_PROFILING@ +WANT_PROFILING := @WANT_PROFILING@ # When WANT_STRIPPED is enabled, executables and libraries will be # stripped of debug symbols From rspencer at reidspencer.com Sun Dec 9 21:15:54 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Mon, 10 Dec 2007 03:15:54 -0000 Subject: [llvm-commits] [support] r44766 - in /support/trunk/autoconf/m4: want_feature.m4 want_level.m4 Message-ID: <200712100315.lBA3Fsdm018556@zion.cs.uiuc.edu> Author: reid Date: Sun Dec 9 21:15:53 2007 New Revision: 44766 URL: http://llvm.org/viewvc/llvm-project?rev=44766&view=rev Log: Move the WANT_LEVEL macro to its own file. Added: support/trunk/autoconf/m4/want_level.m4 Modified: support/trunk/autoconf/m4/want_feature.m4 Modified: support/trunk/autoconf/m4/want_feature.m4 URL: http://llvm.org/viewvc/llvm-project/support/trunk/autoconf/m4/want_feature.m4?rev=44766&r1=44765&r2=44766&view=diff ============================================================================== --- support/trunk/autoconf/m4/want_feature.m4 (original) +++ support/trunk/autoconf/m4/want_feature.m4 Sun Dec 9 21:15:53 2007 @@ -21,35 +21,3 @@ want_var=[WANT_]allcapsname() AC_DEFINE_UNQUOTED($want_var,$enableval,[$2]) ]) - -dnl Make it easier to use the AC_ARG_ENABLE macro for certain numeric switches -dnl that turn specify levels of support as integer values. The arguments are: -dnl 1 - feature name -dnl 2 - feature description -dnl 3 - default value -dnl 4 - min value (default 0) -dnl 5 - max value (default 100) -AC_DEFUN([LLVM_WANT_LEVEL],[ - m4_define([allcapsname],translit($1,a-z-,A-Z_)) - AC_ARG_ENABLE([$1], - AS_HELP_STRING([--enable-$1],[$2 ($3)]),,enableval="$3") - digits=`echo "$enableval" | sed 's/[^0-9]//'` - if test -z "$digits" ; then - AC_MSG_ERROR([Expected numeric value for --enable-$1.]) - fi - min="$4" - max="$5" - if test -z "$min" ; then min="0" ; fi - if test -z "$max" ; then max="100" ; fi - if test "$enableval" -lt "$min" ; then - AC_MSG_ERROR( - [Value for --enable-$1 ($enableval) is less than minimum ($min)]) - fi - if test "$enableval" -gt "$max" ; then - AC_MSG_ERROR( - [Value for --enable-$1 ($enableval) is greater than maximum ($max)]) - fi - AC_SUBST([WANT_]allcapsname(),$enableval) - want_var=[WANT_]allcapsname() - AC_DEFINE_UNQUOTED($want_var,$enableval,[$2]) -]) Added: support/trunk/autoconf/m4/want_level.m4 URL: http://llvm.org/viewvc/llvm-project/support/trunk/autoconf/m4/want_level.m4?rev=44766&view=auto ============================================================================== --- support/trunk/autoconf/m4/want_level.m4 (added) +++ support/trunk/autoconf/m4/want_level.m4 Sun Dec 9 21:15:53 2007 @@ -0,0 +1,31 @@ +dnl Make it easier to use the AC_ARG_ENABLE macro for certain numeric switches +dnl that return levels of support as integer values. The arguments are: +dnl 1 - feature name +dnl 2 - feature description +dnl 3 - default value +dnl 4 - min value (default 0) +dnl 5 - max value (default 100) +AC_DEFUN([LLVM_WANT_LEVEL],[ + m4_define([allcapsname],translit($1,a-z-,A-Z_)) + AC_ARG_ENABLE([$1], + AS_HELP_STRING([--enable-$1],[$2 ($3)]),,enableval="$3") + digits=`echo "$enableval" | sed 's/[^0-9]//'` + if test -z "$digits" ; then + AC_MSG_ERROR([Expected numeric value for --enable-$1.]) + fi + min="$4" + max="$5" + if test -z "$min" ; then min="0" ; fi + if test -z "$max" ; then max="100" ; fi + if test "$enableval" -lt "$min" ; then + AC_MSG_ERROR( + [Value for --enable-$1 ($enableval) is less than minimum ($min)]) + fi + if test "$enableval" -gt "$max" ; then + AC_MSG_ERROR( + [Value for --enable-$1 ($enableval) is greater than maximum ($max)]) + fi + AC_SUBST([WANT_]allcapsname(),$enableval) + want_var=[WANT_]allcapsname() + AC_DEFINE_UNQUOTED($want_var,$enableval,[$2]) +]) From rspencer at reidspencer.com Sun Dec 9 21:16:44 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Mon, 10 Dec 2007 03:16:44 -0000 Subject: [llvm-commits] [support] r44767 - /support/trunk/autoconf/configure.ac Message-ID: <200712100316.lBA3GiUH018589@zion.cs.uiuc.edu> Author: reid Date: Sun Dec 9 21:16:43 2007 New Revision: 44767 URL: http://llvm.org/viewvc/llvm-project?rev=44767&view=rev Log: 1. Update the version number to 2.2svn 2. Make DESTDIR not be defined as '' by using ''! Modified: support/trunk/autoconf/configure.ac Modified: support/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/support/trunk/autoconf/configure.ac?rev=44767&r1=44766&r2=44767&view=diff ============================================================================== --- support/trunk/autoconf/configure.ac (original) +++ support/trunk/autoconf/configure.ac Sun Dec 9 21:16:43 2007 @@ -33,7 +33,7 @@ dnl===-----------------------------------------------------------------------=== dnl Initialize autoconf and define the package name, version number and dnl email address for reporting bugs. -AC_INIT([[LLVM Support Module]],[[2.1svn]],[http://llvm.org/bugs],[llvm-support]) +AC_INIT([[LLVM Support Module]],[[2.2svn]],[http://llvm.org/bugs],[llvm-support]) THIS_IS_LLVM_MODULE([support]) dnl Verify that the source directory is valid. This makes sure that we are @@ -253,7 +253,7 @@ AS_HELP_STRING([--with-destdir], [Specify the install destination directory]),,withval=default) case "$withval" in - default) DESTDIR="" ;; + default) DESTDIR='' ;; *) DESTDIR=$withval ;; esac AC_SUBST(DESTDIR,$DESTDIR) From rspencer at reidspencer.com Sun Dec 9 21:17:09 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Mon, 10 Dec 2007 03:17:09 -0000 Subject: [llvm-commits] [support] r44768 - /support/trunk/configure Message-ID: <200712100317.lBA3H9Fm018614@zion.cs.uiuc.edu> Author: reid Date: Sun Dec 9 21:17:09 2007 New Revision: 44768 URL: http://llvm.org/viewvc/llvm-project?rev=44768&view=rev Log: Regenerate. Modified: support/trunk/configure Modified: support/trunk/configure URL: http://llvm.org/viewvc/llvm-project/support/trunk/configure?rev=44768&r1=44767&r2=44768&view=diff ============================================================================== --- support/trunk/configure (original) +++ support/trunk/configure Sun Dec 9 21:17:09 2007 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for LLVM Support Module 2.1svn. +# Generated by GNU Autoconf 2.61 for LLVM Support Module 2.2svn. # # Report bugs to . # @@ -730,8 +730,8 @@ # Identity of this package. PACKAGE_NAME='LLVM Support Module' PACKAGE_TARNAME='llvm-support' -PACKAGE_VERSION='2.1svn' -PACKAGE_STRING='LLVM Support Module 2.1svn' +PACKAGE_VERSION='2.2svn' +PACKAGE_STRING='LLVM Support Module 2.2svn' PACKAGE_BUGREPORT='http://llvm.org/bugs' ac_unique_file="" @@ -1451,7 +1451,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures LLVM Support Module 2.1svn to adapt to many kinds of systems. +\`configure' configures LLVM Support Module 2.2svn to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1517,7 +1517,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of LLVM Support Module 2.1svn:";; + short | recursive ) echo "Configuration of LLVM Support Module 2.2svn:";; esac cat <<\_ACEOF @@ -1644,7 +1644,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -LLVM Support Module configure 2.1svn +LLVM Support Module configure 2.2svn generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1660,7 +1660,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by LLVM Support Module $as_me 2.1svn, which was +It was created by LLVM Support Module $as_me 2.2svn, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2092,13 +2092,13 @@ LLVM_MODULE_FULLNAME="LLVM Support Module" LLVM_MODULE_TARNAME="llvm-support" - LLVM_MODULE_VERSION="2.1svn" + LLVM_MODULE_VERSION="2.2svn" LLVM_MODULE_BUGREPORT="http://llvm.org/bugs" LLVM_MODULE_FULLNAME="LLVM Support Module" LLVM_MODULE_TARNAME="llvm-support" - LLVM_MODULE_VERSION="2.1svn" + LLVM_MODULE_VERSION="2.2svn" LLVM_MODULE_BUGREPORT="http://llvm.org/bugs" @@ -4772,7 +4772,7 @@ fi case "$withval" in - default) DESTDIR="" ;; + default) DESTDIR='' ;; *) DESTDIR=$withval ;; esac DESTDIR=$DESTDIR @@ -31997,7 +31997,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by LLVM Support Module $as_me 2.1svn, which was +This file was extended by LLVM Support Module $as_me 2.2svn, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -32050,7 +32050,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -LLVM Support Module config.status 2.1svn +LLVM Support Module config.status 2.2svn configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" From gordonhenriksen at mac.com Sun Dec 9 21:18:06 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Mon, 10 Dec 2007 03:18:06 -0000 Subject: [llvm-commits] [llvm] r44769 - in /llvm/trunk: bindings/ocaml/llvm/ docs/ include/llvm-c/ include/llvm/ include/llvm/Bitcode/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/Transforms/Utils/ lib/VMCore/ test/Assembler/ test/Bindings/Ocaml/ test/CodeGen/Generic/GC/ Message-ID: <200712100318.lBA3I7WC018676@zion.cs.uiuc.edu> Author: gordon Date: Sun Dec 9 21:18:06 2007 New Revision: 44769 URL: http://llvm.org/viewvc/llvm-project?rev=44769&view=rev Log: Adding a collector name attribute to Function in the IR. These methods are new to Function: bool hasCollector() const; const std::string &getCollector() const; void setCollector(const std::string &); void clearCollector(); The assembly representation is as such: define void @f() gc "shadow-stack" { ... The implementation uses an on-the-side table to map Functions to collector names, such that there is no overhead. A StringPool is further used to unique collector names, which are extremely likely to be unique per process. Added: llvm/trunk/test/Assembler/2007-09-29-GC.ll Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml llvm/trunk/bindings/ocaml/llvm/llvm.mli llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm-c/Core.h llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h llvm/trunk/include/llvm/Function.h llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs llvm/trunk/lib/AsmParser/llvmAsmParser.h.cvs llvm/trunk/lib/AsmParser/llvmAsmParser.y llvm/trunk/lib/AsmParser/llvmAsmParser.y.cvs llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/Transforms/Utils/CloneModule.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/Core.cpp llvm/trunk/lib/VMCore/Function.cpp llvm/trunk/test/Bindings/Ocaml/vmcore.ml llvm/trunk/test/CodeGen/Generic/GC/alloc_loop.ll Modified: llvm/trunk/bindings/ocaml/llvm/llvm.ml URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.ml?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.ml (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.ml Sun Dec 9 21:18:06 2007 @@ -282,6 +282,8 @@ external function_call_conv : llvalue -> int = "llvm_function_call_conv" external set_function_call_conv : int -> llvalue -> unit = "llvm_set_function_call_conv" +external collector : llvalue -> string option = "llvm_collector" +external set_collector : string option -> llvalue -> unit = "llvm_set_collector" (* TODO: param attrs *) Modified: llvm/trunk/bindings/ocaml/llvm/llvm.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.mli?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.mli (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.mli Sun Dec 9 21:18:06 2007 @@ -754,6 +754,15 @@ external set_function_call_conv : int -> llvalue -> unit = "llvm_set_function_call_conv" +(** [collector f] returns [Some name] if the function [f] has a garbage + collection algorithm specified and [None] otherwise. + See the method [llvm::Function::getCollector]. **) +external collector : llvalue -> string option = "llvm_collector" + +(** [set_collector gc f] sets the collection algorithm for the function [f] to + [gc]. See the method [llvm::Function::setCollector]. **) +external set_collector : string option -> llvalue -> unit = "llvm_set_collector" + (*--... Operations on basic blocks .........................................--*) (** [basic_blocks fn] returns the basic blocks of the function [f]. Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Sun Dec 9 21:18:06 2007 @@ -536,6 +536,29 @@ return Val_unit; } +/* llvalue -> string option */ +CAMLprim value llvm_collector(LLVMValueRef Fn) { + const char *Collector; + CAMLparam0(); + CAMLlocal2(Name, Option); + + if ((Collector = LLVMGetCollector(Fn))) { + Name = copy_string(Collector); + + Option = alloc(1, 0); + Field(Option, 0) = Name; + CAMLreturn(Option); + } else { + CAMLreturn(Val_int(0)); + } +} + +/* string option -> llvalue -> unit */ +CAMLprim value llvm_set_collector(value GC, LLVMValueRef Fn) { + LLVMSetCollector(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0))); + return Val_unit; +} + /*--... Operations on basic blocks .........................................--*/ /* llvalue -> llbasicblock array */ Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Sun Dec 9 21:18:06 2007 @@ -26,6 +26,7 @@
  • Functions
  • Aliases
  • Parameter Attributes
  • +
  • Garbage Collector Names
  • Module-Level Inline Assembly
  • Data Layout
  • @@ -702,15 +703,16 @@ parameter attribute for the return type, a function name, a (possibly empty) argument list (each with optional parameter attributes), an optional section, an -optional alignment, an opening curly brace, a list of basic blocks, and a -closing curly brace. +optional alignment, an optional garbage collector name, an +opening curly brace, a list of basic blocks, and a closing curly brace. LLVM function declarations consist of the "declare" keyword, an optional linkage type, an optional visibility style, an optional calling convention, a return type, an optional parameter attribute for the return type, a function -name, a possibly empty list of arguments, and an optional alignment.

    +name, a possibly empty list of arguments, an optional alignment, and an optional +garbage collector name.

    A function definition contains a list of basic blocks, forming the CFG for the function. Each basic block may optionally start with a label (giving the @@ -826,6 +828,23 @@

    + +
    +

    Each function may specify a garbage collector name, which is simply a +string.

    + +
    define void @f() gc "name" { ...
    + +

    The compiler declares the supported values of name. Specifying a +collector which will cause the compiler to alter its output in order to support +the named garbage collection algorithm.

    +
    + + + Modified: llvm/trunk/include/llvm-c/Core.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Core.h (original) +++ llvm/trunk/include/llvm-c/Core.h Sun Dec 9 21:18:06 2007 @@ -339,6 +339,8 @@ unsigned LLVMGetIntrinsicID(LLVMValueRef Fn); unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn); void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC); +const char *LLVMGetCollector(LLVMValueRef Fn); +void LLVMSetCollector(LLVMValueRef Fn, const char *Coll); /* Operations on basic blocks */ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb); Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Sun Dec 9 21:18:06 2007 @@ -58,7 +58,9 @@ MODULE_CODE_ALIAS = 9, /// MODULE_CODE_PURGEVALS: [numvals] - MODULE_CODE_PURGEVALS = 10 + MODULE_CODE_PURGEVALS = 10, + + MODULE_CODE_COLLECTORNAME = 11 // COLLECTORNAME: [strchr x N] }; /// PARAMATTR blocks have code for defining a parameter attribute set. Modified: llvm/trunk/include/llvm/Function.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Function.h?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/include/llvm/Function.h (original) +++ llvm/trunk/include/llvm/Function.h Sun Dec 9 21:18:06 2007 @@ -153,6 +153,13 @@ /// @brief Set the parameter attributes. void setParamAttrs(const ParamAttrsList *attrs); + /// hasCollector/getCollector/setCollector/clearCollector - The name of the + /// garbage collection algorithm to use during code generation. + bool hasCollector() const; + const char *getCollector() const; + void setCollector(const char *Str); + void clearCollector(); + /// @brief Determine whether the function has the given attribute. bool paramHasAttr(uint16_t i, ParameterAttributes attr) const { return ParamAttrs && ParamAttrs->paramHasAttr(i, attr); Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Sun Dec 9 21:18:06 2007 @@ -468,6 +468,7 @@ KEYWORD("module", MODULE); KEYWORD("asm", ASM_TOK); KEYWORD("sideeffect", SIDEEFFECT); + KEYWORD("gc", GC); KEYWORD("cc", CC_TOK); KEYWORD("ccc", CCC_TOK); Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs?rev=44769&r1=44768&r2=44769&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.cpp.cvs Sun Dec 9 21:18:06 2007 @@ -216,9 +216,10 @@ NEST = 397, READNONE = 398, READONLY = 399, - DEFAULT = 400, - HIDDEN = 401, - PROTECTED = 402 + GC = 400, + DEFAULT = 401, + HIDDEN = 402, + PROTECTED = 403 }; #endif /* Tokens. */ @@ -364,15 +365,16 @@ #define NEST 397 #define READNONE 398 #define READONLY 399 -#define DEFAULT 400 -#define HIDDEN 401 -#define PROTECTED 402 +#define GC 400 +#define DEFAULT 401 +#define HIDDEN 402 +#define PROTECTED 403 /* Copy the first part of user declarations. */ -#line 14 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 14 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -1324,7 +1326,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 945 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 945 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { llvm::Module *ModuleVal; llvm::Function *FunctionVal; @@ -1371,8 +1373,8 @@ llvm::ICmpInst::Predicate IPredicate; llvm::FCmpInst::Predicate FPredicate; } -/* Line 187 of yacc.c. */ -#line 1376 "llvmAsmParser.tab.c" +/* Line 193 of yacc.c. */ +#line 1378 "llvmAsmParser.tab.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -1385,7 +1387,7 @@ /* Line 216 of yacc.c. */ -#line 1389 "llvmAsmParser.tab.c" +#line 1391 "llvmAsmParser.tab.c" #ifdef short # undef short @@ -1435,7 +1437,7 @@ #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -1600,20 +1602,20 @@ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 43 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1816 +#define YYLAST 1820 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 162 +#define YYNTOKENS 163 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 82 +#define YYNNTS 83 /* YYNRULES -- Number of rules. */ -#define YYNRULES 314 +#define YYNRULES 316 /* YYNRULES -- Number of states. */ -#define YYNSTATES 608 +#define YYNSTATES 611 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 402 +#define YYMAXUTOK 403 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -1625,15 +1627,15 @@ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 152, 153, 150, 2, 149, 2, 2, 2, 2, 2, + 153, 154, 151, 2, 150, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 157, 148, 158, 2, 2, 2, 2, 2, 2, 2, + 158, 149, 159, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 154, 151, 156, 2, 2, 2, 2, 2, 161, + 2, 155, 152, 157, 2, 2, 2, 2, 2, 162, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 155, 2, 2, 159, 2, 160, 2, 2, 2, 2, + 156, 2, 2, 160, 2, 161, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1661,7 +1663,7 @@ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147 + 145, 146, 147, 148 }; #if YYDEBUG @@ -1681,32 +1683,32 @@ 175, 177, 179, 181, 182, 184, 186, 187, 189, 191, 193, 195, 197, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 219, 222, 224, 226, 228, 230, 232, - 234, 235, 238, 239, 242, 243, 247, 250, 251, 253, - 254, 258, 260, 263, 265, 267, 269, 271, 273, 275, - 277, 279, 281, 284, 286, 289, 295, 301, 307, 313, - 317, 320, 326, 331, 334, 336, 338, 340, 344, 346, - 350, 352, 353, 355, 359, 364, 368, 372, 377, 382, - 386, 393, 399, 402, 405, 408, 411, 414, 417, 420, - 423, 426, 429, 432, 435, 442, 448, 457, 464, 471, - 479, 487, 494, 503, 512, 516, 518, 520, 522, 524, - 525, 528, 535, 537, 538, 540, 543, 544, 548, 549, - 553, 557, 561, 565, 566, 574, 575, 584, 585, 594, - 600, 603, 607, 609, 613, 617, 621, 625, 627, 628, - 634, 638, 640, 644, 646, 647, 657, 659, 661, 666, - 668, 670, 673, 677, 678, 680, 682, 684, 686, 688, - 690, 692, 694, 696, 700, 702, 708, 710, 712, 714, - 716, 718, 720, 723, 726, 729, 733, 736, 737, 739, - 742, 745, 749, 759, 769, 778, 793, 795, 797, 804, - 810, 813, 820, 828, 833, 838, 845, 852, 853, 854, - 858, 861, 863, 869, 875, 882, 889, 894, 901, 906, - 911, 918, 925, 928, 937, 939, 941, 942, 946, 953, - 957, 964, 967, 973, 981 + 234, 235, 238, 239, 242, 243, 246, 247, 251, 254, + 255, 257, 258, 262, 264, 267, 269, 271, 273, 275, + 277, 279, 281, 283, 285, 288, 290, 293, 299, 305, + 311, 317, 321, 324, 330, 335, 338, 340, 342, 344, + 348, 350, 354, 356, 357, 359, 363, 368, 372, 376, + 381, 386, 390, 397, 403, 406, 409, 412, 415, 418, + 421, 424, 427, 430, 433, 436, 439, 446, 452, 461, + 468, 475, 483, 491, 498, 507, 516, 520, 522, 524, + 526, 528, 529, 532, 539, 541, 542, 544, 547, 548, + 552, 553, 557, 561, 565, 569, 570, 578, 579, 588, + 589, 598, 604, 607, 611, 613, 617, 621, 625, 629, + 631, 632, 638, 642, 644, 648, 650, 651, 662, 664, + 666, 671, 673, 675, 678, 682, 683, 685, 687, 689, + 691, 693, 695, 697, 699, 701, 705, 707, 713, 715, + 717, 719, 721, 723, 725, 728, 731, 734, 738, 741, + 742, 744, 747, 750, 754, 764, 774, 783, 798, 800, + 802, 809, 815, 818, 825, 833, 838, 843, 850, 857, + 858, 859, 863, 866, 868, 874, 880, 887, 894, 899, + 906, 911, 916, 923, 930, 933, 942, 944, 946, 947, + 951, 958, 962, 969, 972, 978, 986 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 206, 0, -1, 73, -1, 74, -1, 75, -1, 76, + 208, 0, -1, 73, -1, 74, -1, 75, -1, 76, -1, 77, -1, 78, -1, 79, -1, 80, -1, 81, -1, 85, -1, 86, -1, 87, -1, 82, -1, 83, -1, 84, -1, 116, -1, 117, -1, 118, -1, 119, @@ -1718,93 +1720,94 @@ -1, 107, -1, 108, -1, 109, -1, 96, -1, 97, -1, 98, -1, 99, -1, 26, -1, 27, -1, 11, -1, 12, -1, 13, -1, 16, -1, 15, -1, 14, - -1, 19, -1, 22, -1, 24, -1, 170, -1, -1, - 170, 148, -1, -1, 20, -1, 23, -1, 175, -1, - -1, 173, 148, -1, 42, -1, 44, -1, 43, -1, + -1, 19, -1, 22, -1, 24, -1, 171, -1, -1, + 171, 149, -1, -1, 20, -1, 23, -1, 176, -1, + -1, 174, 149, -1, 42, -1, 44, -1, 43, -1, 45, -1, 47, -1, 46, -1, 48, -1, 50, -1, - -1, 145, -1, 146, -1, 147, -1, -1, 46, -1, + -1, 146, -1, 147, -1, 148, -1, -1, 46, -1, 48, -1, -1, 42, -1, 43, -1, 44, -1, 47, -1, -1, 44, -1, 42, -1, -1, 61, -1, 62, -1, 63, -1, 64, -1, 65, -1, 60, 4, -1, 135, -1, 117, -1, 134, -1, 118, -1, 137, -1, - 138, -1, 140, -1, 141, -1, 142, -1, -1, 184, - 183, -1, 136, -1, 139, -1, 135, -1, 134, -1, - 143, -1, 144, -1, -1, 186, 185, -1, -1, 53, - 4, -1, -1, 149, 53, 4, -1, 34, 22, -1, - -1, 189, -1, -1, 149, 192, 191, -1, 189, -1, - 53, 4, -1, 11, -1, 12, -1, 13, -1, 16, - -1, 15, -1, 14, -1, 17, -1, 49, -1, 193, - -1, 194, 150, -1, 228, -1, 151, 4, -1, 194, - 152, 198, 153, 186, -1, 10, 152, 198, 153, 186, - -1, 154, 4, 155, 194, 156, -1, 157, 4, 155, - 194, 158, -1, 159, 199, 160, -1, 159, 160, -1, - 157, 159, 199, 160, 158, -1, 157, 159, 160, 158, - -1, 194, 184, -1, 194, -1, 10, -1, 195, -1, - 197, 149, 195, -1, 197, -1, 197, 149, 39, -1, - 39, -1, -1, 194, -1, 199, 149, 194, -1, 194, - 154, 202, 156, -1, 194, 154, 156, -1, 194, 161, - 22, -1, 194, 157, 202, 158, -1, 194, 159, 202, - 160, -1, 194, 159, 160, -1, 194, 157, 159, 202, - 160, 158, -1, 194, 157, 159, 160, 158, -1, 194, - 40, -1, 194, 41, -1, 194, 228, -1, 194, 201, - -1, 194, 25, -1, 168, 3, -1, 168, 5, -1, - 168, 4, -1, 168, 6, -1, 11, 26, -1, 11, - 27, -1, 169, 9, -1, 165, 152, 200, 38, 194, - 153, -1, 115, 152, 200, 239, 153, -1, 129, 152, - 200, 149, 200, 149, 200, 153, -1, 163, 152, 200, - 149, 200, 153, -1, 164, 152, 200, 149, 200, 153, - -1, 88, 166, 152, 200, 149, 200, 153, -1, 89, - 167, 152, 200, 149, 200, 153, -1, 131, 152, 200, - 149, 200, 153, -1, 132, 152, 200, 149, 200, 149, - 200, 153, -1, 133, 152, 200, 149, 200, 149, 200, - 153, -1, 202, 149, 200, -1, 200, -1, 32, -1, - 33, -1, 37, -1, -1, 196, 228, -1, 121, 152, - 205, 38, 194, 153, -1, 207, -1, -1, 208, -1, - 207, 208, -1, -1, 31, 209, 224, -1, -1, 30, - 210, 225, -1, 58, 57, 214, -1, 172, 18, 194, - -1, 172, 18, 10, -1, -1, 174, 178, 204, 203, - 200, 211, 191, -1, -1, 174, 176, 178, 204, 203, - 200, 212, 191, -1, -1, 174, 177, 178, 204, 203, - 194, 213, 191, -1, 174, 178, 35, 181, 205, -1, - 51, 215, -1, 54, 148, 216, -1, 22, -1, 52, - 148, 22, -1, 66, 148, 22, -1, 154, 217, 156, - -1, 217, 149, 22, -1, 22, -1, -1, 218, 149, - 194, 184, 171, -1, 194, 184, 171, -1, 218, -1, - 218, 149, 39, -1, 39, -1, -1, 182, 196, 173, - 152, 219, 153, 186, 190, 187, -1, 28, -1, 159, - -1, 180, 178, 220, 221, -1, 29, -1, 160, -1, - 231, 223, -1, 179, 178, 220, -1, -1, 59, -1, - 3, -1, 4, -1, 9, -1, 26, -1, 27, -1, - 40, -1, 41, -1, 25, -1, 157, 202, 158, -1, - 201, -1, 57, 226, 22, 149, 22, -1, 7, -1, - 8, -1, 170, -1, 173, -1, 228, -1, 227, -1, - 194, 229, -1, 231, 232, -1, 222, 232, -1, 233, - 172, 234, -1, 233, 236, -1, -1, 21, -1, 67, - 230, -1, 67, 10, -1, 68, 17, 229, -1, 68, - 11, 229, 149, 17, 229, 149, 17, 229, -1, 69, - 168, 229, 149, 17, 229, 154, 235, 156, -1, 69, - 168, 229, 149, 17, 229, 154, 156, -1, 70, 182, - 196, 229, 152, 238, 153, 186, 38, 17, 229, 71, - 17, 229, -1, 71, -1, 72, -1, 235, 168, 227, - 149, 17, 229, -1, 168, 227, 149, 17, 229, -1, - 172, 241, -1, 194, 154, 229, 149, 229, 156, -1, - 237, 149, 154, 229, 149, 229, 156, -1, 194, 184, - 229, 184, -1, 17, 184, 229, 184, -1, 238, 149, - 194, 184, 229, 184, -1, 238, 149, 17, 184, 229, - 184, -1, -1, -1, 239, 149, 230, -1, 56, 55, - -1, 55, -1, 163, 194, 229, 149, 229, -1, 164, - 194, 229, 149, 229, -1, 88, 166, 194, 229, 149, - 229, -1, 89, 167, 194, 229, 149, 229, -1, 165, - 230, 38, 194, -1, 129, 230, 149, 230, 149, 230, - -1, 130, 230, 149, 194, -1, 131, 230, 149, 230, - -1, 132, 230, 149, 230, 149, 230, -1, 133, 230, - 149, 230, 149, 230, -1, 128, 237, -1, 240, 182, - 196, 229, 152, 238, 153, 186, -1, 243, -1, 36, - -1, -1, 110, 194, 188, -1, 110, 194, 149, 11, - 229, 188, -1, 111, 194, 188, -1, 111, 194, 149, - 11, 229, 188, -1, 112, 230, -1, 242, 113, 194, - 229, 188, -1, 242, 114, 230, 149, 194, 229, 188, - -1, 115, 194, 229, 239, -1 + 138, -1, 140, -1, 141, -1, 142, -1, -1, 185, + 184, -1, 136, -1, 139, -1, 135, -1, 134, -1, + 143, -1, 144, -1, -1, 187, 186, -1, -1, 145, + 22, -1, -1, 53, 4, -1, -1, 150, 53, 4, + -1, 34, 22, -1, -1, 191, -1, -1, 150, 194, + 193, -1, 191, -1, 53, 4, -1, 11, -1, 12, + -1, 13, -1, 16, -1, 15, -1, 14, -1, 17, + -1, 49, -1, 195, -1, 196, 151, -1, 230, -1, + 152, 4, -1, 196, 153, 200, 154, 187, -1, 10, + 153, 200, 154, 187, -1, 155, 4, 156, 196, 157, + -1, 158, 4, 156, 196, 159, -1, 160, 201, 161, + -1, 160, 161, -1, 158, 160, 201, 161, 159, -1, + 158, 160, 161, 159, -1, 196, 185, -1, 196, -1, + 10, -1, 197, -1, 199, 150, 197, -1, 199, -1, + 199, 150, 39, -1, 39, -1, -1, 196, -1, 201, + 150, 196, -1, 196, 155, 204, 157, -1, 196, 155, + 157, -1, 196, 162, 22, -1, 196, 158, 204, 159, + -1, 196, 160, 204, 161, -1, 196, 160, 161, -1, + 196, 158, 160, 204, 161, 159, -1, 196, 158, 160, + 161, 159, -1, 196, 40, -1, 196, 41, -1, 196, + 230, -1, 196, 203, -1, 196, 25, -1, 169, 3, + -1, 169, 5, -1, 169, 4, -1, 169, 6, -1, + 11, 26, -1, 11, 27, -1, 170, 9, -1, 166, + 153, 202, 38, 196, 154, -1, 115, 153, 202, 241, + 154, -1, 129, 153, 202, 150, 202, 150, 202, 154, + -1, 164, 153, 202, 150, 202, 154, -1, 165, 153, + 202, 150, 202, 154, -1, 88, 167, 153, 202, 150, + 202, 154, -1, 89, 168, 153, 202, 150, 202, 154, + -1, 131, 153, 202, 150, 202, 154, -1, 132, 153, + 202, 150, 202, 150, 202, 154, -1, 133, 153, 202, + 150, 202, 150, 202, 154, -1, 204, 150, 202, -1, + 202, -1, 32, -1, 33, -1, 37, -1, -1, 198, + 230, -1, 121, 153, 207, 38, 196, 154, -1, 209, + -1, -1, 210, -1, 209, 210, -1, -1, 31, 211, + 226, -1, -1, 30, 212, 227, -1, 58, 57, 216, + -1, 173, 18, 196, -1, 173, 18, 10, -1, -1, + 175, 179, 206, 205, 202, 213, 193, -1, -1, 175, + 177, 179, 206, 205, 202, 214, 193, -1, -1, 175, + 178, 179, 206, 205, 196, 215, 193, -1, 175, 179, + 35, 182, 207, -1, 51, 217, -1, 54, 149, 218, + -1, 22, -1, 52, 149, 22, -1, 66, 149, 22, + -1, 155, 219, 157, -1, 219, 150, 22, -1, 22, + -1, -1, 220, 150, 196, 185, 172, -1, 196, 185, + 172, -1, 220, -1, 220, 150, 39, -1, 39, -1, + -1, 183, 198, 174, 153, 221, 154, 187, 192, 189, + 188, -1, 28, -1, 160, -1, 181, 179, 222, 223, + -1, 29, -1, 161, -1, 233, 225, -1, 180, 179, + 222, -1, -1, 59, -1, 3, -1, 4, -1, 9, + -1, 26, -1, 27, -1, 40, -1, 41, -1, 25, + -1, 158, 204, 159, -1, 203, -1, 57, 228, 22, + 150, 22, -1, 7, -1, 8, -1, 171, -1, 174, + -1, 230, -1, 229, -1, 196, 231, -1, 233, 234, + -1, 224, 234, -1, 235, 173, 236, -1, 235, 238, + -1, -1, 21, -1, 67, 232, -1, 67, 10, -1, + 68, 17, 231, -1, 68, 11, 231, 150, 17, 231, + 150, 17, 231, -1, 69, 169, 231, 150, 17, 231, + 155, 237, 157, -1, 69, 169, 231, 150, 17, 231, + 155, 157, -1, 70, 183, 198, 231, 153, 240, 154, + 187, 38, 17, 231, 71, 17, 231, -1, 71, -1, + 72, -1, 237, 169, 229, 150, 17, 231, -1, 169, + 229, 150, 17, 231, -1, 173, 243, -1, 196, 155, + 231, 150, 231, 157, -1, 239, 150, 155, 231, 150, + 231, 157, -1, 196, 185, 231, 185, -1, 17, 185, + 231, 185, -1, 240, 150, 196, 185, 231, 185, -1, + 240, 150, 17, 185, 231, 185, -1, -1, -1, 241, + 150, 232, -1, 56, 55, -1, 55, -1, 164, 196, + 231, 150, 231, -1, 165, 196, 231, 150, 231, -1, + 88, 167, 196, 231, 150, 231, -1, 89, 168, 196, + 231, 150, 231, -1, 166, 232, 38, 196, -1, 129, + 232, 150, 232, 150, 232, -1, 130, 232, 150, 196, + -1, 131, 232, 150, 232, -1, 132, 232, 150, 232, + 150, 232, -1, 133, 232, 150, 232, 150, 232, -1, + 128, 239, -1, 242, 183, 198, 231, 153, 240, 154, + 187, -1, 245, -1, 36, -1, -1, 110, 196, 190, + -1, 110, 196, 150, 11, 231, 190, -1, 111, 196, + 190, -1, 111, 196, 150, 11, 231, 190, -1, 112, + 232, -1, 244, 113, 196, 231, 190, -1, 244, 114, + 232, 150, 196, 231, 190, -1, 115, 196, 231, 241, + -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ @@ -1822,26 +1825,26 @@ 1192, 1193, 1194, 1198, 1199, 1200, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1227, 1228, 1233, 1234, 1235, 1236, 1237, 1238, - 1241, 1242, 1249, 1250, 1256, 1257, 1265, 1273, 1274, 1279, - 1280, 1281, 1286, 1299, 1299, 1299, 1299, 1299, 1299, 1299, - 1302, 1306, 1310, 1317, 1322, 1330, 1360, 1385, 1390, 1400, - 1410, 1414, 1424, 1431, 1440, 1447, 1452, 1457, 1464, 1465, - 1472, 1479, 1487, 1493, 1505, 1533, 1549, 1576, 1604, 1630, - 1650, 1676, 1696, 1708, 1715, 1781, 1791, 1801, 1807, 1817, - 1823, 1833, 1838, 1843, 1856, 1868, 1890, 1898, 1904, 1915, - 1920, 1925, 1931, 1937, 1946, 1950, 1958, 1958, 1961, 1961, - 1964, 1976, 1997, 2002, 2010, 2011, 2015, 2015, 2019, 2019, - 2022, 2025, 2049, 2060, 2060, 2071, 2070, 2080, 2079, 2090, - 2130, 2133, 2139, 2149, 2153, 2158, 2160, 2165, 2170, 2179, - 2189, 2200, 2204, 2213, 2222, 2227, 2357, 2357, 2359, 2368, - 2368, 2370, 2375, 2387, 2391, 2396, 2400, 2404, 2408, 2412, - 2416, 2420, 2424, 2428, 2453, 2457, 2467, 2471, 2475, 2480, - 2487, 2487, 2493, 2502, 2506, 2515, 2524, 2533, 2537, 2544, - 2548, 2552, 2557, 2567, 2586, 2595, 2679, 2683, 2690, 2701, - 2714, 2724, 2735, 2745, 2756, 2764, 2774, 2781, 2784, 2785, - 2792, 2796, 2801, 2817, 2834, 2848, 2862, 2874, 2882, 2889, - 2895, 2901, 2907, 2922, 3013, 3018, 3022, 3029, 3036, 3044, - 3051, 3059, 3067, 3081, 3098 + 1241, 1242, 1247, 1248, 1255, 1256, 1262, 1263, 1271, 1279, + 1280, 1285, 1286, 1287, 1292, 1305, 1305, 1305, 1305, 1305, + 1305, 1305, 1308, 1312, 1316, 1323, 1328, 1336, 1366, 1391, + 1396, 1406, 1416, 1420, 1430, 1437, 1446, 1453, 1458, 1463, + 1470, 1471, 1478, 1485, 1493, 1499, 1511, 1539, 1555, 1582, + 1610, 1636, 1656, 1682, 1702, 1714, 1721, 1787, 1797, 1807, + 1813, 1823, 1829, 1839, 1844, 1849, 1862, 1874, 1896, 1904, + 1910, 1921, 1926, 1931, 1937, 1943, 1952, 1956, 1964, 1964, + 1967, 1967, 1970, 1982, 2003, 2008, 2016, 2017, 2021, 2021, + 2025, 2025, 2028, 2031, 2055, 2066, 2066, 2077, 2076, 2086, + 2085, 2096, 2136, 2139, 2145, 2155, 2159, 2164, 2166, 2171, + 2176, 2185, 2195, 2206, 2210, 2219, 2228, 2233, 2367, 2367, + 2369, 2378, 2378, 2380, 2385, 2397, 2401, 2406, 2410, 2414, + 2418, 2422, 2426, 2430, 2434, 2438, 2463, 2467, 2477, 2481, + 2485, 2490, 2497, 2497, 2503, 2512, 2516, 2525, 2534, 2543, + 2547, 2554, 2558, 2562, 2567, 2577, 2596, 2605, 2689, 2693, + 2700, 2711, 2724, 2734, 2745, 2755, 2766, 2774, 2784, 2791, + 2794, 2795, 2802, 2806, 2811, 2827, 2844, 2858, 2872, 2884, + 2892, 2899, 2905, 2911, 2917, 2932, 3023, 3028, 3032, 3039, + 3046, 3054, 3061, 3069, 3077, 3091, 3108 }; #endif @@ -1872,7 +1875,7 @@ "PTRTOINT", "PHI_TOK", "SELECT", "VAARG", "EXTRACTELEMENT", "INSERTELEMENT", "SHUFFLEVECTOR", "SIGNEXT", "ZEROEXT", "NORETURN", "INREG", "SRET", "NOUNWIND", "NOALIAS", "BYVAL", "NEST", "READNONE", - "READONLY", "DEFAULT", "HIDDEN", "PROTECTED", "'='", "','", "'*'", + "READONLY", "GC", "DEFAULT", "HIDDEN", "PROTECTED", "'='", "','", "'*'", "'\\\\'", "'('", "')'", "'['", "'x'", "']'", "'<'", "'>'", "'{'", "'}'", "'c'", "$accept", "ArithmeticOps", "LogicalOps", "CastOps", "IPredicates", "FPredicates", "IntType", "FPType", "LocalName", @@ -1880,19 +1883,19 @@ "GlobalAssign", "GVInternalLinkage", "GVExternalLinkage", "GVVisibilityStyle", "FunctionDeclareLinkage", "FunctionDefineLinkage", "AliasLinkage", "OptCallingConv", "ParamAttr", "OptParamAttrs", - "FuncAttr", "OptFuncAttrs", "OptAlign", "OptCAlign", "SectionString", - "OptSection", "GlobalVarAttributes", "GlobalVarAttribute", "PrimType", - "Types", "ArgType", "ResultTypes", "ArgTypeList", "ArgTypeListI", - "TypeListI", "ConstVal", "ConstExpr", "ConstVector", "GlobalType", - "ThreadLocal", "AliaseeRef", "Module", "DefinitionList", "Definition", - "@1", "@2", "@3", "@4", "@5", "AsmBlock", "TargetDefinition", - "LibrariesDefinition", "LibList", "ArgListH", "ArgList", - "FunctionHeaderH", "BEGIN", "FunctionHeader", "END", "Function", - "FunctionProto", "OptSideEffect", "ConstValueRef", "SymbolicValueRef", - "ValueRef", "ResolvedVal", "BasicBlockList", "BasicBlock", - "InstructionList", "BBTerminatorInst", "JumpTable", "Inst", "PHIList", - "ParamList", "IndexList", "OptTailCall", "InstVal", "OptVolatile", - "MemoryInst", 0 + "FuncAttr", "OptFuncAttrs", "OptGC", "OptAlign", "OptCAlign", + "SectionString", "OptSection", "GlobalVarAttributes", + "GlobalVarAttribute", "PrimType", "Types", "ArgType", "ResultTypes", + "ArgTypeList", "ArgTypeListI", "TypeListI", "ConstVal", "ConstExpr", + "ConstVector", "GlobalType", "ThreadLocal", "AliaseeRef", "Module", + "DefinitionList", "Definition", "@1", "@2", "@3", "@4", "@5", "AsmBlock", + "TargetDefinition", "LibrariesDefinition", "LibList", "ArgListH", + "ArgList", "FunctionHeaderH", "BEGIN", "FunctionHeader", "END", + "Function", "FunctionProto", "OptSideEffect", "ConstValueRef", + "SymbolicValueRef", "ValueRef", "ResolvedVal", "BasicBlockList", + "BasicBlock", "InstructionList", "BBTerminatorInst", "JumpTable", "Inst", + "PHIList", "ParamList", "IndexList", "OptTailCall", "InstVal", + "OptVolatile", "MemoryInst", 0 }; #endif @@ -1915,47 +1918,47 @@ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 61, 44, - 42, 92, 40, 41, 91, 120, 93, 60, 62, 123, - 125, 99 + 395, 396, 397, 398, 399, 400, 401, 402, 403, 61, + 44, 42, 92, 40, 41, 91, 120, 93, 60, 62, + 123, 125, 99 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 162, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 164, 164, 164, 164, 164, 164, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 166, + 0, 163, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 165, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 168, 169, 169, 169, 169, - 169, 170, 170, 170, 171, 171, 172, 172, 173, 173, - 174, 174, 175, 176, 176, 176, 176, 176, 177, 177, - 177, 178, 178, 178, 178, 179, 179, 179, 180, 180, - 180, 180, 180, 181, 181, 181, 182, 182, 182, 182, - 182, 182, 182, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 184, 184, 185, 185, 185, 185, 185, 185, - 186, 186, 187, 187, 188, 188, 189, 190, 190, 191, - 191, 192, 192, 193, 193, 193, 193, 193, 193, 193, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 195, 196, 196, 197, 197, 198, 198, - 198, 198, 199, 199, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 201, 201, 201, 201, 201, 201, - 201, 201, 201, 201, 202, 202, 203, 203, 204, 204, - 205, 205, 206, 206, 207, 207, 209, 208, 210, 208, - 208, 208, 208, 211, 208, 212, 208, 213, 208, 208, - 208, 208, 214, 215, 215, 216, 217, 217, 217, 218, - 218, 219, 219, 219, 219, 220, 221, 221, 222, 223, - 223, 224, 225, 226, 226, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 228, 228, 228, 228, - 229, 229, 230, 231, 231, 232, 233, 233, 233, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 235, 235, - 236, 237, 237, 238, 238, 238, 238, 238, 239, 239, - 240, 240, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 242, 242, 243, 243, 243, - 243, 243, 243, 243, 243 + 167, 167, 167, 167, 167, 167, 167, 167, 167, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 169, 170, 170, 170, 170, + 170, 171, 171, 171, 172, 172, 173, 173, 174, 174, + 175, 175, 176, 177, 177, 177, 177, 177, 178, 178, + 178, 179, 179, 179, 179, 180, 180, 180, 181, 181, + 181, 181, 181, 182, 182, 182, 183, 183, 183, 183, + 183, 183, 183, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 185, 185, 186, 186, 186, 186, 186, 186, + 187, 187, 188, 188, 189, 189, 190, 190, 191, 192, + 192, 193, 193, 194, 194, 195, 195, 195, 195, 195, + 195, 195, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 197, 198, 198, 199, 199, + 200, 200, 200, 200, 201, 201, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 204, 204, 205, 205, + 206, 206, 207, 207, 208, 208, 209, 209, 211, 210, + 212, 210, 210, 210, 210, 213, 210, 214, 210, 215, + 210, 210, 210, 210, 216, 217, 217, 218, 219, 219, + 219, 220, 220, 221, 221, 221, 221, 222, 223, 223, + 224, 225, 225, 226, 227, 228, 228, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, + 230, 230, 231, 231, 232, 233, 233, 234, 235, 235, + 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 237, 237, 238, 239, 239, 240, 240, 240, 240, 240, + 241, 241, 242, 242, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 244, 244, 245, + 245, 245, 245, 245, 245, 245, 245 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1973,26 +1976,26 @@ 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, - 0, 2, 0, 2, 0, 3, 2, 0, 1, 0, - 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 1, 2, 5, 5, 5, 5, 3, - 2, 5, 4, 2, 1, 1, 1, 3, 1, 3, - 1, 0, 1, 3, 4, 3, 3, 4, 4, 3, - 6, 5, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 6, 5, 8, 6, 6, 7, - 7, 6, 8, 8, 3, 1, 1, 1, 1, 0, - 2, 6, 1, 0, 1, 2, 0, 3, 0, 3, - 3, 3, 3, 0, 7, 0, 8, 0, 8, 5, - 2, 3, 1, 3, 3, 3, 3, 1, 0, 5, - 3, 1, 3, 1, 0, 9, 1, 1, 4, 1, - 1, 2, 3, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 5, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 3, 2, 0, 1, 2, - 2, 3, 9, 9, 8, 14, 1, 1, 6, 5, - 2, 6, 7, 4, 4, 6, 6, 0, 0, 3, - 2, 1, 5, 5, 6, 6, 4, 6, 4, 4, - 6, 6, 2, 8, 1, 1, 0, 3, 6, 3, - 6, 2, 5, 7, 4 + 0, 2, 0, 2, 0, 2, 0, 3, 2, 0, + 1, 0, 3, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 2, 5, 5, 5, + 5, 3, 2, 5, 4, 2, 1, 1, 1, 3, + 1, 3, 1, 0, 1, 3, 4, 3, 3, 4, + 4, 3, 6, 5, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 6, 5, 8, 6, + 6, 7, 7, 6, 8, 8, 3, 1, 1, 1, + 1, 0, 2, 6, 1, 0, 1, 2, 0, 3, + 0, 3, 3, 3, 3, 0, 7, 0, 8, 0, + 8, 5, 2, 3, 1, 3, 3, 3, 3, 1, + 0, 5, 3, 1, 3, 1, 0, 10, 1, 1, + 4, 1, 1, 2, 3, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 5, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 3, 2, 0, + 1, 2, 2, 3, 9, 9, 8, 14, 1, 1, + 6, 5, 2, 6, 7, 4, 4, 6, 6, 0, + 0, 3, 2, 1, 5, 5, 6, 6, 4, 6, + 4, 4, 6, 6, 2, 8, 1, 1, 0, 3, + 6, 3, 6, 2, 5, 7, 4 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -2000,67 +2003,68 @@ means the default is an error. */ static const yytype_uint16 yydefact[] = { - 71, 61, 68, 62, 69, 63, 208, 206, 0, 0, - 0, 0, 0, 0, 81, 70, 0, 71, 204, 85, - 88, 0, 0, 220, 0, 0, 66, 0, 72, 73, + 71, 61, 68, 62, 69, 63, 210, 208, 0, 0, + 0, 0, 0, 0, 81, 70, 0, 71, 206, 85, + 88, 0, 0, 222, 0, 0, 66, 0, 72, 73, 75, 74, 76, 78, 77, 79, 80, 82, 83, 84, - 81, 81, 199, 1, 205, 86, 87, 81, 209, 89, - 90, 91, 92, 81, 267, 207, 267, 0, 0, 228, - 221, 222, 210, 256, 257, 212, 133, 134, 135, 138, - 137, 136, 139, 140, 0, 0, 0, 0, 258, 259, - 141, 211, 143, 199, 199, 93, 198, 0, 96, 96, - 268, 264, 67, 239, 240, 241, 263, 223, 224, 227, - 0, 161, 144, 0, 0, 0, 0, 150, 162, 0, - 142, 161, 0, 0, 95, 94, 0, 196, 197, 0, - 0, 97, 98, 99, 100, 101, 0, 242, 0, 306, - 266, 0, 225, 160, 112, 156, 158, 0, 0, 0, - 0, 0, 0, 149, 0, 0, 0, 155, 0, 154, - 0, 219, 133, 134, 135, 138, 137, 136, 0, 0, - 0, 213, 102, 0, 236, 237, 238, 305, 291, 0, - 0, 0, 0, 96, 276, 277, 2, 3, 4, 5, + 81, 81, 201, 1, 207, 86, 87, 81, 211, 89, + 90, 91, 92, 81, 269, 209, 269, 0, 0, 230, + 223, 224, 212, 258, 259, 214, 135, 136, 137, 140, + 139, 138, 141, 142, 0, 0, 0, 0, 260, 261, + 143, 213, 145, 201, 201, 93, 200, 0, 96, 96, + 270, 266, 67, 241, 242, 243, 265, 225, 226, 229, + 0, 163, 146, 0, 0, 0, 0, 152, 164, 0, + 144, 163, 0, 0, 95, 94, 0, 198, 199, 0, + 0, 97, 98, 99, 100, 101, 0, 244, 0, 308, + 268, 0, 227, 162, 112, 158, 160, 0, 0, 0, + 0, 0, 0, 151, 0, 0, 0, 157, 0, 156, + 0, 221, 135, 136, 137, 140, 139, 138, 0, 0, + 0, 215, 102, 0, 238, 239, 240, 307, 293, 0, + 0, 0, 0, 96, 278, 279, 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 11, 12, 13, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 265, 96, - 280, 0, 304, 226, 153, 0, 120, 0, 0, 152, - 0, 163, 120, 215, 217, 0, 200, 181, 182, 177, - 179, 178, 180, 183, 176, 172, 173, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 267, 96, + 282, 0, 306, 228, 155, 0, 120, 0, 0, 154, + 0, 165, 120, 217, 219, 0, 202, 183, 184, 179, + 181, 180, 182, 185, 178, 174, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 175, 174, 129, 0, 290, 270, 0, 269, 0, + 0, 177, 176, 131, 0, 292, 272, 0, 271, 0, 0, 55, 0, 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 0, 53, 54, 49, 50, 51, 52, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 0, 124, 124, 311, 0, 0, 302, 0, 0, + 48, 0, 126, 126, 313, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, - 106, 105, 103, 107, 108, 109, 110, 111, 113, 159, - 157, 146, 147, 148, 151, 145, 129, 129, 0, 0, - 0, 0, 0, 0, 0, 0, 165, 195, 0, 0, - 0, 169, 0, 166, 0, 0, 0, 0, 214, 234, - 245, 246, 247, 252, 248, 249, 250, 251, 243, 0, - 254, 261, 260, 262, 0, 271, 0, 0, 0, 0, - 0, 307, 0, 309, 288, 0, 0, 0, 0, 0, + 106, 105, 103, 107, 108, 109, 110, 111, 113, 161, + 159, 148, 149, 150, 153, 147, 131, 131, 0, 0, + 0, 0, 0, 0, 0, 0, 167, 197, 0, 0, + 0, 171, 0, 168, 0, 0, 0, 0, 216, 236, + 247, 248, 249, 254, 250, 251, 252, 253, 245, 0, + 256, 263, 262, 264, 0, 273, 0, 0, 0, 0, + 0, 309, 0, 311, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 116, - 114, 115, 118, 119, 121, 216, 218, 0, 0, 0, - 288, 0, 0, 0, 0, 0, 164, 150, 162, 0, - 167, 168, 0, 0, 0, 0, 0, 131, 129, 233, - 112, 231, 0, 244, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 314, 0, 0, 0, 298, 299, - 0, 0, 0, 0, 296, 0, 124, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 194, 171, 0, 0, - 0, 0, 126, 132, 130, 65, 0, 120, 0, 253, - 0, 0, 287, 0, 0, 124, 125, 124, 0, 0, - 0, 0, 0, 0, 292, 293, 287, 0, 312, 0, - 201, 0, 0, 185, 0, 0, 0, 0, 170, 0, - 0, 0, 64, 230, 232, 112, 127, 0, 0, 0, - 112, 112, 0, 294, 295, 308, 310, 289, 0, 0, - 297, 300, 301, 0, 124, 0, 0, 0, 191, 0, - 0, 187, 188, 184, 65, 128, 122, 255, 0, 0, - 0, 0, 0, 120, 281, 0, 120, 313, 189, 190, - 0, 0, 0, 229, 0, 235, 0, 274, 0, 0, - 104, 106, 112, 112, 112, 112, 0, 282, 303, 186, - 192, 193, 123, 272, 0, 273, 0, 284, 283, 0, - 0, 0, 0, 0, 112, 112, 0, 0, 0, 286, - 285, 0, 279, 0, 0, 278, 0, 275 + 114, 115, 118, 119, 121, 218, 220, 0, 0, 0, + 290, 0, 0, 0, 0, 0, 166, 152, 164, 0, + 169, 170, 0, 0, 0, 0, 0, 133, 131, 235, + 112, 233, 0, 246, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 316, 0, 0, 0, 300, 301, + 0, 0, 0, 0, 298, 0, 126, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 196, 173, 0, 0, + 0, 0, 128, 134, 132, 65, 0, 120, 0, 255, + 0, 0, 289, 0, 0, 126, 127, 126, 0, 0, + 0, 0, 0, 0, 294, 295, 289, 0, 314, 0, + 203, 0, 0, 187, 0, 0, 0, 0, 172, 0, + 0, 0, 64, 232, 234, 112, 129, 0, 0, 0, + 112, 112, 0, 296, 297, 310, 312, 291, 0, 0, + 299, 302, 303, 0, 126, 0, 0, 0, 193, 0, + 0, 189, 190, 186, 65, 130, 124, 257, 0, 0, + 0, 0, 0, 120, 283, 0, 120, 315, 191, 192, + 0, 0, 0, 231, 0, 122, 0, 276, 0, 0, + 104, 106, 112, 112, 112, 112, 0, 284, 305, 188, + 194, 195, 125, 0, 237, 274, 0, 275, 0, 286, + 285, 0, 0, 0, 123, 0, 0, 112, 112, 0, + 0, 0, 288, 287, 0, 281, 0, 0, 280, 0, + 277 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -2068,472 +2072,475 @@ { -1, 258, 259, 260, 284, 301, 158, 159, 78, 513, 12, 79, 14, 15, 40, 41, 42, 47, 53, 116, - 126, 328, 224, 404, 331, 565, 381, 427, 546, 358, - 428, 80, 160, 135, 150, 136, 137, 109, 347, 370, - 348, 119, 87, 151, 16, 17, 18, 20, 19, 263, - 336, 337, 62, 23, 60, 100, 431, 432, 127, 166, - 54, 95, 55, 48, 434, 371, 82, 373, 268, 56, - 91, 92, 218, 569, 130, 307, 522, 444, 219, 220, - 221, 222 + 126, 328, 224, 404, 331, 584, 565, 381, 427, 546, + 358, 428, 80, 160, 135, 150, 136, 137, 109, 347, + 370, 348, 119, 87, 151, 16, 17, 18, 20, 19, + 263, 336, 337, 62, 23, 60, 100, 431, 432, 127, + 166, 54, 95, 55, 48, 434, 371, 82, 373, 268, + 56, 91, 92, 218, 569, 130, 307, 522, 444, 219, + 220, 221, 222 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -546 +#define YYPACT_NINF -541 static const yytype_int16 yypact[] = { - 47, -546, -546, -546, -546, -546, -546, -546, -17, -95, - 52, -90, 86, 14, 183, -546, 135, 1758, -546, -10, - 64, 18, 33, -546, 5, 180, -546, 1341, -546, -546, - -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, - 76, 76, 59, -546, -546, -546, -546, 76, -546, -546, - -546, -546, -546, 76, 193, -546, 13, 202, 224, 233, - -546, -546, -546, -546, -546, 111, -546, -546, -546, -546, - -546, -546, -546, -546, 260, 261, 1, 378, -546, -546, - -546, -7, -546, 231, 231, 150, -546, 55, 309, 309, - -546, -546, 100, -546, -546, -546, -546, -546, -546, -546, - -99, 1088, -546, 116, 122, 988, 111, -546, -7, -106, - -546, 1088, 55, 55, -546, -546, 1142, -546, -546, 1359, - 274, -546, -546, -546, -546, -546, 1414, -546, -18, 1624, - -546, 257, -546, -546, -7, -546, 131, 128, 1454, 1454, - 129, -105, 1454, -546, 136, 1359, 1454, 111, 141, -7, - 237, -546, 214, 279, 285, 289, 291, 294, 145, 299, - 803, -546, -546, 103, -546, -546, -546, -546, -546, 254, - 1512, 57, 301, 309, -546, -546, -546, -546, -546, -546, - -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, - -546, 596, 646, 1454, 1454, 1454, 1454, -546, -546, -546, - -546, -546, -546, -546, -546, -546, -546, -546, -546, 1454, - 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, -546, 309, - -546, 61, -546, -546, 132, 1182, -546, -57, -69, -546, - 155, -7, -546, -546, -7, 1142, -546, -546, -546, -546, - -546, -546, -546, -546, -546, -546, -546, 596, 646, 162, - 163, 164, 166, 167, 1242, 1530, 1028, 303, 169, 174, - 179, -546, -546, 185, 191, -546, 111, 644, -546, 780, - 780, -546, 780, 1414, -546, -546, -546, -546, -546, -546, - -546, -546, -546, -546, 1454, -546, -546, -546, -546, -546, - -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, - -546, 1454, 30, 48, -546, 644, -21, 197, 199, 203, - 204, 205, 206, 644, 644, 313, 1414, 1454, 1454, -546, - -546, -546, -546, -546, -546, -546, -546, -546, -546, -546, - -546, 201, -546, -546, -546, 201, 185, 185, 320, 207, - 208, 1359, 1359, 1359, 1359, 1359, -546, -546, -65, 1068, - -86, -546, -104, -546, 1359, 1359, 1359, -20, -546, 1261, - -546, -546, -546, -546, -546, -546, -546, -546, 273, 1359, - -546, -546, -546, -546, 217, -546, 218, 780, 644, 644, - 8, -546, 11, -546, -546, 780, 221, 1454, 1454, 1454, - 1454, 1454, 227, 234, 1454, 780, 644, 235, -546, -546, - -546, -546, -546, -546, -546, -546, -546, 1454, 1359, 1359, - -546, 247, 258, 263, 265, 1359, -546, 259, 803, -101, - -546, -546, 269, 270, 344, 398, 419, -546, 185, -546, - -7, 276, 275, -546, 404, -76, 412, 413, 282, 288, - 292, 780, 440, 780, 297, 300, 780, 302, -7, -546, - 304, 308, 780, 780, -7, 306, 310, 1454, -35, 311, - 314, -73, 1359, 1359, 1359, 1359, -546, -546, 315, 1359, - 1359, 1454, -546, -546, -546, 298, 1301, -546, 319, -546, - 780, 780, 1570, 780, 780, 310, -546, 310, 1454, 780, - 322, 1454, 1454, 1454, -546, -546, 1570, 399, -546, 644, - -546, 1359, 1359, -546, 323, 316, 325, 327, -546, 324, - 326, 60, -546, -546, -546, -7, 3, 460, 334, 330, - 82, -7, -13, -546, -546, -546, -546, -546, 332, 780, - -546, -546, -546, 12, 310, 336, 337, 1359, -546, 1359, - 1359, -546, -546, -546, 298, -546, 438, -546, 475, -4, - 493, 493, 1610, -546, -546, 338, -546, -546, -546, -546, - 342, 345, 346, -546, 501, -546, 780, -546, 940, 2, - 354, 355, -546, -546, 82, -7, 72, -546, 201, -546, - -546, -546, -546, -546, 359, -546, 940, 132, 132, 493, - 493, 492, 494, 361, -546, -546, 780, 780, 497, 132, - 132, 450, -546, 780, 505, -546, 780, -546 + 658, -541, -541, -541, -541, -541, -541, -541, -12, -135, + -38, -125, 106, -69, 26, -541, 29, 1762, -541, 14, + 88, 43, 49, -541, 45, 127, -541, 1344, -541, -541, + -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, + 131, 131, 73, -541, -541, -541, -541, 131, -541, -541, + -541, -541, -541, 131, 201, -541, -11, 135, 215, 216, + -541, -541, -541, -541, -541, 70, -541, -541, -541, -541, + -541, -541, -541, -541, 245, 247, 3, 553, -541, -541, + -541, -34, -541, 219, 219, 110, -541, 62, 171, 171, + -541, -541, 124, -541, -541, -541, -541, -541, -541, -541, + -66, 1092, -541, 108, 114, 991, 70, -541, -34, -109, + -541, 1092, 62, 62, -541, -541, 1146, -541, -541, 1362, + 261, -541, -541, -541, -541, -541, 1418, -541, -15, 1628, + -541, 260, -541, -541, -34, -541, 119, 129, 1458, 1458, + 147, -108, 1458, -541, 134, 1362, 1458, 70, 142, -34, + 118, -541, 40, 306, 307, 308, 309, 310, 172, 311, + 805, -541, -541, 113, -541, -541, -541, -541, -541, 266, + 1516, 72, 314, 171, -541, -541, -541, -541, -541, -541, + -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, + -541, 313, 507, 1458, 1458, 1458, 1458, -541, -541, -541, + -541, -541, -541, -541, -541, -541, -541, -541, -541, 1458, + 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, -541, 171, + -541, 52, -541, -541, -36, 1186, -541, -94, -30, -541, + 163, -34, -541, -541, -34, 1146, -541, -541, -541, -541, + -541, -541, -541, -541, -541, -541, -541, 313, 507, 176, + 178, 184, 185, 187, 1246, 1534, 1031, 302, 190, 193, + 198, -541, -541, 202, 200, -541, 70, 645, -541, 782, + 782, -541, 782, 1418, -541, -541, -541, -541, -541, -541, + -541, -541, -541, -541, 1458, -541, -541, -541, -541, -541, + -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, + -541, 1458, 136, 146, -541, 645, 104, 206, 207, 208, + 209, 210, 217, 645, 645, 328, 1418, 1458, 1458, -541, + -541, -541, -541, -541, -541, -541, -541, -541, -541, -541, + -541, 137, -541, -541, -541, 137, 202, 202, 333, 221, + 222, 1362, 1362, 1362, 1362, 1362, -541, -541, -64, 1071, + -103, -541, -100, -541, 1362, 1362, 1362, 2, -541, 1264, + -541, -541, -541, -541, -541, -541, -541, -541, 317, 1362, + -541, -541, -541, -541, 227, -541, 230, 782, 645, 645, + 11, -541, 12, -541, -541, 782, 228, 1458, 1458, 1458, + 1458, 1458, 232, 234, 1458, 782, 645, 235, -541, -541, + -541, -541, -541, -541, -541, -541, -541, 1458, 1362, 1362, + -541, 239, 241, 243, 244, 1362, -541, 256, 805, -73, + -541, -541, 248, 250, 385, 404, 423, -541, 202, -541, + -34, 278, 280, -541, 413, -72, 419, 420, 288, 292, + 293, 782, 440, 782, 296, 297, 782, 299, -34, -541, + 301, 303, 782, 782, -34, 304, 318, 1458, 151, 319, + 321, -43, 1362, 1362, 1362, 1362, -541, -541, 295, 1362, + 1362, 1458, -541, -541, -541, 279, 1304, -541, 322, -541, + 782, 782, 1574, 782, 782, 318, -541, 318, 1458, 782, + 323, 1458, 1458, 1458, -541, -541, 1574, 399, -541, 645, + -541, 1362, 1362, -541, 324, 305, 326, 327, -541, 325, + 329, 157, -541, -541, -541, -34, 81, 436, 332, 330, + 9, -34, 47, -541, -541, -541, -541, -541, 334, 782, + -541, -541, -541, 96, 318, 336, 338, 1362, -541, 1362, + 1362, -541, -541, -541, 279, -541, 407, -541, 444, -6, + 505, 505, 1614, -541, -541, 337, -541, -541, -541, -541, + 339, 342, 343, -541, 459, 341, 782, -541, 943, -2, + 331, 348, -541, -541, 9, -34, 109, -541, 137, -541, + -541, -541, -541, 442, -541, -541, 352, -541, 943, -36, + -36, 505, 505, 470, -541, 486, 354, -541, -541, 782, + 782, 488, -36, -36, 435, -541, 782, 490, -541, 782, + -541 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -546, 394, 395, 396, 280, 283, -170, -546, 0, -16, - 444, 15, -546, -546, -546, -546, -1, -546, -546, -546, - -157, -546, -418, -546, -229, -546, -292, 23, -546, -307, - -546, -546, -26, 305, -120, -546, 429, 436, -59, -156, - -235, 126, 168, 307, -546, -546, 526, -546, -546, -546, - -546, -546, -546, -546, -546, -546, -546, -546, 456, -546, - -546, -546, -546, -546, -546, -545, -142, 108, -186, -546, - 490, -546, -546, -546, -546, -546, 51, 138, -546, -546, - -546, -546 + -541, 381, 382, 387, 270, 271, -170, -541, 0, -24, + 426, 8, -541, -541, -541, -541, 56, -541, -541, -541, + -161, -541, -393, -541, -217, -541, -541, -292, 5, -541, + -310, -541, -541, -26, 298, -120, -541, 411, 430, -115, + -157, -235, 94, 130, 312, -541, -541, 519, -541, -541, + -541, -541, -541, -541, -541, -541, -541, -541, -541, 448, + -541, -541, -541, -541, -541, -541, -540, -111, -51, -179, + -541, 482, -541, -541, -541, -541, -541, 46, 133, -541, + -541, -541, -541 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -204 +#define YYTABLE_NINF -206 static const yytype_int16 yytable[] = { - 11, 81, 272, 335, 261, 104, 163, 271, 236, 304, - 164, 383, 475, 271, 425, 13, 273, 11, 262, 441, - 350, 352, 443, 584, 308, 309, 310, 311, 312, 405, - 406, 315, 13, 426, 90, 21, 45, 425, 46, 83, - 84, 593, 93, 142, 142, 415, 88, -203, 415, 22, - 131, 108, 89, 24, 143, 230, 421, 132, 26, 468, - 161, 442, 316, 415, 442, -67, 1, 2, 269, 3, - 4, 5, 420, 415, 270, 134, 488, 6, 7, 108, - 503, 110, 479, 111, 415, 134, 233, 117, 118, 333, - 149, 416, 11, 110, 85, 111, 86, 544, 8, 332, - 149, 9, 550, 551, 27, 10, 49, 50, 51, 25, - 591, 52, 227, 228, 419, 110, 231, 111, 500, 1, - 234, 474, 3, 2, 5, 372, 4, 372, 372, 110, - 372, 111, 397, 385, 435, 43, 552, 398, 399, 400, - 553, 165, 401, 110, 267, 111, 402, 403, 239, 240, - 241, 242, 567, 377, 587, 588, 589, 590, 585, 59, - 105, 552, 28, 372, 498, 556, 57, 302, 303, 267, - 305, 372, 372, 94, 317, 318, 599, 600, 264, 380, - 110, 58, 111, 306, 267, 267, 267, 267, 267, 313, - 314, 267, 114, 525, 115, 526, 395, 382, 110, 134, - 111, 447, 61, 449, 450, 451, 398, 399, 400, 149, - 110, 401, 111, 543, 90, 402, 403, -55, -55, -55, - -55, 37, 38, 39, 97, 29, 30, 31, 32, 33, - 34, 35, -139, 36, -139, 372, 372, 372, 145, 146, - 237, 238, 557, 372, 63, 64, 98, 149, 516, 319, - 320, 112, 113, 372, 372, 99, 1, 2, 378, 3, - 4, 5, 261, 101, 102, 103, 321, 322, 86, 323, - 324, 138, 325, 326, 327, 379, 262, 139, 162, 223, - 225, 226, 410, 411, 412, 413, 414, 229, -56, 232, - 149, 396, 267, 235, -57, 422, 423, 424, -60, 372, - -59, 372, 527, -58, 372, 530, 531, 532, 243, 265, - 372, 372, 271, 334, 341, 342, 343, 1, 344, 345, - 3, 354, 5, 418, 576, 353, 355, 578, 37, 38, - 39, 356, 433, 430, 357, 398, 399, 400, 372, 372, - 401, 372, 372, 359, 402, 403, 386, 372, 387, 459, - 460, 394, 388, 389, 390, 391, 466, 372, 407, 408, - 409, 267, 448, 267, 267, 267, 436, 437, 454, 120, - 121, 122, 123, 124, 125, 446, 452, 374, 375, 568, - 376, 458, 471, 453, 457, 63, 64, 372, 106, 66, - 67, 68, 69, 70, 71, 72, 462, 1, 2, 586, - 3, 4, 5, 504, 505, 506, 507, 463, 372, 372, - 509, 510, 464, 384, 465, 319, 320, 467, 469, 470, - 472, 392, 393, 473, 372, 476, 478, 73, 477, 480, - 481, 499, 321, 322, 482, 323, 324, 483, 325, 326, - 327, 484, 535, 536, 486, 511, 488, 372, 372, 489, - 515, 491, 442, 492, 372, 372, 521, 493, 496, 497, - 501, 372, 267, 502, 372, 267, 267, 267, 517, 538, - 521, 529, 537, 508, 539, 512, 540, 541, 560, 542, - 561, 562, 547, 548, 549, 438, 439, 440, 554, 558, - 559, 564, 566, 445, 577, 579, 360, 361, 580, 581, - 63, 64, 362, 455, 456, 582, -18, -19, 592, 596, - 598, 597, 1, 2, 603, 3, 4, 5, 363, 364, - 365, 604, 606, 215, 216, 217, 575, 339, 563, 74, - 330, 340, 75, 366, 367, 76, 129, 77, 107, 545, - 144, 141, 338, 44, 512, 128, 96, 533, 461, 485, - 368, 487, 0, 0, 490, 0, 0, 0, 0, 0, - 494, 495, 0, 0, 0, 0, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 247, 248, 0, 0, 0, 0, 0, 518, 519, - 0, 523, 524, 0, 0, 0, 0, 528, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 534, 249, 197, - 570, 571, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 0, 250, 0, 251, 252, 253, 321, 322, 0, - 323, 324, 0, 325, 326, 327, 0, 555, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 360, 361, 0, - 369, 63, 64, 362, 0, 0, 0, 0, 572, 573, - 0, 0, 0, 1, 2, 0, 3, 4, 5, 363, - 364, 365, 285, 286, 583, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 366, 367, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 0, 594, 595, 0, - 0, 368, 0, 0, 601, 602, 0, 0, 0, 0, - 0, 605, 0, 0, 607, 0, 0, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 247, 248, 0, 0, 0, 0, 0, 0, - 0, 0, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 0, 0, 0, 249, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 0, 250, 0, 251, 252, 253, 0, 0, - 0, 0, 0, 360, 361, 0, 0, 63, 64, 362, - 0, 0, 0, 0, 110, 0, 111, 0, 0, 1, - 2, 369, 3, 4, 5, 363, 364, 365, 0, 0, - 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, - 366, 367, 1, 2, 0, 3, 4, 5, 244, 0, - 0, 0, 0, 0, 0, 0, 0, 368, 0, 0, - 0, 0, 0, 245, 246, 0, 0, 0, 0, 0, - 0, 0, 0, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 247, 248, - 0, 0, 0, 0, 0, 0, 176, 177, 178, 179, + 11, 81, 272, 261, 161, 271, 163, 104, 13, 271, + 90, 383, 273, 164, 24, 335, 304, 11, 93, 25, + 350, 352, 441, 443, 26, 13, 405, 406, 586, 43, + 233, 308, 309, 310, 311, 312, 425, 475, 315, 236, + 21, 142, 142, -55, -55, -55, -55, 415, 596, 262, + 415, 108, 143, 230, 22, 426, 420, 110, 316, 111, + 45, 421, 46, 332, 442, 442, 237, 238, 29, 30, + 31, 32, 33, 34, 35, 134, 36, 415, 415, 108, + 28, 319, 320, 269, 131, 134, 415, 479, 468, 270, + 149, 132, 11, 416, 117, 118, 83, 84, 321, 322, + 149, 323, 324, 88, 325, 326, 327, 488, 85, 89, + 86, 503, 227, 228, 419, 425, 231, 110, 474, 111, + 234, 110, 544, 111, 27, 63, 64, 550, 551, 333, + 49, 50, 51, 2, 435, 52, 4, 1, 2, 397, + 3, 4, 5, 1, 267, 165, 3, 593, 5, 61, + 94, 567, 114, 377, 115, 587, 372, 97, 372, 372, + -141, 372, -141, 105, 498, 317, 318, 302, 303, 267, + 305, 264, 37, 38, 39, 239, 240, 241, 242, 589, + 590, 591, 592, 306, 267, 267, 267, 267, 267, 313, + 314, 267, 57, 525, 372, 526, 395, 552, 58, 134, + 59, 553, 372, 372, 602, 603, 145, 146, 447, 149, + 449, 450, 451, 112, 113, 398, 399, 400, 374, 375, + 401, 376, 90, 101, 402, 403, 410, 411, 412, 413, + 414, 120, 121, 122, 123, 124, 125, 98, 99, 422, + 423, 424, 557, 398, 399, 400, 552, 149, 401, 102, + 556, 103, 402, 403, 384, 110, 86, 111, 378, 385, + 516, 261, 392, 393, 138, 162, 372, 372, 372, 225, + 139, 398, 399, 400, 372, 379, 401, 37, 38, 39, + 402, 403, 223, 226, 372, 372, 380, 110, 232, 111, + 149, 396, 267, 459, 460, 235, 382, 110, 1, 111, + 466, 3, 110, 5, 111, 500, 229, 262, 110, 527, + 111, 543, 530, 531, 532, -56, -57, -60, -59, -58, + 243, 265, 334, 418, 353, 271, 438, 439, 440, 341, + 372, 342, 372, 430, 445, 372, 576, 343, 344, 578, + 345, 372, 372, 354, 455, 456, 355, 504, 505, 506, + 507, 356, 357, 359, 509, 510, 386, 387, 388, 389, + 390, 267, 448, 267, 267, 267, 394, 391, 454, 372, + 372, 407, 372, 372, 408, 409, 433, 436, 372, 568, + 437, 458, 452, 446, 453, 457, 535, 536, 372, 462, + 485, 463, 487, 464, 465, 490, 319, 320, 469, 588, + 470, 494, 495, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 321, 322, 467, 323, 324, 372, 325, + 326, 327, 560, 471, 561, 562, 472, 473, 476, 518, + 519, 499, 523, 524, 477, 478, 480, 481, 528, 372, + 372, 482, 483, 484, 486, 511, 488, 489, 534, 491, + 515, 492, 442, 493, 508, 372, 521, 496, 547, 538, + 564, 566, 267, 582, 594, 267, 267, 267, 497, 501, + 521, 502, 517, 529, 537, 512, 539, 540, 555, 541, + 372, 372, 548, 542, -18, 549, 583, 599, 372, 372, + 558, 554, 559, 579, 577, 372, 580, 581, 372, 572, + 573, -19, 595, 600, 601, 606, 607, 609, 360, 361, + 215, 216, 63, 64, 362, 585, 217, 339, 129, 340, + 563, 545, 144, 330, 1, 2, 575, 3, 4, 5, + 363, 364, 365, 285, 286, 141, 44, 128, 96, 0, + 597, 598, 533, 461, 512, 366, 367, 338, 604, 605, + 0, 0, 0, 0, 0, 608, 0, 0, 610, 0, + 63, 64, 368, 106, 66, 67, 68, 69, 70, 71, + 72, 0, 1, 2, 0, 3, 4, 5, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 247, 248, 0, 0, 0, 0, 0, + 0, 0, 73, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 0, 0, 0, + 249, 197, 570, 571, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 0, 250, 0, 251, 252, 253, 321, + 322, 0, 323, 324, 0, 325, 326, 327, 360, 361, + 0, 0, 63, 64, 362, 0, 0, 0, -205, 0, + 0, 0, 0, 369, 1, 2, 0, 3, 4, 5, + 363, 364, 365, 0, 0, 0, -67, 1, 2, 0, + 3, 4, 5, 0, 0, 366, 367, 0, 6, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 0, 74, 0, 0, 75, 8, + 0, 76, 9, 77, 107, 0, 10, 0, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 247, 248, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 249, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 0, 250, 0, 251, 252, 253, 0, + 0, 0, 0, 0, 0, 360, 361, 0, 0, 63, + 64, 362, 0, 0, 0, 0, 110, 0, 111, 0, + 0, 1, 2, 369, 3, 4, 5, 363, 364, 365, + 0, 0, 63, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 366, 367, 1, 2, 0, 3, 4, 5, + 244, 0, 0, 0, 0, 0, 0, 0, 0, 368, + 0, 0, 0, 0, 0, 245, 246, 0, 0, 0, + 0, 0, 0, 0, 0, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 247, 248, 0, 0, 0, 0, 0, 0, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 247, 248, 0, 0, 249, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 0, 250, 0, 251, 252, 253, 0, 0, 0, 0, + 249, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 0, 250, 0, 251, 252, 253, 0, + 369, 0, 0, 0, 0, 0, 360, 361, 0, 0, + 0, 0, 362, 0, 0, 0, 110, 0, 111, 0, + 254, 0, 0, 255, 0, 256, 0, 257, 363, 364, + 365, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 366, 367, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, + 368, 106, 66, 67, 68, 69, 70, 71, 72, 0, + 1, 2, 0, 3, 4, 5, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 247, 248, 0, 0, 249, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 0, 250, - 0, 251, 252, 253, 0, 0, 0, 0, 249, 197, + 190, 247, 248, 0, 0, 0, 0, 0, 63, 64, + 73, 106, 152, 153, 154, 155, 156, 157, 72, 0, + 1, 2, 0, 3, 4, 5, 0, 0, 249, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 0, 250, 0, 251, 252, 253, 369, 0, 0, - 0, 0, 0, 360, 361, 0, 0, 0, 0, 362, - 0, 0, 0, 110, 0, 111, 0, 254, 0, 0, - 255, 0, 256, 0, 257, 363, 364, 365, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 366, 367, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 63, 64, 368, 106, 66, - 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, - 3, 4, 5, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 247, 248, - 0, 0, 0, 0, 0, 63, 64, 73, 106, 152, - 153, 154, 155, 156, 157, 72, 0, 1, 2, 0, - 3, 4, 5, 0, 0, 249, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 0, 250, - 0, 251, 252, 253, 0, 63, 64, 73, 106, 152, - 153, 154, 155, 156, 157, 72, 0, 1, 2, 0, - 3, 4, 5, 0, 0, 63, 64, 369, 106, 66, - 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, - 3, 4, 5, 0, 0, 0, 0, 73, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 0, 74, - 0, 0, 75, 0, 0, 76, 0, 77, 140, 63, - 64, 0, 147, 66, 67, 68, 69, 70, 71, 72, - 0, 1, 2, 0, 3, 4, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, - 0, 0, 75, 0, 0, 76, 0, 77, 351, 63, - 64, 73, 106, 66, 67, 68, 69, 70, 71, 72, + 208, 0, 250, 0, 251, 252, 253, 0, 63, 64, + 73, 106, 152, 153, 154, 155, 156, 157, 72, 0, + 1, 2, 0, 3, 4, 5, 0, 0, 0, 63, + 64, 369, 106, 66, 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, 3, 4, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, - 0, 329, 75, 0, 0, 76, 0, 77, 417, 0, - 0, 73, 0, 0, 0, 0, 0, 0, 0, 74, - 0, 0, 75, 0, 0, 76, 0, 77, 0, 63, - 64, 0, 106, 152, 153, 154, 155, 156, 157, 72, - 0, 1, 2, 148, 3, 4, 5, 0, 63, 64, - 0, 106, 66, 67, 68, 69, 70, 71, 72, 0, - 1, 2, 0, 3, 4, 5, 0, 0, 0, 0, + 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 74, 0, 0, 75, 0, 0, 76, - 429, 77, 0, 0, 0, 0, 0, 0, 63, 64, - 73, 106, 66, 67, 68, 69, 70, 71, 72, 0, - 1, 2, 0, 3, 4, 5, 0, 0, 0, 0, + 0, 77, 140, 63, 64, 0, 147, 66, 67, 68, + 69, 70, 71, 72, 0, 1, 2, 0, 3, 4, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 75, 0, 0, 76, - 514, 77, 0, 0, 0, 0, 0, 0, 63, 64, - 73, 65, 66, 67, 68, 69, 70, 71, 72, 0, - 1, 2, 0, 3, 4, 5, 63, 64, 0, 106, - 152, 153, 154, 155, 156, 157, 72, 0, 1, 2, - 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, - 73, 0, 0, 74, 0, 0, 75, 0, 346, 76, - 0, 77, 0, 0, 0, 0, 0, 0, 73, 0, - 0, 0, 74, 0, 0, 75, 0, 0, 76, 0, - 77, 63, 64, 0, 147, 66, 67, 68, 69, 70, + 0, 77, 351, 63, 64, 73, 106, 66, 67, 68, + 69, 70, 71, 72, 0, 1, 2, 0, 3, 4, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 74, 0, 329, 75, 0, 0, 76, + 0, 77, 417, 0, 0, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 74, 0, 0, 75, 0, 0, + 76, 0, 77, 63, 64, 0, 106, 152, 153, 154, + 155, 156, 157, 72, 0, 1, 2, 148, 3, 4, + 5, 63, 64, 0, 106, 66, 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, 3, 4, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 0, 0, 75, 0, 0, 76, 0, - 77, 63, 64, 73, 106, 66, 67, 68, 69, 70, + 0, 0, 0, 0, 0, 73, 0, 0, 74, 0, + 0, 75, 0, 429, 76, 0, 77, 0, 0, 0, + 0, 63, 64, 73, 106, 66, 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, 3, 4, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, + 0, 75, 0, 514, 76, 0, 77, 0, 0, 0, + 0, 63, 64, 73, 65, 66, 67, 68, 69, 70, + 71, 72, 0, 1, 2, 0, 3, 4, 5, 63, + 64, 0, 106, 152, 153, 154, 155, 156, 157, 72, + 0, 1, 2, 0, 3, 4, 5, 0, 0, 0, + 0, 0, 0, 73, 0, 0, 0, 0, 74, 0, + 0, 75, 0, 346, 76, 0, 77, 0, 0, 0, + 0, 73, 0, 0, 0, 0, 74, 0, 0, 75, + 0, 0, 76, 0, 77, 63, 64, 0, 147, 66, + 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, + 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 0, 0, 75, + 0, 0, 76, 0, 77, 63, 64, 73, 106, 66, + 67, 68, 69, 70, 71, 72, 0, 1, 2, 0, + 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 0, 0, 75, + 0, 0, 76, 0, 77, 0, 0, 73, 0, 0, + 0, 0, 0, 0, 74, 0, 0, 75, 0, 0, + 76, 0, 77, 63, 64, 0, 266, 66, 67, 68, + 69, 70, 71, 72, 0, 1, 2, 0, 3, 4, + 5, 63, 64, 0, 106, 152, 153, 154, 155, 156, + 157, 72, 0, 1, 2, 0, 3, 4, 5, 0, + 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, + 74, 0, 0, 75, 0, 0, 76, 0, 77, 0, + 0, 63, 64, 73, 106, 66, 67, 68, 69, 70, + 71, 520, 0, 1, 2, 0, 3, 4, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 74, 0, 0, 75, 0, 0, 76, 0, 77, 0, + 0, 63, 64, 73, 106, 66, 67, 68, 69, 70, + 71, 574, 0, 1, 2, 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 0, 0, 75, 0, 0, 76, 0, - 77, 0, 0, 73, 0, 0, 0, 0, 0, 0, - 74, 0, 0, 75, 0, 0, 76, 0, 77, 63, - 64, 0, 266, 66, 67, 68, 69, 70, 71, 72, - 0, 1, 2, 0, 3, 4, 5, 63, 64, 0, - 106, 152, 153, 154, 155, 156, 157, 72, 0, 1, - 2, 0, 3, 4, 5, 0, 0, 0, 0, 0, - 0, 73, 0, 0, 0, 74, 0, 0, 75, 0, - 0, 76, 0, 77, 0, 0, 0, 63, 64, 73, - 106, 66, 67, 68, 69, 70, 71, 520, 0, 1, - 2, 0, 3, 4, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 74, 0, 0, 75, 0, - 0, 76, 0, 77, 0, 0, 0, 63, 64, 73, - 106, 66, 67, 68, 69, 70, 71, 574, 0, 1, - 2, 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, - 167, 0, 0, 74, 0, 0, 75, 0, 0, 76, - 0, 77, 0, 0, 0, 0, 0, 0, 0, 168, - 169, 74, 0, 0, 75, 0, 0, 76, 0, 349, - 0, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 0, 0, 0, 0, 0, 0, - 0, 74, 0, 0, 75, 0, 0, 76, 0, 77, - 0, 0, 0, 0, 193, 194, 195, 0, 0, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, -202, 0, - 0, 74, 0, 0, 75, 0, 0, 76, 0, 77, - 0, 0, 0, 0, 0, 0, -67, 1, 2, 0, - 3, 4, 5, 0, 0, 0, 0, 0, 6, 7, + 0, 0, 0, 73, 167, 0, 0, 0, 74, 0, + 0, 75, 0, 0, 76, 0, 77, 0, 0, 0, + 0, 0, 0, 168, 169, 0, 74, 0, 0, 75, + 0, 0, 76, 0, 349, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 0, 0, 75, + 0, 0, 76, 0, 77, 0, 0, 0, 193, 194, + 195, 0, 0, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, -204, 0, 0, 0, 74, 0, 0, 75, + 0, 0, 76, 0, 77, 0, 0, 0, 0, 0, + -67, 1, 2, 0, 3, 4, 5, 0, 0, 0, + 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, - 0, 0, 9, 0, 0, 0, 10 + 0, 0, 0, 8, 0, 0, 9, 0, 0, 0, + 10 }; static const yytype_int16 yycheck[] = { - 0, 27, 172, 232, 160, 4, 126, 11, 150, 195, - 28, 303, 430, 11, 34, 0, 173, 17, 160, 11, - 255, 256, 11, 568, 210, 211, 212, 213, 214, 336, - 337, 217, 17, 53, 21, 52, 46, 34, 48, 40, - 41, 586, 29, 149, 149, 149, 47, 0, 149, 66, - 149, 77, 53, 148, 160, 160, 160, 156, 148, 160, - 119, 53, 219, 149, 53, 18, 19, 20, 11, 22, - 23, 24, 158, 149, 17, 101, 149, 30, 31, 105, - 153, 150, 158, 152, 149, 111, 145, 32, 33, 158, - 116, 156, 92, 150, 35, 152, 37, 515, 51, 156, - 126, 54, 520, 521, 18, 58, 42, 43, 44, 57, - 38, 47, 138, 139, 349, 150, 142, 152, 153, 19, - 146, 428, 22, 20, 24, 267, 23, 269, 270, 150, - 272, 152, 318, 154, 369, 0, 149, 134, 135, 136, - 153, 159, 139, 150, 170, 152, 143, 144, 3, 4, - 5, 6, 156, 273, 572, 573, 574, 575, 156, 154, - 159, 149, 148, 305, 456, 153, 148, 193, 194, 195, - 196, 313, 314, 160, 113, 114, 594, 595, 163, 149, - 150, 148, 152, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 42, 485, 44, 487, 316, 149, 150, 225, - 152, 387, 22, 389, 390, 391, 134, 135, 136, 235, - 150, 139, 152, 153, 21, 143, 144, 3, 4, 5, - 6, 145, 146, 147, 22, 42, 43, 44, 45, 46, - 47, 48, 150, 50, 152, 377, 378, 379, 112, 113, - 26, 27, 534, 385, 7, 8, 22, 273, 477, 117, - 118, 83, 84, 395, 396, 22, 19, 20, 284, 22, - 23, 24, 418, 152, 4, 4, 134, 135, 37, 137, - 138, 155, 140, 141, 142, 301, 418, 155, 4, 22, - 149, 153, 341, 342, 343, 344, 345, 158, 9, 153, - 316, 317, 318, 152, 9, 354, 355, 356, 9, 441, - 9, 443, 488, 9, 446, 491, 492, 493, 9, 55, - 452, 453, 11, 158, 152, 152, 152, 19, 152, 152, - 22, 152, 24, 349, 553, 22, 152, 556, 145, 146, - 147, 152, 59, 359, 149, 134, 135, 136, 480, 481, - 139, 483, 484, 152, 143, 144, 149, 489, 149, 408, - 409, 38, 149, 149, 149, 149, 415, 499, 38, 152, - 152, 387, 388, 389, 390, 391, 149, 149, 394, 60, - 61, 62, 63, 64, 65, 154, 149, 269, 270, 549, - 272, 407, 38, 149, 149, 7, 8, 529, 10, 11, - 12, 13, 14, 15, 16, 17, 149, 19, 20, 569, - 22, 23, 24, 462, 463, 464, 465, 149, 550, 551, - 469, 470, 149, 305, 149, 117, 118, 158, 149, 149, - 22, 313, 314, 4, 566, 149, 22, 49, 153, 17, - 17, 457, 134, 135, 152, 137, 138, 149, 140, 141, - 142, 149, 501, 502, 4, 471, 149, 589, 590, 149, - 476, 149, 53, 149, 596, 597, 482, 149, 152, 149, - 149, 603, 488, 149, 606, 491, 492, 493, 149, 153, - 496, 149, 149, 158, 149, 475, 149, 153, 537, 153, - 539, 540, 22, 149, 154, 377, 378, 379, 156, 153, - 153, 53, 17, 385, 156, 153, 3, 4, 153, 153, - 7, 8, 9, 395, 396, 4, 152, 152, 149, 17, - 149, 17, 19, 20, 17, 22, 23, 24, 25, 26, - 27, 71, 17, 129, 129, 129, 552, 247, 544, 151, - 225, 248, 154, 40, 41, 157, 92, 159, 160, 516, - 111, 105, 235, 17, 544, 89, 56, 496, 410, 441, - 57, 443, -1, -1, 446, -1, -1, -1, -1, -1, - 452, 453, -1, -1, -1, -1, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, -1, -1, -1, -1, -1, 480, 481, - -1, 483, 484, -1, -1, -1, -1, 489, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 499, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, -1, 129, -1, 131, 132, 133, 134, 135, -1, - 137, 138, -1, 140, 141, 142, -1, 529, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3, 4, -1, - 157, 7, 8, 9, -1, -1, -1, -1, 550, 551, - -1, -1, -1, 19, 20, -1, 22, 23, 24, 25, - 26, 27, 26, 27, 566, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 40, 41, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, -1, 589, 590, -1, - -1, 57, -1, -1, 596, 597, -1, -1, -1, -1, - -1, 603, -1, -1, 606, -1, -1, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, - -1, -1, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, -1, -1, -1, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, -1, 129, -1, 131, 132, 133, -1, -1, - -1, -1, -1, 3, 4, -1, -1, 7, 8, 9, - -1, -1, -1, -1, 150, -1, 152, -1, -1, 19, - 20, 157, 22, 23, 24, 25, 26, 27, -1, -1, - 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, - 40, 41, 19, 20, -1, 22, 23, 24, 25, -1, - -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, + 0, 27, 172, 160, 119, 11, 126, 4, 0, 11, + 21, 303, 173, 28, 149, 232, 195, 17, 29, 57, + 255, 256, 11, 11, 149, 17, 336, 337, 568, 0, + 145, 210, 211, 212, 213, 214, 34, 430, 217, 150, + 52, 150, 150, 3, 4, 5, 6, 150, 588, 160, + 150, 77, 161, 161, 66, 53, 159, 151, 219, 153, + 46, 161, 48, 157, 53, 53, 26, 27, 42, 43, + 44, 45, 46, 47, 48, 101, 50, 150, 150, 105, + 149, 117, 118, 11, 150, 111, 150, 159, 161, 17, + 116, 157, 92, 157, 32, 33, 40, 41, 134, 135, + 126, 137, 138, 47, 140, 141, 142, 150, 35, 53, + 37, 154, 138, 139, 349, 34, 142, 151, 428, 153, + 146, 151, 515, 153, 18, 7, 8, 520, 521, 159, + 42, 43, 44, 20, 369, 47, 23, 19, 20, 318, + 22, 23, 24, 19, 170, 160, 22, 38, 24, 22, + 161, 157, 42, 273, 44, 157, 267, 22, 269, 270, + 151, 272, 153, 160, 456, 113, 114, 193, 194, 195, + 196, 163, 146, 147, 148, 3, 4, 5, 6, 572, + 573, 574, 575, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 149, 485, 305, 487, 316, 150, 149, 225, + 155, 154, 313, 314, 597, 598, 112, 113, 387, 235, + 389, 390, 391, 83, 84, 134, 135, 136, 269, 270, + 139, 272, 21, 153, 143, 144, 341, 342, 343, 344, + 345, 60, 61, 62, 63, 64, 65, 22, 22, 354, + 355, 356, 534, 134, 135, 136, 150, 273, 139, 4, + 154, 4, 143, 144, 305, 151, 37, 153, 284, 155, + 477, 418, 313, 314, 156, 4, 377, 378, 379, 150, + 156, 134, 135, 136, 385, 301, 139, 146, 147, 148, + 143, 144, 22, 154, 395, 396, 150, 151, 154, 153, + 316, 317, 318, 408, 409, 153, 150, 151, 19, 153, + 415, 22, 151, 24, 153, 154, 159, 418, 151, 488, + 153, 154, 491, 492, 493, 9, 9, 9, 9, 9, + 9, 55, 159, 349, 22, 11, 377, 378, 379, 153, + 441, 153, 443, 359, 385, 446, 553, 153, 153, 556, + 153, 452, 453, 153, 395, 396, 153, 462, 463, 464, + 465, 153, 150, 153, 469, 470, 150, 150, 150, 150, + 150, 387, 388, 389, 390, 391, 38, 150, 394, 480, + 481, 38, 483, 484, 153, 153, 59, 150, 489, 549, + 150, 407, 150, 155, 150, 150, 501, 502, 499, 150, + 441, 150, 443, 150, 150, 446, 117, 118, 150, 569, + 150, 452, 453, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 134, 135, 159, 137, 138, 529, 140, + 141, 142, 537, 38, 539, 540, 22, 4, 150, 480, + 481, 457, 483, 484, 154, 22, 17, 17, 489, 550, + 551, 153, 150, 150, 4, 471, 150, 150, 499, 150, + 476, 150, 53, 150, 159, 566, 482, 153, 22, 154, + 53, 17, 488, 4, 22, 491, 492, 493, 150, 150, + 496, 150, 150, 150, 150, 475, 150, 150, 529, 154, + 591, 592, 150, 154, 153, 155, 145, 17, 599, 600, + 154, 157, 154, 154, 157, 606, 154, 154, 609, 550, + 551, 153, 150, 17, 150, 17, 71, 17, 3, 4, + 129, 129, 7, 8, 9, 566, 129, 247, 92, 248, + 544, 516, 111, 225, 19, 20, 552, 22, 23, 24, + 25, 26, 27, 26, 27, 105, 17, 89, 56, -1, + 591, 592, 496, 410, 544, 40, 41, 235, 599, 600, + -1, -1, -1, -1, -1, 606, -1, -1, 609, -1, + 7, 8, 57, 10, 11, 12, 13, 14, 15, 16, + 17, -1, 19, 20, -1, 22, 23, 24, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, -1, -1, -1, -1, -1, + -1, -1, 49, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, -1, 129, -1, 131, 132, 133, 134, + 135, -1, 137, 138, -1, 140, 141, 142, 3, 4, + -1, -1, 7, 8, 9, -1, -1, -1, 0, -1, + -1, -1, -1, 158, 19, 20, -1, 22, 23, 24, + 25, 26, 27, -1, -1, -1, 18, 19, 20, -1, + 22, 23, 24, -1, -1, 40, 41, -1, 30, 31, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 57, -1, -1, 152, -1, -1, 155, 51, + -1, 158, 54, 160, 161, -1, 58, -1, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, -1, 129, -1, 131, 132, 133, -1, + -1, -1, -1, -1, -1, 3, 4, -1, -1, 7, + 8, 9, -1, -1, -1, -1, 151, -1, 153, -1, + -1, 19, 20, 158, 22, 23, 24, 25, 26, 27, + -1, -1, 7, 8, -1, -1, -1, -1, -1, -1, + -1, -1, 40, 41, 19, 20, -1, 22, 23, 24, + 25, -1, -1, -1, -1, -1, -1, -1, -1, 57, + -1, -1, -1, -1, -1, 40, 41, -1, -1, -1, + -1, -1, -1, -1, -1, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, -1, -1, -1, -1, -1, -1, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, -1, -1, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + -1, 129, -1, 131, 132, 133, -1, -1, -1, -1, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, -1, 129, -1, 131, 132, 133, -1, + 158, -1, -1, -1, -1, -1, 3, 4, -1, -1, + -1, -1, 9, -1, -1, -1, 151, -1, 153, -1, + 155, -1, -1, 158, -1, 160, -1, 162, 25, 26, + 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, -1, -1, -1, -1, - -1, -1, -1, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - -1, -1, -1, -1, -1, -1, 73, 74, 75, 76, + -1, -1, -1, -1, -1, -1, -1, -1, 7, 8, + 57, 10, 11, 12, 13, 14, 15, 16, 17, -1, + 19, 20, -1, 22, 23, 24, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, -1, -1, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -1, 129, - -1, 131, 132, 133, -1, -1, -1, -1, 115, 116, + 87, 88, 89, -1, -1, -1, -1, -1, 7, 8, + 49, 10, 11, 12, 13, 14, 15, 16, 17, -1, + 19, 20, -1, 22, 23, 24, -1, -1, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, -1, 129, -1, 131, 132, 133, 157, -1, -1, - -1, -1, -1, 3, 4, -1, -1, -1, -1, 9, - -1, -1, -1, 150, -1, 152, -1, 154, -1, -1, - 157, -1, 159, -1, 161, 25, 26, 27, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 40, 41, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 7, 8, 57, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - -1, -1, -1, -1, -1, 7, 8, 49, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, -1, -1, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -1, 129, - -1, 131, 132, 133, -1, 7, 8, 49, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, -1, -1, 7, 8, 157, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, -1, -1, -1, -1, 49, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 39, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 49, -1, 151, - -1, -1, 154, -1, -1, 157, -1, 159, 160, 7, - 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, -1, 22, 23, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 151, - -1, -1, 154, -1, -1, 157, -1, 159, 160, 7, - 8, 49, 10, 11, 12, 13, 14, 15, 16, 17, + 127, -1, 129, -1, 131, 132, 133, -1, 7, 8, + 49, 10, 11, 12, 13, 14, 15, 16, 17, -1, + 19, 20, -1, 22, 23, 24, -1, -1, -1, 7, + 8, 158, 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, 22, 23, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 151, - -1, 39, 154, -1, -1, 157, -1, 159, 160, -1, - -1, 49, -1, -1, -1, -1, -1, -1, -1, 151, - -1, -1, 154, -1, -1, 157, -1, 159, -1, 7, + 49, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 49, -1, 152, -1, -1, 155, -1, -1, 158, + -1, 160, 161, 7, 8, -1, 10, 11, 12, 13, + 14, 15, 16, 17, -1, 19, 20, -1, 22, 23, + 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 152, -1, -1, 155, -1, -1, 158, + -1, 160, 161, 7, 8, 49, 10, 11, 12, 13, + 14, 15, 16, 17, -1, 19, 20, -1, 22, 23, + 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 152, -1, 39, 155, -1, -1, 158, + -1, 160, 161, -1, -1, 49, -1, -1, -1, -1, + -1, -1, -1, -1, 152, -1, -1, 155, -1, -1, + 158, -1, 160, 7, 8, -1, 10, 11, 12, 13, + 14, 15, 16, 17, -1, 19, 20, 121, 22, 23, + 24, 7, 8, -1, 10, 11, 12, 13, 14, 15, + 16, 17, -1, 19, 20, -1, 22, 23, 24, -1, + -1, -1, -1, -1, -1, 49, -1, -1, 152, -1, + -1, 155, -1, 39, 158, -1, 160, -1, -1, -1, + -1, 7, 8, 49, 10, 11, 12, 13, 14, 15, + 16, 17, -1, 19, 20, -1, 22, 23, 24, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 152, -1, + -1, 155, -1, 39, 158, -1, 160, -1, -1, -1, + -1, 7, 8, 49, 10, 11, 12, 13, 14, 15, + 16, 17, -1, 19, 20, -1, 22, 23, 24, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, 121, 22, 23, 24, -1, 7, 8, - -1, 10, 11, 12, 13, 14, 15, 16, 17, -1, - 19, 20, -1, 22, 23, 24, -1, -1, -1, -1, - -1, 49, -1, 151, -1, -1, 154, -1, -1, 157, - 39, 159, -1, -1, -1, -1, -1, -1, 7, 8, - 49, 10, 11, 12, 13, 14, 15, 16, 17, -1, - 19, 20, -1, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, 151, -1, -1, 154, -1, -1, 157, - 39, 159, -1, -1, -1, -1, -1, -1, 7, 8, - 49, 10, 11, 12, 13, 14, 15, 16, 17, -1, - 19, 20, -1, 22, 23, 24, 7, 8, -1, 10, - 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, - -1, 22, 23, 24, -1, -1, -1, -1, -1, -1, - 49, -1, -1, 151, -1, -1, 154, -1, 156, 157, - -1, 159, -1, -1, -1, -1, -1, -1, 49, -1, - -1, -1, 151, -1, -1, 154, -1, -1, 157, -1, - 159, 7, 8, -1, 10, 11, 12, 13, 14, 15, + -1, 19, 20, -1, 22, 23, 24, -1, -1, -1, + -1, -1, -1, 49, -1, -1, -1, -1, 152, -1, + -1, 155, -1, 157, 158, -1, 160, -1, -1, -1, + -1, 49, -1, -1, -1, -1, 152, -1, -1, 155, + -1, -1, 158, -1, 160, 7, 8, -1, 10, 11, + 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, + 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 152, -1, -1, 155, + -1, -1, 158, -1, 160, 7, 8, 49, 10, 11, + 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, + 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 152, -1, -1, 155, + -1, -1, 158, -1, 160, -1, -1, 49, -1, -1, + -1, -1, -1, -1, 152, -1, -1, 155, -1, -1, + 158, -1, 160, 7, 8, -1, 10, 11, 12, 13, + 14, 15, 16, 17, -1, 19, 20, -1, 22, 23, + 24, 7, 8, -1, 10, 11, 12, 13, 14, 15, + 16, 17, -1, 19, 20, -1, 22, 23, 24, -1, + -1, -1, -1, -1, -1, 49, -1, -1, -1, -1, + 152, -1, -1, 155, -1, -1, 158, -1, 160, -1, + -1, 7, 8, 49, 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 151, -1, -1, 154, -1, -1, 157, -1, - 159, 7, 8, 49, 10, 11, 12, 13, 14, 15, + 152, -1, -1, 155, -1, -1, 158, -1, 160, -1, + -1, 7, 8, 49, 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 151, -1, -1, 154, -1, -1, 157, -1, - 159, -1, -1, 49, -1, -1, -1, -1, -1, -1, - 151, -1, -1, 154, -1, -1, 157, -1, 159, 7, - 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, -1, 22, 23, 24, 7, 8, -1, - 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, - 20, -1, 22, 23, 24, -1, -1, -1, -1, -1, - -1, 49, -1, -1, -1, 151, -1, -1, 154, -1, - -1, 157, -1, 159, -1, -1, -1, 7, 8, 49, - 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, - 20, -1, 22, 23, 24, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 151, -1, -1, 154, -1, - -1, 157, -1, 159, -1, -1, -1, 7, 8, 49, - 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, - 20, -1, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 49, - 36, -1, -1, 151, -1, -1, 154, -1, -1, 157, - -1, 159, -1, -1, -1, -1, -1, -1, -1, 55, - 56, 151, -1, -1, 154, -1, -1, 157, -1, 159, - -1, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, - -1, 151, -1, -1, 154, -1, -1, 157, -1, 159, - -1, -1, -1, -1, 110, 111, 112, -1, -1, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 0, -1, - -1, 151, -1, -1, 154, -1, -1, 157, -1, 159, - -1, -1, -1, -1, -1, -1, 18, 19, 20, -1, - 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, + -1, -1, -1, 49, 36, -1, -1, -1, 152, -1, + -1, 155, -1, -1, 158, -1, 160, -1, -1, -1, + -1, -1, -1, 55, 56, -1, 152, -1, -1, 155, + -1, -1, 158, -1, 160, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, -1, -1, + -1, -1, -1, -1, -1, -1, 152, -1, -1, 155, + -1, -1, 158, -1, 160, -1, -1, -1, 110, 111, + 112, -1, -1, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 0, -1, -1, -1, 152, -1, -1, 155, + -1, -1, 158, -1, 160, -1, -1, -1, -1, -1, + 18, 19, 20, -1, 22, 23, 24, -1, -1, -1, + -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, - -1, -1, 54, -1, -1, -1, 58 + -1, -1, -1, 51, -1, -1, 54, -1, -1, -1, + 58 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -2541,66 +2548,67 @@ static const yytype_uint8 yystos[] = { 0, 19, 20, 22, 23, 24, 30, 31, 51, 54, - 58, 170, 172, 173, 174, 175, 206, 207, 208, 210, - 209, 52, 66, 215, 148, 57, 148, 18, 148, 42, - 43, 44, 45, 46, 47, 48, 50, 145, 146, 147, - 176, 177, 178, 0, 208, 46, 48, 179, 225, 42, - 43, 44, 47, 180, 222, 224, 231, 148, 148, 154, - 216, 22, 214, 7, 8, 10, 11, 12, 13, 14, - 15, 16, 17, 49, 151, 154, 157, 159, 170, 173, - 193, 194, 228, 178, 178, 35, 37, 204, 178, 178, - 21, 232, 233, 29, 160, 223, 232, 22, 22, 22, - 217, 152, 4, 4, 4, 159, 10, 160, 194, 199, - 150, 152, 204, 204, 42, 44, 181, 32, 33, 203, - 60, 61, 62, 63, 64, 65, 182, 220, 220, 172, - 236, 149, 156, 39, 194, 195, 197, 198, 155, 155, - 160, 199, 149, 160, 198, 203, 203, 10, 121, 194, - 196, 205, 11, 12, 13, 14, 15, 16, 168, 169, - 194, 200, 4, 196, 28, 159, 221, 36, 55, 56, + 58, 171, 173, 174, 175, 176, 208, 209, 210, 212, + 211, 52, 66, 217, 149, 57, 149, 18, 149, 42, + 43, 44, 45, 46, 47, 48, 50, 146, 147, 148, + 177, 178, 179, 0, 210, 46, 48, 180, 227, 42, + 43, 44, 47, 181, 224, 226, 233, 149, 149, 155, + 218, 22, 216, 7, 8, 10, 11, 12, 13, 14, + 15, 16, 17, 49, 152, 155, 158, 160, 171, 174, + 195, 196, 230, 179, 179, 35, 37, 206, 179, 179, + 21, 234, 235, 29, 161, 225, 234, 22, 22, 22, + 219, 153, 4, 4, 4, 160, 10, 161, 196, 201, + 151, 153, 206, 206, 42, 44, 182, 32, 33, 205, + 60, 61, 62, 63, 64, 65, 183, 222, 222, 173, + 238, 150, 157, 39, 196, 197, 199, 200, 156, 156, + 161, 201, 150, 161, 200, 205, 205, 10, 121, 196, + 198, 207, 11, 12, 13, 14, 15, 16, 169, 170, + 196, 202, 4, 198, 28, 160, 223, 36, 55, 56, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 110, 111, 112, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 163, 164, 165, 234, 240, - 241, 242, 243, 22, 184, 149, 153, 194, 194, 158, - 160, 194, 153, 200, 194, 152, 228, 26, 27, 3, + 129, 130, 131, 132, 133, 164, 165, 166, 236, 242, + 243, 244, 245, 22, 185, 150, 154, 196, 196, 159, + 161, 196, 154, 202, 196, 153, 230, 26, 27, 3, 4, 5, 6, 9, 25, 40, 41, 88, 89, 115, - 129, 131, 132, 133, 154, 157, 159, 161, 163, 164, - 165, 201, 228, 211, 173, 55, 10, 194, 230, 11, - 17, 11, 168, 182, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 166, 26, 27, 96, 97, 98, + 129, 131, 132, 133, 155, 158, 160, 162, 164, 165, + 166, 203, 230, 213, 174, 55, 10, 196, 232, 11, + 17, 11, 169, 183, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 167, 26, 27, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 167, 194, 194, 230, 194, 194, 237, 230, 230, - 230, 230, 230, 194, 194, 230, 182, 113, 114, 117, - 118, 134, 135, 137, 138, 140, 141, 142, 183, 39, - 195, 186, 156, 158, 158, 186, 212, 213, 205, 166, - 167, 152, 152, 152, 152, 152, 156, 200, 202, 159, - 202, 160, 202, 22, 152, 152, 152, 149, 191, 152, - 3, 4, 9, 25, 26, 27, 40, 41, 57, 157, - 201, 227, 228, 229, 229, 229, 229, 196, 194, 194, - 149, 188, 149, 188, 229, 154, 149, 149, 149, 149, - 149, 149, 229, 229, 38, 196, 194, 230, 134, 135, - 136, 139, 143, 144, 185, 191, 191, 38, 152, 152, - 200, 200, 200, 200, 200, 149, 156, 160, 194, 202, - 158, 160, 200, 200, 200, 34, 53, 189, 192, 39, - 194, 218, 219, 59, 226, 202, 149, 149, 229, 229, - 229, 11, 53, 11, 239, 229, 154, 230, 194, 230, - 230, 230, 149, 149, 194, 229, 229, 149, 194, 200, - 200, 239, 149, 149, 149, 149, 200, 158, 160, 149, - 149, 38, 22, 4, 191, 184, 149, 153, 22, 158, - 17, 17, 152, 149, 149, 229, 4, 229, 149, 149, - 229, 149, 149, 149, 229, 229, 152, 149, 188, 194, - 153, 149, 149, 153, 200, 200, 200, 200, 158, 200, - 200, 194, 170, 171, 39, 194, 186, 149, 229, 229, - 17, 194, 238, 229, 229, 188, 188, 230, 229, 149, - 230, 230, 230, 238, 229, 200, 200, 149, 153, 149, - 149, 153, 153, 153, 184, 189, 190, 22, 149, 154, - 184, 184, 149, 153, 156, 229, 153, 188, 153, 153, - 200, 200, 200, 171, 53, 187, 17, 156, 168, 235, - 117, 118, 229, 229, 17, 194, 186, 156, 186, 153, - 153, 153, 4, 229, 227, 156, 168, 184, 184, 184, - 184, 38, 149, 227, 229, 229, 17, 17, 149, 184, - 184, 229, 229, 17, 71, 229, 17, 229 + 109, 168, 196, 196, 232, 196, 196, 239, 232, 232, + 232, 232, 232, 196, 196, 232, 183, 113, 114, 117, + 118, 134, 135, 137, 138, 140, 141, 142, 184, 39, + 197, 187, 157, 159, 159, 187, 214, 215, 207, 167, + 168, 153, 153, 153, 153, 153, 157, 202, 204, 160, + 204, 161, 204, 22, 153, 153, 153, 150, 193, 153, + 3, 4, 9, 25, 26, 27, 40, 41, 57, 158, + 203, 229, 230, 231, 231, 231, 231, 198, 196, 196, + 150, 190, 150, 190, 231, 155, 150, 150, 150, 150, + 150, 150, 231, 231, 38, 198, 196, 232, 134, 135, + 136, 139, 143, 144, 186, 193, 193, 38, 153, 153, + 202, 202, 202, 202, 202, 150, 157, 161, 196, 204, + 159, 161, 202, 202, 202, 34, 53, 191, 194, 39, + 196, 220, 221, 59, 228, 204, 150, 150, 231, 231, + 231, 11, 53, 11, 241, 231, 155, 232, 196, 232, + 232, 232, 150, 150, 196, 231, 231, 150, 196, 202, + 202, 241, 150, 150, 150, 150, 202, 159, 161, 150, + 150, 38, 22, 4, 193, 185, 150, 154, 22, 159, + 17, 17, 153, 150, 150, 231, 4, 231, 150, 150, + 231, 150, 150, 150, 231, 231, 153, 150, 190, 196, + 154, 150, 150, 154, 202, 202, 202, 202, 159, 202, + 202, 196, 171, 172, 39, 196, 187, 150, 231, 231, + 17, 196, 240, 231, 231, 190, 190, 232, 231, 150, + 232, 232, 232, 240, 231, 202, 202, 150, 154, 150, + 150, 154, 154, 154, 185, 191, 192, 22, 150, 155, + 185, 185, 150, 154, 157, 231, 154, 190, 154, 154, + 202, 202, 202, 172, 53, 189, 17, 157, 169, 237, + 117, 118, 231, 231, 17, 196, 187, 157, 187, 154, + 154, 154, 4, 145, 188, 231, 229, 157, 169, 185, + 185, 185, 185, 38, 22, 150, 229, 231, 231, 17, + 17, 150, 185, 185, 231, 231, 17, 71, 231, 17, + 231 }; #define yyerrok (yyerrstatus = 0) @@ -2674,7 +2682,7 @@ we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ @@ -3415,142 +3423,142 @@ switch (yyn) { case 29: -#line 1111 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1111 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_EQ; ;} break; case 30: -#line 1111 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1111 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_NE; ;} break; case 31: -#line 1112 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1112 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SLT; ;} break; case 32: -#line 1112 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1112 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SGT; ;} break; case 33: -#line 1113 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1113 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SLE; ;} break; case 34: -#line 1113 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1113 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_SGE; ;} break; case 35: -#line 1114 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1114 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_ULT; ;} break; case 36: -#line 1114 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1114 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_UGT; ;} break; case 37: -#line 1115 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1115 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_ULE; ;} break; case 38: -#line 1115 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1115 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.IPredicate) = ICmpInst::ICMP_UGE; ;} break; case 39: -#line 1119 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1119 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OEQ; ;} break; case 40: -#line 1119 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1119 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ONE; ;} break; case 41: -#line 1120 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1120 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OLT; ;} break; case 42: -#line 1120 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1120 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OGT; ;} break; case 43: -#line 1121 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1121 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OLE; ;} break; case 44: -#line 1121 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1121 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_OGE; ;} break; case 45: -#line 1122 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1122 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ORD; ;} break; case 46: -#line 1122 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1122 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UNO; ;} break; case 47: -#line 1123 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1123 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UEQ; ;} break; case 48: -#line 1123 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1123 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UNE; ;} break; case 49: -#line 1124 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1124 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ULT; ;} break; case 50: -#line 1124 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1124 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UGT; ;} break; case 51: -#line 1125 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1125 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_ULE; ;} break; case 52: -#line 1125 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1125 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_UGE; ;} break; case 53: -#line 1126 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1126 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_TRUE; ;} break; case 54: -#line 1127 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1127 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.FPredicate) = FCmpInst::FCMP_FALSE; ;} break; case 65: -#line 1136 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1136 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; ;} break; case 66: -#line 1140 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1140 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[(1) - (2)].StrVal); CHECK_FOR_ERROR @@ -3558,7 +3566,7 @@ break; case 67: -#line 1144 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1144 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; CHECK_FOR_ERROR @@ -3566,7 +3574,7 @@ break; case 71: -#line 1152 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1152 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; CHECK_FOR_ERROR @@ -3574,7 +3582,7 @@ break; case 72: -#line 1157 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1157 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[(1) - (2)].StrVal); CHECK_FOR_ERROR @@ -3582,152 +3590,152 @@ break; case 73: -#line 1163 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1163 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; case 74: -#line 1164 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1164 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; case 75: -#line 1165 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1165 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} break; case 76: -#line 1166 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1166 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::AppendingLinkage; ;} break; case 77: -#line 1167 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1167 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} break; case 78: -#line 1171 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1171 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} break; case 79: -#line 1172 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1172 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} break; case 80: -#line 1173 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1173 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 81: -#line 1177 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1177 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::DefaultVisibility; ;} break; case 82: -#line 1178 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1178 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::DefaultVisibility; ;} break; case 83: -#line 1179 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1179 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::HiddenVisibility; ;} break; case 84: -#line 1180 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1180 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Visibility) = GlobalValue::ProtectedVisibility; ;} break; case 85: -#line 1184 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1184 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 86: -#line 1185 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1185 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} break; case 87: -#line 1186 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1186 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} break; case 88: -#line 1190 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1190 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 89: -#line 1191 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1191 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; case 90: -#line 1192 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1192 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} break; case 91: -#line 1193 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1193 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; case 92: -#line 1194 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1194 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} break; case 93: -#line 1198 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1198 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; case 94: -#line 1199 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1199 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; case 95: -#line 1200 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1200 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; case 96: -#line 1203 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1203 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::C; ;} break; case 97: -#line 1204 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1204 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::C; ;} break; case 98: -#line 1205 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1205 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::Fast; ;} break; case 99: -#line 1206 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1206 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::Cold; ;} break; case 100: -#line 1207 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1207 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::X86_StdCall; ;} break; case 101: -#line 1208 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1208 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::X86_FastCall; ;} break; case 102: -#line 1209 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1209 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { if ((unsigned)(yyvsp[(2) - (2)].UInt64Val) != (yyvsp[(2) - (2)].UInt64Val)) GEN_ERROR("Calling conv too large"); @@ -3737,111 +3745,123 @@ break; case 103: -#line 1216 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1216 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ZExt; ;} break; case 104: -#line 1217 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1217 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ZExt; ;} break; case 105: -#line 1218 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1218 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::SExt; ;} break; case 106: -#line 1219 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1219 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::SExt; ;} break; case 107: -#line 1220 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1220 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::InReg; ;} break; case 108: -#line 1221 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1221 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::StructRet; ;} break; case 109: -#line 1222 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1222 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::NoAlias; ;} break; case 110: -#line 1223 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1223 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ByVal; ;} break; case 111: -#line 1224 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1224 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::Nest; ;} break; case 112: -#line 1227 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1227 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::None; ;} break; case 113: -#line 1228 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1228 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = (yyvsp[(1) - (2)].ParamAttrs) | (yyvsp[(2) - (2)].ParamAttrs); ;} break; case 114: -#line 1233 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1233 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::NoReturn; ;} break; case 115: -#line 1234 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1234 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::NoUnwind; ;} break; case 116: -#line 1235 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1235 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ZExt; ;} break; case 117: -#line 1236 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1236 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::SExt; ;} break; case 118: -#line 1237 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1237 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ReadNone; ;} break; case 119: -#line 1238 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1238 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::ReadOnly; ;} break; case 120: -#line 1241 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1241 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = ParamAttr::None; ;} break; case 121: -#line 1242 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1242 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ParamAttrs) = (yyvsp[(1) - (2)].ParamAttrs) | (yyvsp[(2) - (2)].ParamAttrs); ;} break; case 122: -#line 1249 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = 0; ;} +#line 1247 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" + { (yyval.StrVal) = 0; ;} break; case 123: -#line 1250 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" +#line 1248 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" + { + (yyval.StrVal) = (yyvsp[(2) - (2)].StrVal); + ;} + break; + + case 124: +#line 1255 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" + { (yyval.UIntVal) = 0; ;} + break; + + case 125: +#line 1256 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = (yyvsp[(2) - (2)].UInt64Val); if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) @@ -3850,13 +3870,13 @@ ;} break; - case 124: -#line 1256 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 126: +#line 1262 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = 0; ;} break; - case 125: -#line 1257 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 127: +#line 1263 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = (yyvsp[(3) - (3)].UInt64Val); if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) @@ -3865,8 +3885,8 @@ ;} break; - case 126: -#line 1265 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 128: +#line 1271 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { for (unsigned i = 0, e = (yyvsp[(2) - (2)].StrVal)->length(); i != e; ++i) if ((*(yyvsp[(2) - (2)].StrVal))[i] == '"' || (*(yyvsp[(2) - (2)].StrVal))[i] == '\\') @@ -3876,28 +3896,28 @@ ;} break; - case 127: -#line 1273 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 129: +#line 1279 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; ;} break; - case 128: -#line 1274 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 130: +#line 1280 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[(1) - (1)].StrVal); ;} break; - case 129: -#line 1279 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 131: +#line 1285 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" {;} break; - case 130: -#line 1280 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 132: +#line 1286 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" {;} break; - case 131: -#line 1281 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 133: +#line 1287 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV->setSection(*(yyvsp[(1) - (1)].StrVal)); delete (yyvsp[(1) - (1)].StrVal); @@ -3905,8 +3925,8 @@ ;} break; - case 132: -#line 1286 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 134: +#line 1292 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[(2) - (2)].UInt64Val) != 0 && !isPowerOf2_32((yyvsp[(2) - (2)].UInt64Val))) GEN_ERROR("Alignment must be a power of two"); @@ -3915,24 +3935,24 @@ ;} break; - case 140: -#line 1302 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 142: +#line 1308 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder(OpaqueType::get()); CHECK_FOR_ERROR ;} break; - case 141: -#line 1306 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 143: +#line 1312 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder((yyvsp[(1) - (1)].PrimType)); CHECK_FOR_ERROR ;} break; - case 142: -#line 1310 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 144: +#line 1316 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Pointer type? if (*(yyvsp[(1) - (2)].TypeVal) == Type::LabelTy) GEN_ERROR("Cannot form a pointer to a basic block"); @@ -3942,8 +3962,8 @@ ;} break; - case 143: -#line 1317 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 145: +#line 1323 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Named types are also simple types... const Type* tmp = getTypeVal((yyvsp[(1) - (1)].ValIDVal)); CHECK_FOR_ERROR @@ -3951,8 +3971,8 @@ ;} break; - case 144: -#line 1322 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 146: +#line 1328 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Type UpReference if ((yyvsp[(2) - (2)].UInt64Val) > (uint64_t)~0U) GEN_ERROR("Value out of range"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder @@ -3963,8 +3983,8 @@ ;} break; - case 145: -#line 1330 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 147: +#line 1336 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -3997,8 +4017,8 @@ ;} break; - case 146: -#line 1360 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 148: +#line 1366 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -4025,8 +4045,8 @@ ;} break; - case 147: -#line 1385 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 149: +#line 1391 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Sized array type? (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(ArrayType::get(*(yyvsp[(4) - (5)].TypeVal), (unsigned)(yyvsp[(2) - (5)].UInt64Val)))); delete (yyvsp[(4) - (5)].TypeVal); @@ -4034,8 +4054,8 @@ ;} break; - case 148: -#line 1390 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 150: +#line 1396 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Vector type? const llvm::Type* ElemTy = (yyvsp[(4) - (5)].TypeVal)->get(); if ((unsigned)(yyvsp[(2) - (5)].UInt64Val) != (yyvsp[(2) - (5)].UInt64Val)) @@ -4048,8 +4068,8 @@ ;} break; - case 149: -#line 1400 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 151: +#line 1406 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Structure type? std::vector Elements; for (std::list::iterator I = (yyvsp[(2) - (3)].TypeList)->begin(), @@ -4062,16 +4082,16 @@ ;} break; - case 150: -#line 1410 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 152: +#line 1416 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector())); CHECK_FOR_ERROR ;} break; - case 151: -#line 1414 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 153: +#line 1420 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { std::vector Elements; for (std::list::iterator I = (yyvsp[(3) - (5)].TypeList)->begin(), @@ -4084,16 +4104,16 @@ ;} break; - case 152: -#line 1424 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 154: +#line 1430 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector(), true)); CHECK_FOR_ERROR ;} break; - case 153: -#line 1431 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 155: +#line 1437 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Allow but ignore attributes on function types; this permits auto-upgrade. // FIXME: remove in LLVM 3.0. @@ -4102,8 +4122,8 @@ ;} break; - case 154: -#line 1440 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 156: +#line 1446 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (1)].TypeVal))->getDescription()); @@ -4113,15 +4133,15 @@ ;} break; - case 155: -#line 1447 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 157: +#line 1453 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeVal) = new PATypeHolder(Type::VoidTy); ;} break; - case 156: -#line 1452 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 158: +#line 1458 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); (yyval.TypeWithAttrsList)->push_back((yyvsp[(1) - (1)].TypeWithAttrs)); @@ -4129,16 +4149,16 @@ ;} break; - case 157: -#line 1457 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 159: +#line 1463 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { ((yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList))->push_back((yyvsp[(3) - (3)].TypeWithAttrs)); CHECK_FOR_ERROR ;} break; - case 159: -#line 1465 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 161: +#line 1471 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList); TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None; @@ -4148,8 +4168,8 @@ ;} break; - case 160: -#line 1472 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 162: +#line 1478 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList; TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None; @@ -4159,16 +4179,16 @@ ;} break; - case 161: -#line 1479 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 163: +#line 1485 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); CHECK_FOR_ERROR ;} break; - case 162: -#line 1487 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 164: +#line 1493 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList) = new std::list(); (yyval.TypeList)->push_back(*(yyvsp[(1) - (1)].TypeVal)); @@ -4177,8 +4197,8 @@ ;} break; - case 163: -#line 1493 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 165: +#line 1499 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { ((yyval.TypeList)=(yyvsp[(1) - (3)].TypeList))->push_back(*(yyvsp[(3) - (3)].TypeVal)); delete (yyvsp[(3) - (3)].TypeVal); @@ -4186,8 +4206,8 @@ ;} break; - case 164: -#line 1505 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 166: +#line 1511 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); @@ -4218,8 +4238,8 @@ ;} break; - case 165: -#line 1533 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 167: +#line 1539 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4238,8 +4258,8 @@ ;} break; - case 166: -#line 1549 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 168: +#line 1555 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); @@ -4269,8 +4289,8 @@ ;} break; - case 167: -#line 1576 "/home/asl/proj/llvm/src/lib/AsmParser/llvmAsmParser.y" + case 169: +#line 1582 "/Users/malichus/Source/llvm/src/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); @@ -4301,8 +4321,8 @@ ;}